From 0c04c377bc8ac177d28bd0e0096d7c6940d33cd4 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 18 Feb 1999 16:48:14 +0000 Subject: ./clock/Makefile.in,v ./clock/clock.c,v ./console/Makefile.in,v ./console/config.c,v ./console/console.c,v ./console/console.h,v ./console/debugio.c,v ./console/i8042.c,v ./console/i8042_p.h,v ./console/i8042vga.c,v ./console/i8042vga.h,v ./console/ns16550.c,v ./console/ns16550.h,v ./console/ns16550_p.h,v ./console/ns16550cfg.c,v ./console/ns16550cfg.h,v ./console/vga.c,v ./console/vga_p.h,v ./console/z85c30.c,v ./console/z85c30.h,v ./console/z85c30_p.h,v ./console/z85c30cfg.c,v ./console/z85c30cfg.h,v ./include/Makefile.in,v ./include/bsp.h,v ./include/chain.h,v ./include/coverhd.h,v ./include/extisrdrv.h,v ./include/nvram.h,v ./include/pci.h,v ./include/tod.h,v ./network/Makefile.in,v ./network/amd79c970.c,v ./network/amd79c970.h,v ./nvram/Makefile.in,v ./nvram/ds1385.h,v ./nvram/mk48t18.h,v ./nvram/nvram.c,v ./nvram/prepnvr.h,v ./nvram/stk11c68.h,v ./pci/Makefile.in,v ./pci/pci.c,v ./start/Makefile.in,v ./start/start.s,v ./startup/Makefile.in,v ./startup/bspclean.c,v ./startup/bspstart.c,v ./startup/bsptrap.s,v ./startup/device-tree,v ./startup/genpvec.c,v ./startup/linkcmds,v ./startup/rtems-ctor.cc,v ./startup/sbrk.c,v ./startup/setvec.c,v ./startup/spurious.c,v ./startup/swap.c,v ./timer/Makefile.in,v ./timer/timer.c,v ./tod/Makefile.in,v ./tod/cmos.h,v ./tod/tod.c,v ./universe/Makefile.in,v ./universe/universe.c,v ./vectors/Makefile.in,v ./vectors/README,v ./vectors/align_h.s,v ./vectors/vectors.s,v ./wrapup/Makefile.in,v ./Makefile.in,v ./README,v ./STATUS,v ./bsp_specs,v --- c/src/lib/libbsp/powerpc/ppcn_60x/Makefile.in | 25 + c/src/lib/libbsp/powerpc/ppcn_60x/README | 48 + c/src/lib/libbsp/powerpc/ppcn_60x/STATUS | 8 + c/src/lib/libbsp/powerpc/ppcn_60x/bsp_specs | 23 + .../lib/libbsp/powerpc/ppcn_60x/clock/Makefile.in | 59 ++ c/src/lib/libbsp/powerpc/ppcn_60x/clock/clock.c | 241 +++++ .../libbsp/powerpc/ppcn_60x/console/Makefile.in | 54 + .../lib/libbsp/powerpc/ppcn_60x/console/console.c | 358 +++++++ .../lib/libbsp/powerpc/ppcn_60x/console/console.h | 67 ++ c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c | 1073 ++++++++++++++++++++ .../lib/libbsp/powerpc/ppcn_60x/console/i8042_p.h | 196 ++++ .../lib/libbsp/powerpc/ppcn_60x/console/i8042vga.c | 46 + .../lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h | 34 + .../lib/libbsp/powerpc/ppcn_60x/console/ns16550.c | 632 ++++++++++++ .../lib/libbsp/powerpc/ppcn_60x/console/ns16550.h | 40 + .../libbsp/powerpc/ppcn_60x/console/ns16550_p.h | 196 ++++ .../libbsp/powerpc/ppcn_60x/console/ns16550cfg.c | 53 + .../libbsp/powerpc/ppcn_60x/console/ns16550cfg.h | 55 + c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c | 368 +++++++ c/src/lib/libbsp/powerpc/ppcn_60x/console/vga_p.h | 70 ++ c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.c | 917 +++++++++++++++++ c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.h | 52 + .../lib/libbsp/powerpc/ppcn_60x/console/z85c30_p.h | 385 +++++++ .../libbsp/powerpc/ppcn_60x/console/z85c30cfg.c | 96 ++ .../libbsp/powerpc/ppcn_60x/console/z85c30cfg.h | 64 ++ .../libbsp/powerpc/ppcn_60x/include/Makefile.in | 36 + c/src/lib/libbsp/powerpc/ppcn_60x/include/bsp.h | 465 +++++++++ c/src/lib/libbsp/powerpc/ppcn_60x/include/chain.h | 362 +++++++ .../lib/libbsp/powerpc/ppcn_60x/include/coverhd.h | 119 +++ .../libbsp/powerpc/ppcn_60x/include/extisrdrv.h | 41 + c/src/lib/libbsp/powerpc/ppcn_60x/include/nvram.h | 60 ++ c/src/lib/libbsp/powerpc/ppcn_60x/include/pci.h | 322 ++++++ c/src/lib/libbsp/powerpc/ppcn_60x/include/tod.h | 38 + .../libbsp/powerpc/ppcn_60x/network/Makefile.in | 54 + .../libbsp/powerpc/ppcn_60x/network/amd79c970.c | 1010 ++++++++++++++++++ .../libbsp/powerpc/ppcn_60x/network/amd79c970.h | 426 ++++++++ .../lib/libbsp/powerpc/ppcn_60x/nvram/Makefile.in | 56 + c/src/lib/libbsp/powerpc/ppcn_60x/nvram/ds1385.h | 39 + c/src/lib/libbsp/powerpc/ppcn_60x/nvram/mk48t18.h | 87 ++ c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c | 515 ++++++++++ c/src/lib/libbsp/powerpc/ppcn_60x/nvram/prepnvr.h | 127 +++ c/src/lib/libbsp/powerpc/ppcn_60x/nvram/stk11c68.h | 46 + c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in | 56 + c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c | 342 +++++++ .../lib/libbsp/powerpc/ppcn_60x/start/Makefile.in | 54 + c/src/lib/libbsp/powerpc/ppcn_60x/start/start.S | 153 +++ .../libbsp/powerpc/ppcn_60x/startup/Makefile.in | 62 ++ .../lib/libbsp/powerpc/ppcn_60x/startup/bspclean.c | 30 + .../lib/libbsp/powerpc/ppcn_60x/startup/bspstart.c | 305 ++++++ .../lib/libbsp/powerpc/ppcn_60x/startup/bsptrap.S | 25 + .../lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c | 355 +++++++ c/src/lib/libbsp/powerpc/ppcn_60x/startup/linkcmds | 173 ++++ .../libbsp/powerpc/ppcn_60x/startup/rtems-ctor.cc | 124 +++ c/src/lib/libbsp/powerpc/ppcn_60x/startup/setvec.c | 55 + .../lib/libbsp/powerpc/ppcn_60x/startup/spurious.c | 202 ++++ c/src/lib/libbsp/powerpc/ppcn_60x/startup/swap.c | 64 ++ .../lib/libbsp/powerpc/ppcn_60x/timer/Makefile.in | 59 ++ c/src/lib/libbsp/powerpc/ppcn_60x/timer/timer.c | 82 ++ c/src/lib/libbsp/powerpc/ppcn_60x/tod/Makefile.in | 56 + c/src/lib/libbsp/powerpc/ppcn_60x/tod/cmos.h | 95 ++ c/src/lib/libbsp/powerpc/ppcn_60x/tod/tod.c | 617 +++++++++++ .../libbsp/powerpc/ppcn_60x/universe/Makefile.in | 54 + .../libbsp/powerpc/ppcn_60x/universe/universe.c | 449 ++++++++ .../libbsp/powerpc/ppcn_60x/vectors/Makefile.in | 59 ++ c/src/lib/libbsp/powerpc/ppcn_60x/vectors/README | 25 + .../lib/libbsp/powerpc/ppcn_60x/vectors/align_h.S | 434 ++++++++ .../lib/libbsp/powerpc/ppcn_60x/vectors/vectors.S | 297 ++++++ .../lib/libbsp/powerpc/ppcn_60x/wrapup/Makefile.in | 59 ++ 68 files changed, 13249 insertions(+) create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/README create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/STATUS create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/bsp_specs create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/clock/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/clock/clock.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042_p.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/vga_p.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30_p.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/bsp.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/chain.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/coverhd.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/extisrdrv.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/nvram.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/pci.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/include/tod.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/nvram/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/nvram/ds1385.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/nvram/mk48t18.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/nvram/prepnvr.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/nvram/stk11c68.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/start/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/start/start.S create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspclean.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspstart.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/bsptrap.S create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/linkcmds create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/rtems-ctor.cc create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/setvec.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/spurious.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/startup/swap.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/timer/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/timer/timer.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/tod/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/tod/cmos.h create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/tod/tod.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/universe/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/universe/universe.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/vectors/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/vectors/README create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/vectors/align_h.S create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/vectors/vectors.S create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/wrapup/Makefile.in (limited to 'c') diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/Makefile.in new file mode 100644 index 0000000000..ff468879d0 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/Makefile.in @@ -0,0 +1,25 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/directory.cfg + +SRCS=README + +# We only build the network device driver if HAS_NETWORK was defined +# NETWORK_DRIVER_yes_V = network +# NETWORK_DRIVER = $(NETWORK_DRIVER_$(HAS_NETWORK)_V) + +all: $(SRCS) + +# wrapup is the one that actually builds and installs the library +# from the individual .rel files built in other directories +SUB_DIRS=include clock console startup start timer tod \ + $(NETWORK_DRIVER) universe pci nvram vectors wrapup diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/README b/c/src/lib/libbsp/powerpc/ppcn_60x/README new file mode 100644 index 0000000000..197c652369 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/README @@ -0,0 +1,48 @@ +# +# $Id$ +# + +BSP NAME: psim +BOARD: PowerPC Simulator +BUS: N/A +CPU FAMILY: ppc +CPU: PowerPC 603, 603e, 604 +COPROCESSORS: N/A +MODE: 32 bit mode + +DEBUG MONITOR: BUG mode (emulates Motorola debug monitor) + +PERIPHERALS +=========== +TIMERS: PPC internal Timebase register + RESOLUTION: ??? +SERIAL PORTS: simulated via bug +REAL-TIME CLOCK: PPC internal Decrementer register +DMA: none +VIDEO: none +SCSI: none +NETWORKING: none + +DRIVER INFORMATION +================== +CLOCK DRIVER: PPC internal +IOSUPP DRIVER: N/A +SHMSUPP: N/A +TIMER DRIVER: PPC internal +TTY DRIVER: PPC internal + +STDIO +===== +PORT: Console port 0 +ELECTRICAL: na +BAUD: na +BITS PER CHARACTER: na +PARITY: na +STOP BITS: na + +Notes +===== + +Based on papyrus bsp which only really supports +the PowerOpen ABI with an ELF assembler. + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/STATUS b/c/src/lib/libbsp/powerpc/ppcn_60x/STATUS new file mode 100644 index 0000000000..cc05554441 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/STATUS @@ -0,0 +1,8 @@ +# +# $Id$ +# + +These are the notes made while updating this BSP to a more current +RTEMS version. + + + device-tree is psim specific and was removed diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/bsp_specs b/c/src/lib/libbsp/powerpc/ppcn_60x/bsp_specs new file mode 100644 index 0000000000..ab5a8ddbeb --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/bsp_specs @@ -0,0 +1,23 @@ +%rename cpp old_cpp +%rename lib old_lib +%rename endfile old_endfile +%rename startfile old_startfile +%rename link old_link + +*cpp: +%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded) + +*lib: +%{!qrtems: %(old_lib)} %{qrtems: --start-group \ +%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \ +-lc -lgcc --end-group ecrtn%O%s \ +%{!qnolinkcmds: -T linkcmds%s}} + +*startfile: +%{!qrtems: %(old_startfile)} %{qrtems: ecrti%O%s \ +%{!qrtems_debug: start.o%s} \ +%{qrtems_debug: start_g.o%s}} + +*link: +%{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -T linkcmds%s -e _start -u __vectors} + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/clock/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/clock/Makefile.in new file mode 100644 index 0000000000..7c2cfc0772 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/clock/Makefile.in @@ -0,0 +1,59 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/clock.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=clock +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES= +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/clock/clock.c b/c/src/lib/libbsp/powerpc/ppcn_60x/clock/clock.c new file mode 100644 index 0000000000..29ca97be32 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/clock/clock.c @@ -0,0 +1,241 @@ +/* + * Clock Tick Device Driver + * + * This routine utilizes the Decrementer Register common to the PPC family. + * + * The tick frequency is directly programmed to the configured number of + * microseconds per tick. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +#include +#include +#include + +/* + * The Real Time Clock Counter Timer uses this trap type. + */ + +#define CLOCK_VECTOR PPC_IRQ_DECREMENTER + +/* + * Clock ticks since initialization + */ + +volatile rtems_unsigned32 Clock_driver_ticks; + +/* + * This is the value programmed into the count down timer. + */ + +rtems_unsigned32 Clock_Decrementer_value; + +rtems_isr_entry Old_ticker; + +void Clock_exit( void ); + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +#define PPC_Set_decrementer( _clicks ) \ + do { \ + asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \ + } while (0) + + +/* + * Clock_isr + * + * This is the clock tick interrupt handler. + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + * + */ +rtems_isr Clock_isr( + rtems_vector_number vector, + CPU_Interrupt_frame *frame +) +{ + /* + * Set the decrementer. + */ + + PPC_Set_decrementer( Clock_Decrementer_value ); + + /* + * The driver has seen another tick. + */ + + Clock_driver_ticks += 1; + + /* + * Real Time Clock counter/timer is set to automatically reload. + */ + + rtems_clock_tick(); +} + +/* + * Install_clock + * + * This routine actually performs the hardware initialization for the clock. + * + * Input parameters: + * clock_isr - clock interrupt service routine entry point + * + * Output parameters: NONE + * + * Return values: NONE + * + */ + +extern int CLOCK_SPEED; + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + Clock_driver_ticks = 0; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + + PPC_Set_decrementer( Clock_Decrementer_value ); + + atexit( Clock_exit ); + } +} + +/* + * Clock_exit + * + * This routine allows the clock driver to exit by masking the interrupt and + * disabling the clock's counter. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: NONE + * + */ + +void Clock_exit( void ) +{ + if ( BSP_Configuration.ticks_per_timeslice ) { + + /* nothing to do */; + + /* do not restore old vector */ + } +} + +/* + * Clock_initialize + * + * This routine initializes the clock driver. + * + * Input parameters: + * major - clock device major number + * minor - clock device minor number + * parg - pointer to optional device driver arguments + * + * Output parameters: NONE + * + * Return values: + * rtems_device_driver status code + */ + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + Clock_Decrementer_value = (ulCpuBusClock/4000)* + (BSP_Configuration.microseconds_per_tick/1000); + + Install_clock((rtems_isr_entry)Clock_isr); + + /* + * make major/minor avail to others such as shared memory driver + */ + + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} + +/* + * Clock_control + * + * This routine is the clock device driver control entry point. + * + * Input parameters: + * major - clock device major number + * minor - clock device minor number + * parg - pointer to optional device driver arguments + * + * Output parameters: NONE + * + * Return values: + * rtems_device_driver status code + */ + +rtems_device_driver Clock_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + rtems_unsigned32 isrlevel; + rtems_libio_ioctl_args_t *args = pargp; + + if (args == 0) + goto done; + + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) + { + Clock_isr( CLOCK_VECTOR, pargp ); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + rtems_interrupt_disable( isrlevel ); + (void) set_vector( args->buffer, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); + } + +done: + return RTEMS_SUCCESSFUL; +} + + + + + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in new file mode 100644 index 0000000000..4c05c37698 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in @@ -0,0 +1,54 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/console.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=console ns16550 z85c30 i8042vga i8042 vga +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c new file mode 100644 index 0000000000..6b60503ec9 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c @@ -0,0 +1,358 @@ +/* + * This file contains the TTY driver 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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include "console.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; + + /* + * Patch in flow control routines + */ +/* XXX */ +#if 0 + if((status==RTEMS_SUCCESSFUL) && + (Console_Port_Tbl[minor].pDeviceFlow)) + { + status=rtems_termios_flow_control( + major, minor, arg, + Console_Port_Tbl[minor].pDeviceFlow-> + deviceStartRemoteTx, + Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx, + Console_Port_Tbl[minor].ulMargin, + Console_Port_Tbl[minor].ulHysteresis); + } +#endif + + 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; +} + +void console_reserve_resources( + rtems_configuration_table *configuration +) +{ + rtems_termios_reserve_resources( configuration, 2 ); +} + + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_open_close_args_t *args = arg; + + if((args->iop->flags&LIBIO_FLAGS_READ) && + Console_Port_Tbl[minor].pDeviceFlow && + Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx) + { + Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor); + } + + return rtems_termios_close (arg); +} + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read (arg); +} + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write (arg); +} + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} + +/* PAGE + * + * console_initialize + * + * Routine called to initialize the console device driver. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + /* + * initialize the termio interface. + */ + rtems_termios_initialize(); + + Console_Port_Count=NUM_CONSOLE_PORTS; + + for(minor=0; + minordeviceProbe(minor)) + { + /* + * Use this device for the console + */ + break; + } + } + if(minor==Console_Port_Count) + { + /* + * Failed to find a working device + */ + rtems_fatal_error_occurred(RTEMS_IO_ERROR); + } + + Console_Port_Minor=minor; + + /* + * Register Device Names + */ + status = rtems_io_register_name("/dev/console", + major, + Console_Port_Minor ); + if (status != RTEMS_SUCCESSFUL) + { + rtems_fatal_error_occurred(status); + } + Console_Port_Tbl[minor].pDeviceFns->deviceInitialize( + Console_Port_Minor); + + for(minor++;minordeviceProbe(minor)) + { + status = rtems_io_register_name( + Console_Port_Tbl[minor].sDeviceName, + major, + minor ); + if (status != RTEMS_SUCCESSFUL) + { + rtems_fatal_error_occurred(status); + } + + /* + * Initialize the hardware device. + */ + 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); +} + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h new file mode 100644 index 0000000000..1d6b6fc2b1 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h @@ -0,0 +1,67 @@ +/* + * 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. + * + * $Id$ + */ + +#include + +typedef struct _console_fns { + boolean (*deviceProbe)(int minor); + int (*deviceFirstOpen)(int major, int minor, void *arg); + int (*deviceLastClose)(int major, int minor, void *arg); + int (*deviceRead)(int minor); + int (*deviceWrite)(int minor, const char *buf, int len); + void (*deviceInitialize)(int minor); + int (*deviceSetAttributes)(int minor, const struct termios *); + void (*deviceWritePolled)(int minor, char cChar); + int deviceOutputUsesInterrupts; +} console_fns; + +typedef struct _console_flow { + int (*deviceStopRemoteTx)(int minor); + int (*deviceStartRemoteTx)(int minor); +} console_flow; + +typedef struct _console_tbl { + char *sDeviceName; + console_fns *pDeviceFns; + boolean (*deviceProbe)(int minor); + console_flow *pDeviceFlow; + unsigned32 ulMargin; + unsigned32 ulHysteresis; + void *pDeviceParams; + unsigned32 ulCtrlPort1; + unsigned32 ulCtrlPort2; + unsigned32 ulDataPort; + unsigned int ulIntVector; +} console_tbl; + +typedef struct _console_data { + void *termios_data; + volatile boolean bActive; + volatile Ring_buffer_t TxBuffer; + /* + * This field may be used for any purpose required by the driver + */ + void *pDeviceContext; +} console_data; + +extern console_tbl Console_Port_Tbl[]; +extern console_data Console_Port_Data[]; +extern unsigned long Console_Port_Count; diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c new file mode 100644 index 0000000000..dcfd68e72d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c @@ -0,0 +1,1073 @@ +/* + * This file contains the PS2 keyboard driver for the i8042 + * + * Note that this driver will only handle a single i8042 device + * + * 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. + * + * This driver uses the termios pseudo driver. + * + * $Id$ + */ + +#include +#include +#include +#include + +#include "console.h" +#include "i8042_p.h" +#include "vga_p.h" + +/* + * UK style keyboard + */ +char pcUKNormalLookup[] = "1234567890-=\b\tqwertyuiop[]\n\0asdfghjkl;\'" + "`\0#zxcvbnm,./\0*\0 \0\0\0\0\0\0\0\0\0\0\0\0" + "\000789-456+1230.\0\0\\"; +char pcUKShiftedLookup[]= "!\"£$%^&*()_+\b\tQWERTYUIOP{}\n\0ASDFGHJKL:" + "@\0\0~ZXCVBNM<>?\0*\0 \0\0\0\0\0\0\0\0\0\0\0" + "\0\000789-456+1230.\0\0|"; +/* + * US style keyboard + */ +char pcUSNormalLookup[] = "1234567890-=\b\tqwertyuiop[]\n\0asdfghjkl;\'" + "`\0\\zxcvbnm,./\0*\0 \0\0\0\0\0\0\0\0\0\0\0" + "\0\000789-456+1230.\0\0\\"; +char pcUSShiftedLookup[]= "!@#$%^&*()_+\b\tQWERTYUIOP{}\n\0ASDFGHJKL:@~" + "\0|ZXCVBNM<>?\0*\0 \0\0\0\0\0\0\0\0\0\0\0\0" + "\000789-456+1230.\0\0|"; + +static char *pcNormalLookup; +static char *pcShiftedLookup; + +/* + * This is exported to vga.c to provide flow control + */ +volatile boolean bScrollLock=FALSE; + +/* + * If multiple devices are to be supported then a private copy of + * the following will be required for each instance + */ +static boolean bCtrlPressed=FALSE; +static boolean bAltPressed=FALSE; +static boolean bAltGrPressed=FALSE; +static boolean bLShiftPressed=FALSE; +static boolean bRShiftPressed=FALSE; +static boolean bCapsLock=FALSE; +static boolean bNumLock=FALSE; +static boolean bTwoCode=FALSE; + +#if CONSOLE_USE_INTERRUPTS +static volatile Ring_buffer_t KbdOutputBuffer; +static volatile boolean bProcessInterruptInput=FALSE; +static boolean bInterruptsEnabled=FALSE; +static volatile boolean bReceivedAck=TRUE; + +static void i8042_process( + int minor +); + +static void i8042_scan_code( + int minor, + unsigned8 ucScan +); +#endif + +static volatile Ring_buffer_t KbdInputBuffer; + +/* + * The following routines enable an interrupt driver to switch + * to polled mode as required for command processing + */ +void i8042_polled_on( + int minor +) +{ +#if CONSOLE_USE_INTERRUPTS + bProcessInterruptInput=FALSE; +#endif +} + +void i8042_polled_off( + int minor +) +{ +#if CONSOLE_USE_INTERRUPTS + unsigned32 Irql; + unsigned8 ucScan; + + /* + * Make sure we have processed everything outstanding + */ + rtems_interrupt_disable(Irql); + while(!Ring_buffer_Is_empty(&KbdInputBuffer)) + { + rtems_interrupt_enable(Irql); + Ring_buffer_Remove_character(&KbdInputBuffer, + ucScan); + i8042_scan_code(minor, ucScan); + rtems_interrupt_disable(Irql); + } + bProcessInterruptInput=TRUE; + rtems_interrupt_enable(Irql); +#endif +} + +/* + * Send data to the keyboard + */ +static rtems_status_code +i8042_outbyte_raw( + int minor, + unsigned8 ucData +) +{ + unsigned32 i; + unsigned8 Status; + +#if CONSOLE_USE_INTERRUPTS + unsigned32 Irql; + + if(bInterruptsEnabled) + { + Ring_buffer_Add_character(&KbdOutputBuffer, + ucData); + if(!Console_Port_Data[minor].bActive) + { + /* + * Wake up the device + */ + rtems_interrupt_disable(Irql); + Console_Port_Data[minor].bActive=TRUE; + i8042_process(minor); + rtems_interrupt_enable(Irql); + + } + return RTEMS_SUCCESSFUL; + } +#endif + for (i=0; i= 16) && (ucScan <= 25)) || + ((ucScan >= 30) && (ucScan <= 38)) || + ((ucScan >= 44) && (ucScan <= 50))) + { + if(bCtrlPressed) + { + cChar=pcNormalLookup[ucScan - 2]-'a'+1; + } + else + { + if(((bLShiftPressed || bRShiftPressed) && !bCapsLock) || + (!(bLShiftPressed || bRShiftPressed) && bCapsLock)) + { + cChar=pcShiftedLookup[ucScan - 2]; + } + else + { + cChar=pcNormalLookup[ucScan - 2]; + } + } + } + else if((ucScan > 1) && (ucScan <= 0x56)) + { + /* + * Its ASCII but not alpha, so don't shift on CapsLock. + */ + if(bLShiftPressed || bRShiftPressed) + { + cChar=pcShiftedLookup[ucScan - 2]; + } + else + { + cChar=pcNormalLookup[ucScan - 2]; + } + } + + /* + * If we got a character then queue it + */ + if(cChar) + { + EnqueueKbdChar(minor, cChar); + } +} + +/* + * Console Device Driver Entry Points + */ +boolean i8042_probe(int minor) +{ + unsigned8 ucKeyboardAck; + unsigned8 ucKeyboardID1, ucKeyboardID2; + + if(!vga_probe(minor)) + { + /* + * There is no VGA adaptor so fail probe + */ + return(FALSE); + } + + Ring_buffer_Initialize(&KbdInputBuffer); +#if CONSOLE_USE_INTERRUPTS + Ring_buffer_Initialize(&KbdOutputBuffer); +#endif + + i8042_polled_on(minor); + /* + * Determine keyboard type + */ + i8042_outbyte_raw(minor, KBD_CMD_READ_ID); + ucKeyboardAck=0; + if((i8042_inbyte_raw(minor, &ucKeyboardAck)==RTEMS_TIMEOUT) || + (ucKeyboardAck==KBD_CMD_RESEND)) + { + /* + * No or incorrect keyboard response so fail probe + */ + return(FALSE); + } + + i8042_inbyte_raw(minor, &ucKeyboardID1); + i8042_inbyte_raw(minor, &ucKeyboardID2); + if((ucKeyboardID1==0xab) && (ucKeyboardID2==0x41)) + { + pcNormalLookup=&pcUKNormalLookup[0]; + pcShiftedLookup=&pcUKShiftedLookup[0]; + } + else + { + pcNormalLookup=&pcUSNormalLookup[0]; + pcShiftedLookup=&pcUSShiftedLookup[0]; + } + i8042_polled_off(minor); + + return(TRUE); +} + +void i8042_init(int minor) +{ + unsigned8 ucKeyboardAck; + + vga_init(minor); + + i8042_polled_on(minor); + /* + * Switch all LEDs off + */ + i8042_outbyte_raw(minor, KBD_CMD_SET_LEDS); + i8042_inbyte_raw(minor, &ucKeyboardAck); + i8042_outbyte_raw(minor, 0); + i8042_inbyte_raw(minor, &ucKeyboardAck); + /* + * Select scan code set 1 + */ + i8042_outbyte_raw(minor, KBD_CMD_SEL_SCAN_CODE); + i8042_inbyte_raw(minor, &ucKeyboardAck); + i8042_outbyte_raw(minor, 1); + i8042_inbyte_raw(minor, &ucKeyboardAck); + i8042_polled_off(minor); +} + +/* PAGE + * + * i8042_inbyte_nonblocking_polled + * + * Console Termios polling input entry point. + */ + +int i8042_inbyte_nonblocking_polled( + int minor +) +{ + unsigned8 ucScan; + char ucData; + + if(i8042_inbyte_polled(minor, &ucScan)==RTEMS_SUCCESSFUL) + { + i8042_scan_code(minor, ucScan); + } + + if(!Ring_buffer_Is_empty(&KbdInputBuffer)) + { + Ring_buffer_Remove_character(&KbdInputBuffer, + ucData); + return(ucData); + } + + return(-1); +} + +#if CONSOLE_USE_INTERRUPTS +/* + * i8042_isr + * + * This routine is the console interrupt handler for the keyboard + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ +static void i8042_process( + int minor +) +{ + unsigned8 Status; + unsigned8 ucData; + + inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status); + + if(Status & KBD_OBF_MASK) + { + inport_byte(Console_Port_Tbl[minor].ulDataPort, ucData); + + if(bProcessInterruptInput) + { + /* + * Every byte written to the keyboard should be followed + * by an acknowledge + */ + if(ucData==KBD_CMD_ACK) + { + bReceivedAck=TRUE; + } + else + { + i8042_scan_code(minor, ucData); + } + } + else + { + /* + * Store the scan code into the ring buffer where it + * can be read using i8042_inbyte_raw() + */ + Ring_buffer_Add_character(&KbdInputBuffer, ucData); + } + } + + if(((Status & KBD_IBF_MASK)==0) && + bReceivedAck) + { + if(Ring_buffer_Is_empty(&KbdOutputBuffer)) + { + Console_Port_Data[minor].bActive=FALSE; + } + else + { + Ring_buffer_Remove_character(&KbdOutputBuffer, + ucData); + outport_byte(Console_Port_Tbl[minor].ulDataPort, + ucData); + bReceivedAck=FALSE; + } + } +} + +static rtems_isr i8042_isr( + rtems_vector_number vector +) +{ + int minor; + + for(minor=0;minor +#include +#include + +#include "console.h" +#include "vga_p.h" +#include "i8042_p.h" + +console_fns i8042vga_fns = +{ + i8042_probe, /* deviceProbe */ + NULL, /* deviceFirstOpen */ + NULL, /* deviceLastClose */ +#if CONSOLE_USE_INTERRUPTS + NULL, /* deviceRead */ + vga_write_support, /* deviceWrite */ + i8042_initialize_interrupts, /* deviceInitialize */ +#else + i8042_inbyte_nonblocking_polled, /* deviceRead */ + vga_write_support, /* deviceWrite */ + i8042_init, /* deviceInitialize */ +#endif + vga_write, /* deviceWritePolled */ + FALSE, /* deviceOutputUsesInterrupts */ +}; diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h new file mode 100644 index 0000000000..6cbceb92de --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h @@ -0,0 +1,34 @@ +/* + * 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. + * + * $Id$ + */ + +#ifndef _I8042VGA_H_ +#define _I8042VGA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Driver function table + */ +extern console_fns i8042vga_fns; + +#ifdef __cplusplus +} +#endif + +#endif /* _I8042VGA_H_ */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c new file mode 100644 index 0000000000..30c10f73b2 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c @@ -0,0 +1,632 @@ +/* + * This file contains the TTY driver for the NS16550 + * + * 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. + * + * This driver uses the termios pseudo driver. + */ + +#include +#include +#include +#include + +#include "console.h" +#include "ns16550_p.h" + +/* + * Flow control is only supported when using interrupts + */ +console_flow ns16550_flow_RTSCTS = +{ + ns16550_negate_RTS, /* deviceStopRemoteTx */ + ns16550_assert_RTS /* deviceStartRemoteTx */ +}; + +console_flow ns16550_flow_DTRCTS = +{ + ns16550_negate_DTR, /* deviceStopRemoteTx */ + ns16550_assert_DTR /* deviceStartRemoteTx */ +}; + +console_fns ns16550_fns = +{ + ns16550_probe, /* deviceProbe */ + ns16550_open, /* deviceFirstOpen */ + ns16550_flush, /* deviceLastClose */ + NULL, /* deviceRead */ + ns16550_write_support_int, /* deviceWrite */ + ns16550_initialize_interrupts, /* deviceInitialize */ + ns16550_write_polled, /* deviceWritePolled */ + FALSE, /* deviceOutputUsesInterrupts */ +}; + +console_fns ns16550_fns_polled = +{ + ns16550_probe, /* deviceProbe */ + ns16550_open, /* deviceFirstOpen */ + ns16550_close, /* deviceLastClose */ + ns16550_inbyte_nonblocking_polled, /* deviceRead */ + ns16550_write_support_polled, /* deviceWrite */ + ns16550_init, /* deviceInitialize */ + ns16550_write_polled, /* deviceWritePolled */ + FALSE, /* deviceOutputUsesInterrupts */ +}; + +/* + * Console Device Driver Entry Points + */ +static boolean ns16550_probe(int minor) +{ + /* + * If the configuration dependant probe has located the device then + * assume it is there + */ + return(TRUE); +} + +static void ns16550_init(int minor) +{ + PSP_READ_REGISTERS pNS16550Read; + PSP_WRITE_REGISTERS pNS16550Write; + unsigned8 ucTrash; + unsigned8 ucDataByte; + unsigned32 ulBaudDivisor; + ns16550_context *pns16550Context; + + pns16550Context=(ns16550_context *)malloc(sizeof(ns16550_context)); + + Console_Port_Data[minor].pDeviceContext=(void *)pns16550Context; + pns16550Context->ucModemCtrl=SP_MODEM_IRQ; + + pNS16550Read=(PSP_READ_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + pNS16550Write=(PSP_WRITE_REGISTERS)pNS16550Read; + + /* Clear the divisor latch, clear all interrupt enables, + * and reset and + * disable the FIFO's. + */ + + outport_byte(&pNS16550Write->LineControl, 0x0); + outport_byte(&pNS16550Write->InterruptEnable, 0x0); + + /* Set the divisor latch and set the baud rate. */ + + ulBaudDivisor=NS16550_Baud( + (unsigned32)Console_Port_Tbl[minor].pDeviceParams); + ucDataByte = SP_LINE_DLAB; + outport_byte(&pNS16550Write->LineControl, ucDataByte); + outport_byte(&pNS16550Write->TransmitBuffer, ulBaudDivisor&0xff); + outport_byte(&pNS16550Write->InterruptEnable, (ulBaudDivisor>>8)&0xff); + + /* Clear the divisor latch and set the character size to eight bits */ + /* with one stop bit and no parity checking. */ + + ucDataByte = EIGHT_BITS; + outport_byte(&pNS16550Write->LineControl, ucDataByte); + + /* Enable and reset transmit and receive FIFOs. TJA */ + ucDataByte = SP_FIFO_ENABLE; + outport_byte(&pNS16550Write->FifoControl, ucDataByte); + + ucDataByte = SP_FIFO_ENABLE | SP_FIFO_RXRST | SP_FIFO_TXRST; + outport_byte(&pNS16550Write->FifoControl, ucDataByte); + + /* + * Disable interrupts + */ + ucDataByte = 0; + outport_byte(&pNS16550Write->InterruptEnable, ucDataByte); + + /* Set data terminal ready. */ + /* And open interrupt tristate line */ + + outport_byte(&pNS16550Write->ModemControl, + pns16550Context->ucModemCtrl); + + inport_byte(&pNS16550Read->LineStatus, ucTrash); + inport_byte(&pNS16550Read->ReceiveBuffer, ucTrash); +} + +static int ns16550_open( + int major, + int minor, + void * arg +) +{ + PSP_WRITE_REGISTERS pNS16550Write; + + pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Assert DTR + */ + if(Console_Port_Tbl[minor].pDeviceFlow + !=&ns16550_flow_DTRCTS) + { + ns16550_assert_DTR(minor); + } + + return(RTEMS_SUCCESSFUL); +} + +static int ns16550_close( + int major, + int minor, + void * arg +) +{ + PSP_WRITE_REGISTERS pNS16550Write; + + pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Negate DTR + */ + if(Console_Port_Tbl[minor].pDeviceFlow + !=&ns16550_flow_DTRCTS) + { + ns16550_negate_DTR(minor); + } + + return(RTEMS_SUCCESSFUL); +} + +/* + * ns16550_write_polled + */ +static void ns16550_write_polled( + int minor, + char cChar +) +{ + PSP_READ_REGISTERS pNS16550Read; + PSP_WRITE_REGISTERS pNS16550Write; + unsigned char ucLineStatus; + int iTimeout; + + pNS16550Read=(PSP_READ_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + pNS16550Write=(PSP_WRITE_REGISTERS)pNS16550Read; + + /* + * wait for transmitter holding register to be empty + */ + iTimeout=1000; + inport_byte(&pNS16550Read->LineStatus, ucLineStatus); + while ((ucLineStatus & SP_LSR_THOLD) == 0) + { + /* + * Yield while we wait + */ + if(_System_state_Is_up(_System_state_Get())) + { + rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); + } + inport_byte(&pNS16550Read->LineStatus, ucLineStatus); + if(!--iTimeout) + { + break; + } + } + + /* + * transmit character + */ + outport_byte(&pNS16550Write->TransmitBuffer, cChar); +} + +/* + * These routines provide control of the RTS and DTR lines + */ +/* + * ns16550_assert_RTS + */ +static void ns16550_assert_RTS(int minor) +{ + PSP_WRITE_REGISTERS pNS16550Write; + unsigned32 Irql; + ns16550_context *pns16550Context; + + pns16550Context=(ns16550_context *) + Console_Port_Data[minor].pDeviceContext; + + pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Assert RTS + */ + rtems_interrupt_disable(Irql); + pns16550Context->ucModemCtrl|=SP_MODEM_RTS; + outport_byte(&pNS16550Write->ModemControl, + pns16550Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * ns16550_negate_RTS + */ +static void ns16550_negate_RTS(int minor) +{ + PSP_WRITE_REGISTERS pNS16550Write; + unsigned32 Irql; + ns16550_context *pns16550Context; + + pns16550Context=(ns16550_context *) + Console_Port_Data[minor].pDeviceContext; + + pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Negate RTS + */ + rtems_interrupt_disable(Irql); + pns16550Context->ucModemCtrl&=~SP_MODEM_RTS; + outport_byte(&pNS16550Write->ModemControl, + pns16550Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * These flow control routines utilise a connection from the local DTR + * line to the remote CTS line + */ +/* + * ns16550_assert_DTR + */ +static void ns16550_assert_DTR(int minor) +{ + PSP_WRITE_REGISTERS pNS16550Write; + unsigned32 Irql; + ns16550_context *pns16550Context; + + pns16550Context=(ns16550_context *) + Console_Port_Data[minor].pDeviceContext; + + pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Assert DTR + */ + rtems_interrupt_disable(Irql); + pns16550Context->ucModemCtrl|=SP_MODEM_DTR; + outport_byte(&pNS16550Write->ModemControl, + pns16550Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * ns16550_negate_DTR + */ +static void ns16550_negate_DTR(int minor) +{ + PSP_WRITE_REGISTERS pNS16550Write; + unsigned32 Irql; + ns16550_context *pns16550Context; + + pns16550Context=(ns16550_context *) + Console_Port_Data[minor].pDeviceContext; + + pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Negate DTR + */ + rtems_interrupt_disable(Irql); + pns16550Context->ucModemCtrl&=~SP_MODEM_DTR; + outport_byte(&pNS16550Write->ModemControl, + pns16550Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * ns16550_isr + * + * This routine is the console interrupt handler for COM1 and COM2 + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ + +static void ns16550_process( + int minor +) +{ + PSP_READ_REGISTERS pNS16550Read; + PSP_WRITE_REGISTERS pNS16550Write; + volatile unsigned8 ucLineStatus, ucInterruptId; + char cChar; + + pNS16550Read=(PSP_READ_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1; + pNS16550Write=(PSP_WRITE_REGISTERS)pNS16550Read; + + do + { + /* + * Deal with any received characters + */ + while(TRUE) + { + inport_byte(&pNS16550Read->LineStatus, ucLineStatus); + if(~ucLineStatus & SP_LSR_RDY) + { + break; + } + inport_byte(&pNS16550Read->ReceiveBuffer, cChar); + rtems_termios_enqueue_raw_characters( + Console_Port_Data[minor].termios_data, + &cChar, 1 ); + } + + while(TRUE) + { + if(Ring_buffer_Is_empty( + &Console_Port_Data[minor].TxBuffer)) + { + Console_Port_Data[minor].bActive=FALSE; + if(Console_Port_Tbl[minor].pDeviceFlow + !=&ns16550_flow_RTSCTS) + { + ns16550_negate_RTS(minor); + } + /* + * There is no data to transmit + */ + break; + } + + inport_byte(&pNS16550Read->LineStatus, ucLineStatus); + if(~ucLineStatus & SP_LSR_THOLD) + { + /* + * We'll get another interrupt when + * the transmitter holding reg. becomes + * free again + */ + break; + } + + Ring_buffer_Remove_character( + &Console_Port_Data[minor].TxBuffer, + cChar); + /* + * transmit character + */ + outport_byte(&pNS16550Write->TransmitBuffer, cChar); + } + + inport_byte(&pNS16550Read->InterruptId, ucInterruptId); + } + while((ucInterruptId&0xf)!=0x1); +} + +static rtems_isr ns16550_isr( + rtems_vector_number vector +) +{ + int minor; + + for(minor=0;minorInterruptEnable, ucDataByte); + +} + +static void ns16550_initialize_interrupts(int minor) +{ + ns16550_init(minor); + + Ring_buffer_Initialize(&Console_Port_Data[minor].TxBuffer); + + Console_Port_Data[minor].bActive = FALSE; + + set_vector(ns16550_isr, + Console_Port_Tbl[minor].ulIntVector, + 1); + + ns16550_enable_interrupts(minor); +} + +/* + * ns16550_write_support_int + * + * Console Termios output entry point. + * + */ +static int ns16550_write_support_int( + int minor, + const char *buf, + int len) +{ + int i; + unsigned32 Irql; + + for(i=0; iLineStatus, ucLineStatus); + if(ucLineStatus & SP_LSR_RDY) + { + inport_byte(&pNS16550Read->ReceiveBuffer, cChar); + return((int)cChar); + } + else + { + return(-1); + } +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h new file mode 100644 index 0000000000..e797ba2244 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +#ifndef _NS16550_H_ +#define _NS16550_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Driver function table + */ +extern console_fns ns16550_fns; +extern console_fns ns16550_fns_polled; + +/* + * Flow control function tables + */ +extern console_flow ns16550_flow_RTSCTS; +extern console_flow ns16550_flow_DTRCTS; + +#ifdef __cplusplus +} +#endif + +#endif /* _NS16550_H_ */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h new file mode 100644 index 0000000000..7f7f51afa9 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h @@ -0,0 +1,196 @@ +/* + * 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. + * + */ + +#ifndef _NS16550_P_H_ +#define _NS16550_P_H_ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Define serial port read registers structure. + */ + +typedef volatile struct _SP_READ_REGISTERS { + unsigned char ReceiveBuffer; + unsigned char InterruptEnable; + unsigned char InterruptId; + unsigned char LineControl; + unsigned char ModemControl; + unsigned char LineStatus; + unsigned char ModemStatus; + unsigned char ScratchPad; +} SP_READ_REGISTERS, *PSP_READ_REGISTERS; + +/* + * Define serial port write registers structure. + */ + +typedef volatile struct _SP_WRITE_REGISTERS { + unsigned char TransmitBuffer; + unsigned char InterruptEnable; + unsigned char FifoControl; + unsigned char LineControl; + unsigned char ModemControl; + unsigned char Reserved1; + unsigned char ModemStatus; + unsigned char ScratchPad; +} SP_WRITE_REGISTERS, *PSP_WRITE_REGISTERS; + +/* + * Define serial port interrupt enable register structure. + */ + +#define SP_INT_RX_ENABLE 0x01 +#define SP_INT_TX_ENABLE 0x02 +#define SP_INT_LS_ENABLE 0x04 +#define SP_INT_MS_ENABLE 0x08 + +/* + * Define serial port interrupt id register structure. + */ + +typedef struct _SP_INTERRUPT_ID { + unsigned char InterruptPending : 1; + unsigned char Identification : 3; + unsigned char Reserved1 : 2; + unsigned char FifoEnabled : 2; +} SP_INTERRUPT_ID, *PSP_INTERRUPT_ID; + +/* + * Define serial port fifo control register structure. + */ +#define SP_FIFO_ENABLE 0x01 +#define SP_FIFO_RXRST 0x02 +#define SP_FIFO_TXRST 0x04 +#define SP_FIFO_DMA 0x08 +#define SP_FIFO_RXLEVEL 0xc0 + +/* + * Define serial port line control register structure. + */ +#define SP_LINE_SIZE 0x03 +#define SP_LINE_STOP 0x04 +#define SP_LINE_PAR 0x08 +#define SP_LINE_ODD 0x10 +#define SP_LINE_STICK 0x20 +#define SP_LINE_BREAK 0x40 +#define SP_LINE_DLAB 0x80 + +/* + * Line status register character size definitions. + */ +#define FIVE_BITS 0x0 /* five bits per character */ +#define SIX_BITS 0x1 /* six bits per character */ +#define SEVEN_BITS 0x2 /* seven bits per character */ +#define EIGHT_BITS 0x3 /* eight bits per character */ + +/* + * Line speed divisor definition. + */ +#define NS16550_Baud(baud_rate) (115200/baud_rate) + +/* + * Define serial port modem control register structure. + */ +#define SP_MODEM_DTR 0x01 +#define SP_MODEM_RTS 0x02 +#define SP_MODEM_IRQ 0x08 +#define SP_MODEM_LOOP 0x10 +#define SP_MODEM_DIV4 0x80 + +/* + * Define serial port line status register structure. + */ +#define SP_LSR_RDY 0x01 +#define SP_LSR_EOVRUN 0x02 +#define SP_LSR_EPAR 0x04 +#define SP_LSR_EFRAME 0x08 +#define SP_LSR_BREAK 0x10 +#define SP_LSR_THOLD 0x20 +#define SP_LSR_TX 0x40 +#define SP_LSR_EFIFO 0x80 + +typedef struct _ns16550_context +{ + unsigned8 ucModemCtrl; +} ns16550_context; + +/* + * Driver functions + */ +static boolean ns16550_probe(int minor); + +static void ns16550_init(int minor); + +static int ns16550_open( + int major, + int minor, + void * arg +); + +static int ns16550_close( + int major, + int minor, + void * arg +); + +static void ns16550_write_polled( + int minor, + char cChar +); + +static void ns16550_assert_RTS( + int minor +); + +static void ns16550_negate_RTS( + int minor +); + +static void ns16550_assert_DTR( + int minor +); + +static void ns16550_negate_DTR( + int minor +); + +static void ns16550_initialize_interrupts(int minor); + +static int ns16550_flush(int major, int minor, void *arg); + +static int ns16550_write_support_int( + int minor, + const char *buf, + int len +); + +static int ns16550_write_support_polled( + int minor, + const char *buf, + int len + ); + +static int ns16550_inbyte_nonblocking_polled( + int minor +); + +#ifdef __cplusplus +} +#endif + +#endif /* _NS16550_P_H_ */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c new file mode 100644 index 0000000000..88cbde4bbe --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c @@ -0,0 +1,53 @@ +/* nc16550cfg.c + * + * 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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +unsigned8 Read_ns16550_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum +) +{ + unsigned char *p = (unsigned char *)ulCtrlPort; + unsigned char ucData; + + inport_byte( &p[ucRegNum], ucData ); + return ucData; +} + +void Write_ns16550_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum, + unsigned8 ucData +) +{ + unsigned char *p = (unsigned char *)ulCtrlPort; + + outport_byte( &p[ucRegNum], ucData ); +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h new file mode 100644 index 0000000000..87235a80f2 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h @@ -0,0 +1,55 @@ +/* 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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $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 +); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c new file mode 100644 index 0000000000..ed7a867d1d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c @@ -0,0 +1,368 @@ +/* + * This file contains the TTY driver for VGA + * + * 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. + * + * This driver uses the termios pseudo driver. + */ +/*-------------------------------------------------------------------------+ +| (C) Copyright 1997 - +| - NavIST Group - Real-Time Distributed Systems and Industrial Automation +| +| http://pandora.ist.utl.pt +| +| Instituto Superior Tecnico * Lisboa * PORTUGAL ++--------------------------------------------------------------------------+ +| Disclaimer: +| +| This file is provided "AS IS" without warranty of any kind, either +| expressed or implied. ++--------------------------------------------------------------------------+ +| This code is based on: +| outch.c,v 1.4 1995/12/19 20:07:27 joel Exp - go32 BSP +| With the following copyright notice: +| ************************************************************************** +| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. * +| * On-Line Applications Research Corporation (OAR). * +| * All rights assigned to U.S. Government, 1994. * +| * * +| * This material may be reproduced by or for the U.S. Government pursuant * +| * to the copyright license under the clause at DFARS 252.227-7013. This * +| * notice must appear in all copies of this file and its derivatives. * +| ************************************************************************** ++--------------------------------------------------------------------------*/ + + +#include + +#include +#include + +#include "vga_p.h" + +/*-------------------------------------------------------------------------+ +| Constants ++--------------------------------------------------------------------------*/ +#define DISPLAY_CELL_COUNT (VGA_NUM_ROWS * VGA_NUM_COLS) + /* Number of display cells. */ +#define TABSIZE 4 /* Number of spaces for TAB (\t) char. */ +#define WHITE 0x0007 /* White on Black background colour. */ +#define BLANK (WHITE | (' '<<8)) /* Blank character. */ + +/* + * This is imported from i8042.c to provide flow control + */ +extern volatile boolean bScrollLock; + +/*-------------------------------------------------------------------------+ +| Global Variables ++--------------------------------------------------------------------------*/ +/* Physical address of start of video text memory. */ +static unsigned16 *videoRam = (unsigned16 *)VGA_FB; +/* Pointer for current output position in display. */ +static unsigned16 *videoRamPtr = (unsigned16 *)VGA_FB; +static unsigned8 videoRows = VGA_NUM_ROWS; /* Number of rows in display. */ +static unsigned8 videoCols = VGA_NUM_COLS; /* Number of columns in display. */ +static unsigned8 cursRow = 0; /* Current cursor row. */ +static unsigned8 cursCol = 0; /* Current cursor column. */ + + +/*-------------------------------------------------------------------------+ +| Function: setHardwareCursorPos +| Description: Set hardware video cursor at given offset into video RAM. +| Global Variables: None. +| Arguments: videoCursor - Offset into video memory. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static inline void +setHardwareCursorPos(unsigned16 videoCursor) +{ + VGA_WRITE_CRTC(0x0e, (videoCursor >> 8) & 0xff); + VGA_WRITE_CRTC(0x0f, videoCursor & 0xff); +} /* setHardwareCursorPos */ + + +/*-------------------------------------------------------------------------+ +| Function: updateVideoRamPtr +| Description: Updates value of global variable "videoRamPtr" based on +| current window's cursor position. +| Global Variables: videoRamPtr, cursRow, cursCol. +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static inline void +updateVideoRamPtr(void) +{ + videoRamPtr = videoRam + cursRow * videoCols + cursCol; +} /* updateVideoRamPtr */ + + +/*-------------------------------------------------------------------------+ +| Function: scrollUp +| Description: Scrolls display up n lines. +| Global Variables: None. +| Arguments: lines - number of lines to scroll. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static void +scrollUp(unsigned8 lines) +{ + /* Number of blank display cells on bottom of window. */ + unsigned16 blankCount; + + /* Source and destination pointers for memory copy operations. */ + unsigned16 *ptrDst, *ptrSrc; + + if(lines0) + { + *ptrDst++ = BLANK; + } +} /* scrollUp */ + + +/*-------------------------------------------------------------------------+ +| Function: printCHAR +| Description: Print printable character to display. +| Global Variables: videoRamPtr, cursRow, cursCol. +| Arguments: c - character to write to display. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static void +printCHAR(char c) +{ + *videoRamPtr++ = (c<<8) | WHITE; + cursCol++; + if(cursCol==videoCols) + { + cursCol = 0; + cursRow++; + if(cursRow==videoRows) + { + cursRow--; + scrollUp(1); + videoRamPtr -= videoCols; + } + } +} /* printCHAR */ + +/*-------------------------------------------------------------------------+ +| Function: printBS +| Description: Print BS (BackSpace - '\b') character to display. +| Global Variables: videoRamPtr, cursRow, cursCol. +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static inline void +printBS(void) +{ + /* Move cursor back one cell. */ + if(cursCol>0) + { + cursCol--; + } + else if(cursRow>0) + { + cursRow--; + cursCol = videoCols - 1; + } + else + { + return; + } + + /* Write a whitespace. */ + *(--videoRamPtr) = BLANK; +} /* printBS */ + + +/*-------------------------------------------------------------------------+ +| Function: printHT +| Description: Print HT (Horizontal Tab - '\t') character to display. +| Global Variables: cursCol. +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static inline void +printHT(void) +{ + do + { + printCHAR(' '); + } + while (cursCol % TABSIZE); +} /* printHT */ + + +/*-------------------------------------------------------------------------+ +| Function: printLF +| Description: Print LF (Line Feed - '\n') character to display. +| Global Variables: cursRow. +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static inline void +printLF(void) +{ + cursRow++; + if(cursRow==videoRows) + { + cursRow--; + scrollUp(1); + } + updateVideoRamPtr(); +} /* printLF */ + + +/*-------------------------------------------------------------------------+ +| Function: printCR +| Description: Print CR (Carriage Return - '\r') to display. +| Global Variables: cursCol. +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +static inline void +printCR(void) +{ + cursCol = 0; + updateVideoRamPtr(); +} /* printCR */ + +/* + * Console Device Driver Entry Points + */ +void +vga_write( + int minor, + char cChar) +{ + switch (cChar) + { + case '\b': + printBS(); + break; + case '\t': + printHT(); + break; + case '\n': + printLF(); + break; + case '\r': + printCR(); + break; + default: + printCHAR(cChar); + break; + } + + setHardwareCursorPos(videoRamPtr - videoRam); +} /* vga_write */ + +/* + * vga_write_support + * + * Console Termios output entry point. + * + */ +int vga_write_support( + int minor, + const char *buf, + int len +) +{ + int nwrite = 0; + + while(bScrollLock) + { + /* + * The Scroll lock on the keyboard is active + */ + /* + * Yield while we wait + */ + rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); + } + + /* + * Write each byte in the string to the display + */ + while (nwrite +#include +#include +#include + +#include "console.h" +#include "z85c30_p.h" + +/* + * Flow control is only supported when using interrupts + */ +console_flow z85c30_flow_RTSCTS = +{ + z85c30_negate_RTS, /* deviceStopRemoteTx */ + z85c30_assert_RTS /* deviceStartRemoteTx */ +}; + +console_flow z85c30_flow_DTRCTS = +{ + z85c30_negate_DTR, /* deviceStopRemoteTx */ + z85c30_assert_DTR /* deviceStartRemoteTx */ +}; + +/* + * Exported driver function table + */ +console_fns z85c30_fns = +{ + z85c30_probe, /* deviceProbe */ + z85c30_open, /* deviceFirstOpen */ + z85c30_flush, /* deviceLastClose */ + NULL, /* deviceRead */ + z85c30_write_support_int, /* deviceWrite */ + z85c30_initialize_interrupts, /* deviceInitialize */ + z85c30_write_polled, /* deviceWritePolled */ + FALSE, /* deviceOutputUsesInterrupts */ +}; + +console_fns z85c30_fns_polled = +{ + z85c30_probe, /* deviceProbe */ + z85c30_open, /* deviceFirstOpen */ + z85c30_close, /* deviceLastClose */ + z85c30_inbyte_nonblocking_polled, /* deviceRead */ + z85c30_write_support_polled, /* deviceWrite */ + z85c30_init, /* deviceInitialize */ + z85c30_write_polled, /* deviceWritePolled */ + FALSE, /* deviceOutputUsesInterrupts */ +}; + +/* + * Read_85c30_register + * + * Read a Z85c30 register + */ +static unsigned8 Read_85c30_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum +) +{ + unsigned8 ucData; + + outport_byte(ulCtrlPort, ucRegNum); + + inport_byte(ulCtrlPort, ucData); + + return ucData; +} + +/* + * Write_85c30_register + * + * Write a Z85c30 register + */ +static void Write_85c30_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum, + unsigned8 ucData +) +{ + if(ucRegNum!=SCC_WR0_SEL_WR0) + { + outport_byte(ulCtrlPort, ucRegNum); + } + outport_byte(ulCtrlPort, ucData); +} + +/* + * Read_85c30_data + * + * Read a Z85c30 data register + */ +static unsigned8 Read_85c30_data( + unsigned32 ulDataPort +) +{ + unsigned8 ucData; + + inport_byte(ulDataPort, ucData); + + return ucData; +} + +/* + * Write_85c30_data + * + * Write a Z85c30 data register + */ +static void Write_85c30_data( + unsigned32 ulDataPort, + unsigned8 ucData +) +{ + outport_byte(ulDataPort, ucData); +} + +/* + * z85c30_initialize_port + * + * initialize a z85c30 Port + */ +static void z85c30_initialize_port( + int minor +) +{ + unsigned32 ulCtrlPort; + unsigned32 ulBaudDivisor; + + ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Using register 4 + * Set up the clock rate is 16 times the data + * rate, 8 bit sync char, 1 stop bit, no parity + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR4, + SCC_WR4_1_STOP | + SCC_WR4_16_CLOCK); + + /* + * Set up for 8 bits/character on receive with + * receiver disable via register 3 + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR3, + SCC_WR3_RX_8_BITS); + + /* + * Set up for 8 bits/character on transmit + * with transmitter disable via register 5 + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR5, + SCC_WR5_TX_8_BITS); + + /* + * Clear misc control bits + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR10, + 0x00); + + /* + * Setup the source of the receive and xmit + * clock as BRG output and the transmit clock + * as the output source for TRxC pin via register 11 + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR11, + SCC_WR11_OUT_BR_GEN | + SCC_WR11_TRXC_OI | + SCC_WR11_TX_BR_GEN | + SCC_WR11_RX_BR_GEN); + + ulBaudDivisor=Z85C30_Baud( + (unsigned32)Console_Port_Tbl[minor].pDeviceParams); + /* + * Setup the lower 8 bits time constants=1E. + * If the time constans=1E, then the desire + * baud rate will be equilvalent to 9600, via register 12. + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR12, + ulBaudDivisor&0xff); + + /* + * using register 13 + * Setup the upper 8 bits time constant + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR13, + (ulBaudDivisor>>8)&0xff); + + /* + * Enable the baud rate generator enable with clock from the + * SCC's PCLK input via register 14. + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR14, + SCC_WR14_BR_EN | + SCC_WR14_BR_SRC | + SCC_WR14_NULL); + + /* + * We are only interested in CTS state changes + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR15, + SCC_WR15_CTS_IE); + + /* + * Reset errors + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_INT); + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_ERR_RST); + + /* + * Enable the receiver via register 3 + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR3, + SCC_WR3_RX_8_BITS | + SCC_WR3_RX_EN); + + /* + * Enable the transmitter pins set via register 5. + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR5, + SCC_WR5_TX_8_BITS | + SCC_WR5_TX_EN); + + /* + * Disable interrupts + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR1, + 0); + + /* + * Reset TX CRC + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_TX_CRC); + + /* + * Reset interrupts + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_INT); +} + +static int z85c30_open( + int major, + int minor, + void * arg +) +{ + /* + * Assert DTR + */ + if(Console_Port_Tbl[minor].pDeviceFlow + !=&z85c30_flow_DTRCTS) + { + z85c30_assert_DTR(minor); + } + + return(RTEMS_SUCCESSFUL); +} + +static int z85c30_close( + int major, + int minor, + void * arg +) +{ + /* + * Negate DTR + */ + if(Console_Port_Tbl[minor].pDeviceFlow + !=&z85c30_flow_DTRCTS) + { + z85c30_negate_DTR(minor); + } + + return(RTEMS_SUCCESSFUL); +} + +/* + * z85c30_write_polled + * + * This routine transmits a character using polling. + */ +static void z85c30_write_polled( + int minor, + char cChar +) +{ + volatile unsigned8 z85c30_status; + unsigned32 ulCtrlPort; + + ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Wait for the Transmit buffer to indicate that it is empty. + */ + z85c30_status=Read_85c30_register(ulCtrlPort, + SCC_WR0_SEL_RD0); + while(!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) + { + /* + * Yield while we wait + */ + if(_System_state_Is_up(_System_state_Get())) + { + rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); + } + z85c30_status=Read_85c30_register(ulCtrlPort, + SCC_WR0_SEL_RD0); + } + + /* + * Write the character. + */ + Write_85c30_data(Console_Port_Tbl[minor].ulDataPort, cChar); +} + +/* + * Console Device Driver Entry Points + */ +static boolean z85c30_probe(int minor) +{ + /* + * If the configuration dependant probe has located the device then + * assume it is there + */ + return(TRUE); +} + +static void z85c30_init(int minor) +{ + unsigned32 ulCtrlPort; + unsigned8 dummy; + z85c30_context *pz85c30Context; + + pz85c30Context=(z85c30_context *)malloc(sizeof(z85c30_context)); + + Console_Port_Data[minor].pDeviceContext=(void *)pz85c30Context; + pz85c30Context->ucModemCtrl=SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN; + + ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1; + if(ulCtrlPort==Console_Port_Tbl[minor].ulCtrlPort2) + { + /* + * This is channel A + */ + /* + * Ensure port state machine is reset + */ + inport_byte(ulCtrlPort, dummy); + + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR9, + SCC_WR9_CH_A_RST); + } + else + { + /* + * This is channel B + */ + /* + * Ensure port state machine is reset + */ + inport_byte(ulCtrlPort, dummy); + + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR9, + SCC_WR9_CH_B_RST); + } + + z85c30_initialize_port(minor); +} + +/* + * These routines provide control of the RTS and DTR lines + */ +/* + * z85c30_assert_RTS + */ +static void z85c30_assert_RTS(int minor) +{ + unsigned32 Irql; + z85c30_context *pz85c30Context; + + pz85c30Context=(z85c30_context *) + Console_Port_Data[minor].pDeviceContext; + + /* + * Assert RTS + */ + rtems_interrupt_disable(Irql); + pz85c30Context->ucModemCtrl|=SCC_WR5_RTS; + Write_85c30_register( + Console_Port_Tbl[minor].ulCtrlPort1, + SCC_WR0_SEL_WR5, + pz85c30Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * z85c30_negate_RTS + */ +static void z85c30_negate_RTS(int minor) +{ + unsigned32 Irql; + z85c30_context *pz85c30Context; + + pz85c30Context=(z85c30_context *) + Console_Port_Data[minor].pDeviceContext; + + /* + * Negate RTS + */ + rtems_interrupt_disable(Irql); + pz85c30Context->ucModemCtrl&=~SCC_WR5_RTS; + Write_85c30_register( + Console_Port_Tbl[minor].ulCtrlPort1, + SCC_WR0_SEL_WR5, + pz85c30Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * These flow control routines utilise a connection from the local DTR + * line to the remote CTS line + */ +/* + * z85c30_assert_DTR + */ +static void z85c30_assert_DTR(int minor) +{ + unsigned32 Irql; + z85c30_context *pz85c30Context; + + pz85c30Context=(z85c30_context *) + Console_Port_Data[minor].pDeviceContext; + + /* + * Assert DTR + */ + rtems_interrupt_disable(Irql); + pz85c30Context->ucModemCtrl|=SCC_WR5_DTR; + Write_85c30_register( + Console_Port_Tbl[minor].ulCtrlPort1, + SCC_WR0_SEL_WR5, + pz85c30Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * z85c30_negate_DTR + */ +static void z85c30_negate_DTR(int minor) +{ + unsigned32 Irql; + z85c30_context *pz85c30Context; + + pz85c30Context=(z85c30_context *) + Console_Port_Data[minor].pDeviceContext; + + /* + * Negate DTR + */ + rtems_interrupt_disable(Irql); + pz85c30Context->ucModemCtrl&=~SCC_WR5_DTR; + Write_85c30_register( + Console_Port_Tbl[minor].ulCtrlPort1, + SCC_WR0_SEL_WR5, + pz85c30Context->ucModemCtrl); + rtems_interrupt_enable(Irql); +} + +/* + * z85c30_isr + * + * This routine is the console interrupt handler for COM3 and COM4 + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ + +static void z85c30_process( + int minor, + unsigned8 ucIntPend +) +{ + unsigned32 ulCtrlPort, ulDataPort; + volatile unsigned8 z85c30_status; + char cChar; + + ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1; + ulDataPort=Console_Port_Tbl[minor].ulDataPort; + + /* + * Deal with any received characters + */ + while(ucIntPend&SCC_RR3_B_RX_IP) + { + z85c30_status=Read_85c30_register(ulCtrlPort, SCC_WR0_SEL_RD0); + if(!Z85C30_Status_Is_RX_character_available(z85c30_status)) + { + break; + } + + /* + * Return the character read. + */ + cChar=Read_85c30_data(ulDataPort); + + rtems_termios_enqueue_raw_characters( + Console_Port_Data[minor].termios_data, + &cChar, + 1); + } + + while(TRUE) + { + z85c30_status=Read_85c30_register(ulCtrlPort, SCC_WR0_SEL_RD0); + if(!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) + { + /* + * We'll get another interrupt when + * the transmitter holding reg. becomes + * free again and we are clear to send + */ + break; + } + + if(!Z85C30_Status_Is_CTS_asserted(z85c30_status)) + { + /* + * We can't transmit yet + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_TX_INT); + /* + * The next state change of CTS will wake us up + */ + break; + } + + if(Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) + { + Console_Port_Data[minor].bActive=FALSE; + if(Console_Port_Tbl[minor].pDeviceFlow + !=&z85c30_flow_RTSCTS) + { + z85c30_negate_RTS(minor); + } + /* + * There is no data to transmit + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_TX_INT); + break; + } + + Ring_buffer_Remove_character( + &Console_Port_Data[minor].TxBuffer, + cChar); + /* + * transmit character + */ + Write_85c30_data(ulDataPort, cChar); + + /* + * Interrupt once FIFO has room + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_TX_INT); + break; + } + + if(ucIntPend&SCC_RR3_B_EXT_IP) + { + /* + * Clear the external status interrupt + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_INT); + z85c30_status=Read_85c30_register(ulCtrlPort, SCC_WR0_SEL_RD0); + } + + /* + * Reset interrupts + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_HI_IUS); +} + +static rtems_isr z85c30_isr( + rtems_vector_number vector +) +{ + int minor; + unsigned32 ulCtrlPort; + volatile unsigned8 ucIntPend; + volatile unsigned8 ucIntPendPort; + + for(minor=0;minor>3; + ucIntPendPort=ucIntPendPort&=7; + } + else + { + ucIntPendPort=ucIntPend&=7; + } + + if(ucIntPendPort) + { + z85c30_process(minor, ucIntPendPort); + } + } while(ucIntPendPort); + } + } +} + +/* + * z85c30_flush + */ +static int z85c30_flush(int major, int minor, void *arg) +{ + while(!Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) + { + /* + * Yield while we wait + */ + if(_System_state_Is_up(_System_state_Get())) + { + rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); + } + } + + z85c30_close(major, minor, arg); + + return(RTEMS_SUCCESSFUL); +} + +/* + * z85c30_initialize_interrupts + * + * This routine initializes the console's receive and transmit + * ring buffers and loads the appropriate vectors to handle the interrupts. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: NONE + */ + +static void z85c30_enable_interrupts( + int minor +) +{ + unsigned32 ulCtrlPort; + + ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1; + + /* + * Enable interrupts + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR1, + SCC_WR1_EXT_INT_EN | + SCC_WR1_TX_INT_EN | + SCC_WR1_INT_ALL_RX); + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR2, + 0); + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR9, + SCC_WR9_MIE); + + /* + * Reset interrupts + */ + Write_85c30_register(ulCtrlPort, + SCC_WR0_SEL_WR0, + SCC_WR0_RST_INT); +} + +static void z85c30_initialize_interrupts( + int minor +) +{ + z85c30_init(minor); + + Ring_buffer_Initialize(&Console_Port_Data[minor].TxBuffer); + + Console_Port_Data[minor].bActive=FALSE; + if(Console_Port_Tbl[minor].pDeviceFlow + !=&z85c30_flow_RTSCTS) + { + z85c30_negate_RTS(minor); + } + + if(Console_Port_Tbl[minor].ulCtrlPort1== + Console_Port_Tbl[minor].ulCtrlPort2) + { + /* + * Only do this for Channel A + */ + set_vector(z85c30_isr, + Console_Port_Tbl[minor].ulIntVector, + 1); + } + + z85c30_enable_interrupts(minor); +} + +/* + * z85c30_write_support_int + * + * Console Termios output entry point. + * + */ +static int z85c30_write_support_int( + int minor, + const char *buf, + int len) +{ + int i; + unsigned32 Irql; + + for(i=0; i +#include + +/* + * Read_85c30_register + * + * Read a Z85c30 register + */ + +unsigned8 Read_85c30_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum +) +{ + unsigned8 ucData; + + outport_byte(ulCtrlPort, ucRegNum); + inport_byte(ulCtrlPort, ucData); + return ucData; +} + +/* + * Write_85c30_register + * + * Write a Z85c30 register + */ + +void Write_85c30_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum, + unsigned8 ucData +) +{ + if(ucRegNum) { + outport_byte(ulCtrlPort, ucRegNum); + } + outport_byte(ulCtrlPort, ucData); +} + +/* + * Read_85c30_data + * + * Read a Z85c30 data register + */ + +unsigned8 Read_85c30_data( + unsigned32 ulDataPort +) +{ + unsigned8 ucData; + + inport_byte(ulDataPort, ucData); + return ucData; +} + +/* + * Write_85c30_data + * + * Write a Z85c30 data register + */ + +void Write_85c30_data( + unsigned32 ulDataPort, + unsigned8 ucData +) +{ + outport_byte(ulDataPort, ucData); +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h new file mode 100644 index 0000000000..3dfb96e048 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h @@ -0,0 +1,64 @@ +/* z85c30cfg.h + * + * This include file contains all console driver definations for the z85c30 + * + * 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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef __Z85C30_CONFIG_H +#define __Z85C30_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Board specific register access routines + */ + +unsigned8 Read_85c30_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum +); + +void Write_85c30_register( + unsigned32 ulCtrlPort, + unsigned8 ucRegNum, + unsigned8 ucData +); + +unsigned8 Read_85c30_data( + unsigned32 ulDataPort +); + +void Write_85c30_data( + unsigned32 ulDataPort, + unsigned8 ucData +); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/include/Makefile.in new file mode 100644 index 0000000000..011a5629e2 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/Makefile.in @@ -0,0 +1,36 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h $(srcdir)/chain.h \ + $(srcdir)/tod.h $(srcdir)/nvram.h $(srcdir)/pci.h + +# +# Equate files are for including from assembly preprocessed by +# gm4 or gasp. No examples are provided except for those for +# other CPUs. The best way to generate them would be to +# provide a program which generates the constants used based +# on the C equivalents. +# +# If you add equate files, don't forget to uncomment the install line +# below. +# + +EQ_FILES = + +SRCS=$(H_FILES) $(EQ_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: $(SRCS) + $(INSTALL) -m 444 $(H_FILES) $(PROJECT_INCLUDE) diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/bsp.h b/c/src/lib/libbsp/powerpc/ppcn_60x/include/bsp.h new file mode 100644 index 0000000000..98fc0781bf --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/bsp.h @@ -0,0 +1,465 @@ +/* bsp.h + * + * This include file contains all board IO definitions. + * + * 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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http:www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef __BSP_h +#define __BSP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define processor identification. */ + +#define MPC601 1 +#define MPC603 3 +#define MPC604 4 +#define MPC603e 6 +#define MPC603ev 7 +#define MPC604e 9 + +#ifdef ASM +/* Definition of where to store registers in alignment handler */ +#define ALIGN_REGS 0x0140 + +/* BAT register definitions for the MPC603 and MPC604. */ +/* Define bit fields for upper MPC603/4 BAT registers. */ + +#define BEPI_FIELD_60X 0xFFFE0000 +#define VALID_SUPERVISOR 0x2 +#define VALID_PROBLEM 0x1 +#define KEY_USER_60X 0x1 +#define BL_128K 0x0 +#define BL_256K (0x1<2) +#define BL_512K (0x3<2) +#define BL_1M (0x7<2) +#define BL_2M (0xF<2) +#define BL_4M (0x1F<2) +#define BL_8M (0x3F<2) +#define BL_16M (0x7F<2) +#define BL_32M (0xFF<2) +#define BL_64M (0x1FF<2) +#define BL_128M (0x3FF<2) +#define BL_256M (0x7FF<2) + + +/* Define bit fields for lower MPC603/4 BAT registers. */ + +#define BRPN_FIELD_60X 0xFFFE0000 + +/* Common defines for BAT registers. */ +/* Depending on the processor, the following may be in the upper */ +/* and lower BAT register. */ + +#define WRITE_THRU 0x40 +#define WRITE_BK 0x0 +#define COHERE_EN 0x10 +#define COHERE_DIS 0x0 +#define CACHE_DIS 0x20 +#define CACHE_EN 0x0 +#define GUARDED_EN 0x8 +#define GUARDED_DIS 0x0 +#define PP_00 0x0 +#define PP_01 0x1 +#define PP_10 0x2 +#define PP_11 0x3 + +/* HID0 definitions for MPC603 and MPC604 */ +#define HID0 0x3f0 /* HID0 Special Purpose Register # */ +/* HID1 definitions for MPC603e and MPC604e */ +#define HID1 0x3f1 /* HID1 Special Purpose Register # */ + +#define H0_603_ICFI 0x0800 /* HID0 I-Cache Flash Invalidate */ +#define H0_603_DCI 0x0400 /* HID0 D-Cache Flash Invalidate */ + +#define H0_60X_ICE 0x8000 /* HID0 I-Cache Enable */ +#define H0_60X_DCE 0x4000 /* HID0 D-Cache Enable */ + +#define H0_604_BHTE 0x0004 /* HID0 Branch History Table enable */ +#define H0_604_SIED 0x0080 /* HID0 Serial Instruction Execution */ +#define H0_604_ICIA 0x0800 /* HID0 I-Cache Invalidate All */ +#define H0_604_DCIA 0x0400 /* HID0 D-Cache Invalidate All */ + +#define BAT0U 528 +#define BAT0L 529 +#define BAT1U 530 +#define BAT1L 531 +#define BAT2U 532 +#define BAT2L 533 +#define BAT3U 534 +#define BAT3L 535 +#define SPRG0 272 +#define SPRG1 273 + +/* MSR bit settings */ +#define MSR_LE 0x0001 +#define MSR_RI 0x0002 +#define MSR_DR 0x0010 +#define MSR_IR 0x0020 +#define MSR_IP 0x0040 +#define MSR_FE1 0x0100 +#define MSR_BE 0x0200 +#define MSR_SE 0x0400 +#define MSR_FE0 0x0800 +#define MSR_ME 0x1000 +#define MSR_FP 0x2000 +#define MSR_PR 0x4000 +#define MSR_EE 0x8000 +#define MSR_ILE 0x0001 /* Upper 16 bits */ +#define MSR_POW 0x0004 /* Upper 16 bits */ +#else +#include +#include +#include +#include +#include +#include + +/* + * PPCn_60x Interupt Definations. + */ +#define PPCN_60X_8259_IRQ_BASE ( PPC_IRQ_LAST + 1 ) + +/* + * 8259 IRQ definations. + */ +#define PPCN_60X_IRQ_SYS_TIMER (PPCN_60X_8259_IRQ_BASE + 0) +#define PPCN_60X_IRQ_KBD (PPCN_60X_8259_IRQ_BASE + 1) +#define PPCN_60X_IRQ_COM2 (PPCN_60X_8259_IRQ_BASE + 3) +#define PPCN_60X_IRQ_COM1 (PPCN_60X_8259_IRQ_BASE + 4) +#define PPCN_60X_IRQ_CIO (PPCN_60X_8259_IRQ_BASE + 5) +#define PPCN_60X_IRQ_FDC (PPCN_60X_8259_IRQ_BASE + 6) +#define PPCN_60X_IRQ_LPT (PPCN_60X_8259_IRQ_BASE + 7) +#define PPCN_60X_IRQ_RTC (PPCN_60X_8259_IRQ_BASE + 8) +#define PPCN_60X_IRQ_COM3_4 (PPCN_60X_8259_IRQ_BASE + 10) +#define PPCN_60X_IRQ_MSE (PPCN_60X_8259_IRQ_BASE + 12) +#define PPCN_60X_IRQ_SCSI (PPCN_60X_8259_IRQ_BASE + 13) + +/* + * PCI interrupts as read from line register map directly to + * ISA interrupt lines 9, 11, 14 and 15. + */ +#define PPCN_60X_IRQ_PCI(n) (PPCN_60X_8259_IRQ_BASE + (n)) + +#define MAX_BOARD_IRQS (PPCN_60X_8259_IRQ_BASE + 15) + +#define ISA8259_M_CTRL 0x20 +#define ISA8259_S_CTRL 0xa0 +#define ISA8259_M_MASK 0x21 +#define ISA8259_S_MASK 0xa1 +#define ISA8259_M_ELCR 0x4d0 +#define ISA8259_S_ELCR 0x4d1 + +#define ELCRS_INT15_LVL 0x80 +#define ELCRS_INT14_LVL 0x40 +#define ELCRS_INT12_LVL 0x10 +#define ELCRS_INT11_LVL 0x08 +#define ELCRS_INT10_LVL 0x04 +#define ELCRS_INT9_LVL 0x02 +#define ELCRS_INT8_LVL 0x01 +#define ELCRM_INT7_LVL 0x80 +#define ELCRM_INT5_LVL 0x20 + + +#define NONSPECIFIC_EOI 0x20 + +extern void En_Ext_Interrupt(int level); +extern void Dis_Ext_Interrupt(int level); + +#define IRQ_VECTOR_BASE 0xbffffff0 + +/* + * i8042 addresses + */ +#define I8042_DATA 0x60 +#define I8042_CS 0x64 + +/* + * ns16550 addresses + */ +#define NS16550_PORT_A 0x3f8 +#define NS16550_PORT_B 0x2f8 + +/* + * z85c30 addresses + */ +#define Z85C30_CTRL_B 0x840 +#define Z85C30_DATA_B 0x841 +#define Z85C30_CTRL_A 0x842 +#define Z85C30_DATA_A 0x843 + +/* + * Z85C30 Definations for the 422 interface. + */ +#define Z85C30_CLOCK 14745600 + +#define PCI_SYS_MEM_BASE 0x80000000 +#define PCI_MEM_BASE 0xc0000000 +#define PCI_IO_BASE 0x80000000 + +#define EIEIO asm volatile("eieio") + +/* + * As ports are all little endian we will perform swaps here on 16 and 32 + * bit transfers + */ +extern unsigned16 Swap16(unsigned16 usVal); +extern unsigned32 Swap32(unsigned32 ulVal); + +#define outport_byte(port, val) \ + EIEIO; \ + *(volatile unsigned8 *)(PCI_IO_BASE+ \ + (unsigned long)(port))=(val) + +#define outport_16(port, val) \ + EIEIO; \ + *(volatile unsigned16 *)(PCI_IO_BASE+ \ + (unsigned long)(port))=Swap16(val) + +#define outport_32(port, val) \ + EIEIO; \ + *(volatile unsigned32 *)(PCI_IO_BASE+ \ + (unsigned long)(port))=Swap32(val) + +#define inport_byte(port, val) \ + EIEIO; \ + (val)=*(volatile unsigned8 *)(PCI_IO_BASE+ \ + (unsigned long)(port)) + +#define inport_16(port, val) \ + EIEIO; \ + (val)=Swap16(*(volatile unsigned16 *)(PCI_IO_BASE+ \ + (unsigned long)(port))) + +#define inport_32(port, val) \ + EIEIO; \ + (val)=Swap32(*(volatile unsigned32 *)(PCI_IO_BASE+ \ + (unsigned long)(port))) + +/* + * System Planar Board Registers + */ +typedef volatile struct _PLANARREGISTERS{ + unsigned8 Reserved0[0x803]; /* Offset 0x000 */ + unsigned8 SimmId; /* Offset 0x803 */ + unsigned8 SimmPresent; /* Offset 0x804 */ + unsigned8 Reserved1[3]; + unsigned8 HardfileLight; /* Offset 0x808 */ + unsigned8 Reserved2[3]; + unsigned8 EquipmentPresent1; /* Offset 0x80C */ + unsigned8 Reserved3; + unsigned8 EquipmentPresent2; /* Offset 0x80e */ + unsigned8 Reserved4; + unsigned8 PasswordProtect1; /* Offset 0x810 */ + unsigned8 Reserved5; + unsigned8 PasswordProtect2; /* Offset 0x812 */ + unsigned8 Reserved6; + unsigned8 L2Flush; /* Offset 0x814 */ + unsigned8 Reserved7[3]; + unsigned8 Keylock; /* Offset 0x818 */ + unsigned8 Reserved8[0x3c]; + unsigned8 BoardRevision; /* Offset 0x854 */ + unsigned8 Reserved9[0xf]; + unsigned8 BoardID; /* Offset 0x864 */ + unsigned8 Reserved10; + unsigned8 MotherboardMemoryType; /* Offset 0x866 */ + unsigned8 Reserved11; + unsigned8 MezzanineMemoryType; /* Offset 0x868 */ +} PLANARREGISTERS, *PPLANARREGISTERS; + +extern unsigned char ucSystemType; +extern unsigned char ucBoardRevMaj; +extern unsigned char ucBoardRevMin; +extern unsigned long ulMemorySize; +extern unsigned long ulCpuBusClock; + +#define SYS_TYPE_PPC1 0 +#define SYS_TYPE_PPC2 1 +#define SYS_TYPE_PPC1a 2 +#define SYS_TYPE_PPC2a 3 +#define SYS_TYPE_PPC4 4 + +/* + * PCI initialisation + */ +void InitializePCI(void); + +/* + * VME initiaisation + */ +void InitializeUniverse(); + +/* + * RTC initialisation + */ +void InitializeRTC(void); + +/* + * NvRAM initialisation + */ +void InitializeNvRAM(void); + +/* + * BSP_TIMER_AVG_OVERHEAD and BSP_TIMER_LEAST_VALID for the shared timer + * driver. + */ + +#define BSP_TIMER_AVG_OVERHEAD 4 /* It typically takes xx clicks */ + /* to start/stop the timer. */ +#define BSP_TIMER_LEAST_VALID 1 /* Don't trust a value lower than this */ + +/* + * Convert decrement value to tenths of microsecnds (used by + * shared timer driver). + * + * + There are 4 bus cycles per click + * + We return value in 1/10 microsecond units. + * Modified following equation to integer equation to remove + * floating point math. + * (int) ((float)(_value) / ((66.67 * 0.1) / 4.0)) + */ + +#define BSP_Convert_decrementer( _value ) \ + (int) (((_value) * 4000) / (ulCpuBusClock/10000)) + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Stuff for Time Test 27 + */ + +#define MUST_WAIT_FOR_INTERRUPT 1 + +#define Install_tm27_vector( _handler ) \ + set_vector( (_handler), PPC_IRQ_DECREMENTER, 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) + + +/* Constants */ + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* + * How many libio files we want + */ + +#define BSP_LIBIO_MAX_FDS 20 + +/* functions */ + +void bsp_start( void ); + +void bsp_cleanup( void ); + +rtems_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +); + +/* + * spurious.c + */ +rtems_isr bsp_stub_handler( + rtems_vector_number trap +); +rtems_isr bsp_spurious_handler( + rtems_vector_number trap +); +void bsp_spurious_initialize(); + +/* + * genvec.c + */ +void set_EE_vector( + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector /* vector number */ +); +void initialize_external_exception_vector(); + +/* + * console.c + */ +void DEBUG_puts( char *string ); +void DEBUG_puth( unsigned32 ulHexNum ); + +void BSP_fatal_return( void ); + +extern rtems_configuration_table BSP_Configuration; /* owned by BSP */ + +extern rtems_cpu_table Cpu_table; /* owned by BSP */ + +extern unsigned32 bsp_isr_level; + +#endif /* ASM */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/chain.h b/c/src/lib/libbsp/powerpc/ppcn_60x/include/chain.h new file mode 100644 index 0000000000..98cf2b1a86 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/chain.h @@ -0,0 +1,362 @@ +/* chain.h + * + * This include file contains all the constants and structures associated + * with doubly linked chains. This file actually just provides an + * interface to the chain object in rtems. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $ld: + */ + +#ifndef __CHAIN_h +#define __CHAIN_h + +#include + +/* + * Chain_Initialize + * + * This routine initializes the_chain structure to manage the + * contiguous array of number_nodes nodes which starts at + * starting_address. Each node is of node_size bytes. + * + * Chain_Control *the_chain, * IN * + * void *starting_address, * IN * + * rtems_unsigned32 number_nodes, * IN * + * rtems_unsigned32 node_size * IN * + */ + +#define Chain_Initialize( the_chain, starting_address, \ + number_nodes, node_size ) \ + _Chain_Initialize( the_chain, starting_address, \ + number_nodes, node_size ) \ + + +/* + * Chain_Initialize_empty + * + * This routine initializes the specified chain to contain zero nodes. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Initialize_empty( the_chain ) \ + _Chain_Initialize_empty( the_chain ) + + +/* + * Chain_Are_nodes_equal + * + * This function returns TRUE if LEFT and RIGHT are equal, + * and FALSE otherwise. + * + * Chain_Node *left, * IN * + * Chain_Node *right * IN * + */ + +#define Chain_Are_nodes_equal( left, right ) \ + _Chain_Are_nodes_equal( left, right ) + + +/* + * Chain_Extract_unprotected + * + * This routine extracts the_node from the chain on which it resides. + * It does NOT disable interrupts to insure the atomicity of the + * extract operation. + * + * Chain_Node *the_node * IN * + */ + +#define Chain_Extract_unprotected( the_node ) \ + _Chain_Extract_unprotected( the_node ) + + +/* + * Chain_Extract + * + * This routine extracts the_node from the chain on which it resides. + * It disables interrupts to insure the atomicity of the + * extract operation. + * + * Chain_Node *the_node * IN * + */ + +#define Chain_Extract( the_node ) \ + _Chain_Extract( the_node ) + + +/* + * Chain_Get_unprotected + * + * This function removes the first node from the_chain and returns + * a pointer to that node. If the_chain is empty, then NULL is returned. + * It does NOT disable interrupts to insure the atomicity of the + * get operation. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Get_unprotected( the_chain ) \ + _Chain_Get_unprotected( the_chain ) + + +/* + * Chain_Get + * + * This function removes the first node from the_chain and returns + * a pointer to that node. If the_chain is empty, then NULL is returned. + * It disables interrupts to insure the atomicity of the + * get operation. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Get( the_chain ) \ + _Chain_Get( the_chain ) + + +/* + * Chain_Get_first_unprotected + * + * This function removes the first node from the_chain and returns + * a pointer to that node. It does NOT disable interrupts to insure + * the atomicity of the get operation. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Get_first_unprotected( the_chain ) \ + _Chain_Get_first_unprotected( the_chain ) + + +/* + * Chain_Insert_unprotected + * + * This routine inserts the_node on a chain immediately following + * after_node. It does NOT disable interrupts to insure the atomicity + * of the extract operation. + * + * Chain_Node *after_node, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Insert_unprotected( after_node, the_node ) \ + _Chain_Insert_unprotected( after_node, the_node ) + + +/* + * Chain_Insert + * + * This routine inserts the_node on a chain immediately following + * after_node. It disables interrupts to insure the atomicity + * of the extract operation. + * + * Chain_Node *after_node, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Insert( after_node, the_node ) \ + _Chain_Insert( after_node, the_node ) + + +/* + * Chain_Append_unprotected + * + * This routine appends the_node onto the end of the_chain. + * It does NOT disable interrupts to insure the atomicity of the + * append operation. + * + * Chain_Control *the_chain, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Append_unprotected( the_chain, the_node ) \ + _Chain_Append_unprotected( the_chain, the_node ) + + +/* + * Chain_Append + * + * This routine appends the_node onto the end of the_chain. + * It disables interrupts to insure the atomicity of the + * append operation. + * + * Chain_Control *the_chain, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Append( the_chain, the_node ) \ + _Chain_Append( the_chain, the_node ) + + +/* + * Chain_Prepend_unprotected + * + * This routine prepends the_node onto the front of the_chain. + * It does NOT disable interrupts to insure the atomicity of the + * prepend operation. + * + * Chain_Control *the_chain, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Prepend_unprotected( the_chain, the_node ) \ + _Chain_Prepend_unprotected( the_chain, the_node ) + + +/* + * Chain_Prepend + * + * This routine prepends the_node onto the front of the_chain. + * It disables interrupts to insure the atomicity of the + * prepend operation. + * + * Chain_Control *the_chain, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Prepend( the_chain, the_node ) \ + _Chain_Prepend( the_chain, the_node ) + + +/* + * Chain_Head + * + * This function returns a pointer to the first node on the chain. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Head( the_chain ) \ + _Chain_Head( the_chain ) + + +/* + * Chain_Tail + * + * This function returns a pointer to the last node on the chain. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Tail( the_chain ) \ + _Chain_Tail( the_chain ) + + +/* + * Chain_Is_head + * + * This function returns TRUE if the_node is the head of the_chain and + * FALSE otherwise. + * + * Chain_Control *the_chain, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Is_head( the_chain, the_node ) \ + _Chain_Is_head( the_chain, the_node ) + + +/* + * Chain_Is_tail + * + * This function returns TRUE if the_node is the tail of the_chain and + * FALSE otherwise. + * + * Chain_Control *the_chain, * IN * + * Chain_Node *the_node * IN * + */ + +#define Chain_Is_tail( the_chain, the_node ) \ + _Chain_Is_tail( the_chain, the_node ) + + +/* + * Chain_Is_first + * + * This function returns TRUE if the_node is the first node on a chain and + * FALSE otherwise. + * + * Chain_Node *the_node * IN * + */ + +#define Chain_Is_first( the_node ) \ + _Chain_Is_first( the_node ) + + +/* + * Chain_Is_last + * + * This function returns TRUE if the_node is the last node on a chain and + * FALSE otherwise. + * + * Chain_Node *the_node * IN * + */ + +#define Chain_Is_last( the_node ) \ + _Chain_Is_last( the_node ) + + +/* + * Chain_Is_empty + * + * This function returns TRUE if there are no nodes on the_chain and + * FALSE otherwise. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Is_empty( the_chain ) \ + _Chain_Is_empty( the_chain ) + + +/* + * Chain_Has_only_one_node + * + * This function returns TRUE if there is only one node on the_chain and + * FALSE otherwise. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Has_only_one_node( the_chain ) \ + _Chain_Has_only_one_node( the_chain ) + + +/* + * Chain_Is_null + * + * This function returns TRUE if the_chain is NULL and FALSE otherwise. + * + * Chain_Control *the_chain * IN * + */ + +#define Chain_Is_null( the_chain ) \ + _Chain_Is_null( the_chain ) + + +/* + * Chain_Is_null_node + * + * This function returns TRUE if the_node is NULL and FALSE otherwise. + * + * Chain_Node *the_node * IN * + */ + +#define Chain_Is_null_node( the_node ) \ + _Chain_Is_null_node( the_node ) + + +#undef __RTEMS_APPLICATION__ +#include +#define __RTEMS_APPLICATION__ +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/coverhd.h b/c/src/lib/libbsp/powerpc/ppcn_60x/include/coverhd.h new file mode 100644 index 0000000000..340c5ca16d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/coverhd.h @@ -0,0 +1,119 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C. These are used in the + * Timing Test Suite to ignore the overhead required to pass arguments + * to directives. On some CPUs and/or target boards, this overhead + * is significant and makes it difficult to distinguish internal + * RTEMS execution time from that used to call the directive. + * This file should be updated after running the C overhead timing + * test. Once this update has been performed, the RTEMS Time Test + * Suite should be rebuilt to account for these overhead times in the + * timing results. + * + * NOTE: If these are all zero, then the times reported include + * calling overhead including passing of arguments. + * + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 0 +#define CALLING_OVERHEAD_CLOCK_SET 0 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + + + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/extisrdrv.h b/c/src/lib/libbsp/powerpc/ppcn_60x/include/extisrdrv.h new file mode 100644 index 0000000000..32d0e7562c --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/extisrdrv.h @@ -0,0 +1,41 @@ +/* extisrdrv.h + * + * This file describes the external interrupt driver + * + */ + +#ifndef __EXT_ISR_DRIVER_H +#define __EXT_ISR_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* variables */ + +extern rtems_device_major_number rtems_externalISR_major; +extern rtems_device_minor_number rtems_externalISR_minor; + +/* default external ISR driver entry */ + +#define EXTISR_DRIVER_TABLE_ENTRY \ + { ExternalISR_initialize, NULL, NULL, NULL, NULL, ExternalISR_control } + +rtems_device_driver ExternalISR_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +rtems_device_driver ExternalISR_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/nvram.h b/c/src/lib/libbsp/powerpc/ppcn_60x/include/nvram.h new file mode 100644 index 0000000000..246c2679c5 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/nvram.h @@ -0,0 +1,60 @@ +/* + * This file contains the NvRAM driver definitions for the PPCn_60x + * + * 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. + * + */ + +#ifndef _NVRAM_H +#define _NVRAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This initializes the NvRAM driver + */ + +void InitializeNvRAM(void); + + +/* + * These routines access data in the NvRAM's OS area + */ +extern rtems_status_code ReadNvRAM8(unsigned32 ulOffset, unsigned8 *pucData); +extern rtems_status_code WriteNvRAM8(unsigned32 ulOffset, unsigned8 ucValue); +extern rtems_status_code ReadNvRAM16(unsigned32 ulOffset, unsigned16 *pusData); +extern rtems_status_code WriteNvRAM16(unsigned32 ulOffset, unsigned16 usValue); +extern rtems_status_code ReadNvRAM32(unsigned32 ulOffset, unsigned32 *pulData); +extern rtems_status_code WriteNvRAM32(unsigned32 ulOffset, unsigned32 ulValue); +rtems_status_code ReadNvRAMBlock( + unsigned32 ulOffset, unsigned8 *pucData, unsigned32 length); +rtems_status_code WriteNvRAMBlock( + unsigned32 ulOffset, unsigned8 *ucValue, unsigned32 length); +/* + * This routine returns the size of the NvRAM + */ +extern unsigned32 SizeNvRAM(); + +/* + * This routine commits changes to the NvRAM + */ +extern void CommitNvRAM(); + +#ifdef __cplusplus +} +#endif + +#endif /* _NVRAM_H */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/pci.h b/c/src/lib/libbsp/powerpc/ppcn_60x/include/pci.h new file mode 100644 index 0000000000..f012d882d7 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/pci.h @@ -0,0 +1,322 @@ +/* + * 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. + * + */ +#ifndef _PCI_H_ +#define _PCI_H_ + +/* + * PCI Configuration space definitions + */ + +#define PCI_CONFIG_ADDR 0xcf8 +#define PCI_CONFIG_DATA 0xcfc + +#define PCI_MAX_DEVICES 16 +#define PCI_MAX_FUNCTIONS 8 + +#define PCI_CONFIG_VENDOR_LOW 0x00 +#define PCI_CONFIG_VENDOR_HIGH 0x01 +#define PCI_CONFIG_DEVICE_LOW 0x02 +#define PCI_CONFIG_DEVICE_HIGH 0x03 +#define PCI_CONFIG_COMMAND 0x04 +#define PCI_CONFIG_STATUS 0x06 +#define PCI_CONFIG_REVISIONID 0x08 +#define PCI_CONFIG_CLASS_CODE_L 0x09 +#define PCI_CONFIG_CLASS_CODE_M 0x0a +#define PCI_CONFIG_CLASS_CODE_U 0x0b +#define PCI_CONFIG_CACHE_LINE_SIZE 0x0c +#define PCI_CONFIG_LATENCY_TIMER 0x0d +#define PCI_CONFIG_HEADER_TYPE 0x0e +#define PCI_CONFIG_BIST 0x0f +#define PCI_CONFIG_BAR_0 0x10 +#define PCI_CONFIG_BAR_1 0x14 +#define PCI_CONFIG_BAR_2 0x18 +#define PCI_CONFIG_BAR_3 0x1c +#define PCI_CONFIG_BAR_4 0x20 +#define PCI_CONFIG_BAR_5 0x24 +#define PCI_CONFIG_SUBVENDOR_LOW 0x2c +#define PCI_CONFIG_SUBVENDOR_HIGH 0x2d +#define PCI_CONFIG_SUBDEVICE_LOW 0x2e +#define PCI_CONFIG_SUBDEVICE_HIGH 0x2f +#define PCI_CONFIG_ROM_BAR 0x30 +#define PCI_CONFIG_INTERRUPTLINE 0x3c +#define PCI_CONFIG_INTERRUPTPIN 0x3d +#define PCI_CONFIG_MIN_GNT 0x3e +#define PCI_CONFIG_MAX_LAT 0x3f + +/* + * PCI Status register definitions + */ + +#define PCI_STATUS_66MHZ_CAPABLE 0x0020 +#define PCI_STATUS_UDF_SUPPORTED 0x0040 +#define PCI_STATUS_FAST_BACK_TO_BACK 0x0080 +#define PCI_STATUS_DET_DPAR_ERR 0x0100 +#define PCI_STATUS_DEVSEL_MSK 0x0600 +#define PCI_STATUS_DEVSEL_SLOW 0x0400 +#define PCI_STATUS_DEVSEL_MED 0x0200 +#define PCI_STATUS_DEVSEL_FAST 0x0000 +#define PCI_STATUS_SIG_TARG_ABT 0x0800 +#define PCI_STATUS_REC_TARG_ABT 0x1000 +#define PCI_STATUS_REC_MAST_ABT 0x2000 +#define PCI_STATUS_SIG_SYS_ERR 0x4000 +#define PCI_STATUS_DET_PAR_ERR 0x8000 + +/* + * PCI Enable register definitions + */ + +#define PCI_ENABLE_IO_SPACE 0x0001 +#define PCI_ENABLE_MEMORY_SPACE 0x0002 +#define PCI_ENABLE_BUS_MASTER 0x0004 +#define PCI_ENABLE_SPECIAL_CYCLES 0x0008 +#define PCI_ENABLE_WRITE_AND_INVALIDATE 0x0010 +#define PCI_ENABLE_VGA_COMPATIBLE_PALETTE 0x0020 +#define PCI_ENABLE_PARITY 0x0040 +#define PCI_ENABLE_WAIT_CYCLE 0x0080 +#define PCI_ENABLE_SERR 0x0100 +#define PCI_ENABLE_FAST_BACK_TO_BACK 0x0200 + +/* + * Bit encode for PCI_CONFIG_HEADER_TYPE register + */ + +#define PCI_MULTI_FUNCTION 0x80 + +/* + * Bit encodes for PCI Config BaseAddressesRegisters (BARs) + */ + +#define PCI_ADDRESS_IO_SPACE 0x00000001 +#define PCI_ADDRESS_MEMORY_TYPE_MASK 0x00000007 +#define PCI_ADDRESS_MEMORY_PREFETCHABLE 0x00000008 + +#define PCI_TYPE_32BIT 0 +#define PCI_TYPE_20BIT 2 +#define PCI_TYPE_64BIT 4 + +/* + * Bit encodes for PCI Config ROMBaseAddresses + */ + +#define PCI_ROMADDRESS_ENABLED 0x00000001 + +/* + * PCI Bridge Configuration space definitions + */ + +#define PCI_BRIDGE_PRIMARY_BUS 0x18 +#define PCI_BRIDGE_SECONDARY_BUS 0x19 +#define PCI_BRIDGE_SUBORDINATE_BUS 0x1a +#define PCI_BRIDGE_SECONDARY_LAT 0x1b +#define PCI_BRIDGE_IO_BASE 0x1c +#define PCI_BRIDGE_IO_LIMIT 0x1d +#define PCI_BRIDGE_SECONDARY_STATUS 0x1e +#define PCI_BRIDGE_MEMORY_BASE 0x20 +#define PCI_BRIDGE_MEMORY_LIMIT 0x22 +#define PCI_BRIDGE_PRE_MEMORY_BASE 0x24 +#define PCI_BRIDGE_PRE_MEMORY_LIMIT 0x26 +#define PCI_BRIDGE_PRE_BASE_U 0x28 +#define PCI_BRIDGE_PRE_LIMIT_U 0x2c +#define PCI_BRIDGE_IO_BASE_U 0x30 +#define PCI_BRIDGE_IO_LIMIT_U 0x32 +#define PCI_BRIDGE_ROM_BAR 0x38 +#define PCI_BRIDGE_CONTROL 0x3e + +/* + * PCI Bridge Control register definitions + */ + +#define PCI_BRIDGE_PAR_ERR_RESPONSE 0x01 +#define PCI_BRIDGE_S_SERR_L_FWD_EN 0x02 +#define PCI_BRIDGE_ENABLE_ISA 0x04 +#define PCI_BRIDGE_ENABLE_VGA 0x08 +#define PCI_BRIDGE_MASTER_ABORT 0x20 +#define PCI_BRIDGE_SECONDARY_RESET 0x40 +#define PCI_BRIDGE_BACK_TO_BACK_EN 0x80 + +/* + * PCI IO address forwarding capability + */ +#define PCI_BRIDGE_IO_CAPABILITY 0x0f +#define PCI_BRIDGE_IO_16BIT 0x00 +#define PCI_BRIDGE_IO_32BIT 0x01 + +/* + * Class codes + */ +#define PCI_BASE_CLASS_NULL 0x00 +#define PCI_BASE_CLASS_STORAGE 0x01 +#define PCI_BASE_CLASS_NETWORK 0x02 +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_BASE_CLASS_MULTIMEDIA 0x04 +#define PCI_BASE_CLASS_MEMORY 0x05 +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_BASE_CLASS_COM_CTRL 0x07 +#define PCI_BASE_CLASS_BASEPERIPH 0x08 +#define PCI_BASE_CLASS_INPUTDEV 0x09 +#define PCI_BASE_CLASS_DOCKING 0x0a +#define PCI_BASE_CLASS_PROC 0x0b +#define PCI_BASE_CLASS_SERBUSCTRL 0x0c +#define PCI_BASE_CLASS_UNDEFINED 0xff + +#define PCI_SUB_CLASS_NULL_NVGA 0x00 +#define PCI_IF_CLASS_DISPLAY_VGA 0x00 +#define PCI_IF_CLASS_DISPLAY_VGA8514 0x01 +#define PCI_SUB_CLASS_NULL_VGA 0x01 + +#define PCI_SUB_CLASS_STORAGE_SCSI 0x00 +#define PCI_SUB_CLASS_STORAGE_IDE 0x01 +#define PCI_SUB_CLASS_STORAGE_FLOPPY 0x02 +#define PCI_SUB_CLASS_STORAGE_IPI 0x03 +#define PCI_SUB_CLASS_STORAGE_RAID 0x04 +#define PCI_SUB_CLASS_STORAGE_OTHER 0x80 + +#define PCI_SUB_CLASS_NETWORK_ETH 0x00 +#define PCI_SUB_CLASS_NETWORK_TOKEN 0x01 +#define PCI_SUB_CLASS_NETWORK_FDDI 0x02 +#define PCI_SUB_CLASS_NETWORK_ATM 0x03 +#define PCI_SUB_CLASS_NETWORK_OTHER 0x80 + +#define PCI_SUB_CLASS_DISPLAY_VGA 0x00 +#define PCI_SUB_CLASS_DISPLAY_XGA 0x01 +#define PCI_SUB_CLASS_DISPLAY_OTHER 0x80 + +#define PCI_SUB_CLASS_MULTIMEDIA_VIDEO 0x00 +#define PCI_SUB_CLASS_MULTIMEDIA_AUDIO 0x01 +#define PCI_SUB_CLASS_MULTIMEDIA_OTHER 0x80 + +#define PCI_SUB_CLASS_MEMORY_RAM 0x00 +#define PCI_SUB_CLASS_MEMORY_FLASH 0x01 +#define PCI_SUB_CLASS_MEMORY_OTHER 0x80 + +#define PCI_SUB_CLASS_BRIDGE_HOST 0x00 +#define PCI_SUB_CLASS_BRIDGE_ISA 0x01 +#define PCI_SUB_CLASS_BRIDGE_EISA 0x02 +#define PCI_SUB_CLASS_BRIDGE_MC 0x03 +#define PCI_SUB_CLASS_BRIDGE_PCI 0x04 +#define PCI_SUB_CLASS_BRIDGE_PCMCIA 0x05 +#define PCI_SUB_CLASS_BRIDGE_NUBUS 0x06 +#define PCI_SUB_CLASS_BRIDGE_CARDBUS 0x07 +#define PCI_SUB_CLASS_BRIDGE_OTHER 0x80 + +#define PCI_SUB_CLASS_COM_CTRL_SERIAL 0x00 +#define PCI_IF_CLASS_COM_SER_XT 0x00 +#define PCI_IF_CLASS_COM_SER_16450 0x01 +#define PCI_IF_CLASS_COM_SER_16550 0x02 +#define PCI_SUB_CLASS_COM_CTRL_PARALLEL 0x01 +#define PCI_IF_CLASS_COM_PAR 0x00 +#define PCI_IF_CLASS_COM_PAR_BI 0x01 +#define PCI_IF_CLASS_COM_PAR_ECP 0x02 +#define PCI_SUB_CLASS_COM_CTRL_OTHER 0x80 + +#define PCI_SUB_CLASS_BASEPERIPH_PIC 0x00 +#define PCI_IF_CLASS_BASEPERIPH_PIC 0x00 +#define PCI_IF_CLASS_BASEPERIPH_PIC_ISA 0x01 +#define PCI_IF_CLASS_BASEPERIPH_PIC_EISA 0x02 +#define PCI_SUB_CLASS_BASEPERIPH_DMA 0x01 +#define PCI_IF_CLASS_BASEPERIPH_DMA 0x00 +#define PCI_IF_CLASS_BASEPERIPH_DMA_ISA 0x01 +#define PCI_IF_CLASS_BASEPERIPH_DMA_EISA 0x02 +#define PCI_SUB_CLASS_BASEPERIPH_TIMER 0x02 +#define PCI_IF_CLASS_BASEPERIPH_TIMER 0x00 +#define PCI_IF_CLASS_BASEPERIPH_TIMER_ISA 0x01 +#define PCI_IF_CLASS_BASEPERIPH_TIMER_EISA 0x02 +#define PCI_SUB_CLASS_BASEPERIPH_RTC 0x03 +#define PCI_IF_CLASS_BASEPERIPH_RTC 0x00 +#define PCI_IF_CLASS_BASEPERIPH_RTC_ISA 0x01 +#define PCI_SUB_CLASS_BASEPERIPH_OTHER 0x80 + +#define PCI_SUB_CLASS_INPUTDEV_KEYBOARD 0x00 +#define PCI_SUB_CLASS_INPUTDEV_PEN 0x01 +#define PCI_SUB_CLASS_INPUTDEV_MOUSE 0x02 +#define PCI_SUB_CLASS_INPUTDEV_OTHER 0x80 + +#define PCI_SUB_CLASS_DOCKING_GENERIC 0x00 +#define PCI_SUB_CLASS_DOCKING_OTHER 0x80 + +#define PCI_SUB_CLASS_PROC_386 0x00 +#define PCI_SUB_CLASS_PROC_486 0x01 +#define PCI_SUB_CLASS_PROC_PENTIUM 0x02 +#define PCI_SUB_CLASS_PROC_ALPHA 0x10 +#define PCI_SUB_CLASS_PROC_POWERPC 0x20 +#define PCI_SUB_CLASS_PROC_COPROC 0x40 + +#define PCI_SUB_CLASS_SERBUSCTRL_FIREWIRE 0x00 +#define PCI_SUB_CLASS_SERBUSCTRL_ACCESS 0x01 +#define PCI_SUB_CLASS_SERBUSCTRL_SSA 0x02 +#define PCI_SUB_CLASS_SERBUSCTRL_USB 0x03 +#define PCI_SUB_CLASS_SERBUSCTRL_FIBRECHAN 0x04 + +#define PCI_INVALID_VENDORDEVICEID 0xffffffff +#define PCI_ID(v, d) ((d << 16) | v) + +/* + * PCI access functions + */ +extern rtems_status_code PCIConfigWrite8( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned8 ucValue +); + +extern rtems_status_code PCIConfigWrite16( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned16 usValue +); + +extern rtems_status_code PCIConfigWrite32( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned32 ulValue +); + +extern rtems_status_code PCIConfigRead8( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned8 *pucValue +); + +extern rtems_status_code PCIConfigRead16( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned16 *pusValue +); + +extern rtems_status_code PCIConfigRead32( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned32 *pulValue +); + +/* + * Return the number of PCI busses in the system + */ +extern unsigned8 BusCountPCI(); + +#endif /* _PCI_H_ */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/include/tod.h b/c/src/lib/libbsp/powerpc/ppcn_60x/include/tod.h new file mode 100644 index 0000000000..ef94d35252 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/include/tod.h @@ -0,0 +1,38 @@ +/* + * Real Time Clock (MK48T08) for RTEMS on PPCn_60x + * + * Based on MVME162 TOD by: + * COPYRIGHT (C) 1997 + * by Katsutoshi Shibuya - BU Denken Co.,Ltd. - Sapporo - JAPAN + * ALL RIGHTS RESERVED + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#ifndef TOD_H +#define TOD_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern void setRealTimeToRTEMS(); +/* Read real time from RTC and set it to RTEMS' clock manager */ + +extern void setRealTimeFromRTEMS(); +/* Read time from RTEMS' clock manager and set it to RTC */ + +extern int checkRealTime(); +/* Return the difference between RTC and RTEMS' clock manager time in minutes. + If the difference is greater than 1 day, this returns 9999. */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in new file mode 100644 index 0000000000..cef35eb353 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in @@ -0,0 +1,54 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/network.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=amd79c970 +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c new file mode 100644 index 0000000000..ba3849df9a --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c @@ -0,0 +1,1010 @@ +/* + * 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. + * + */ +/* + * RTEMS/KA9Q driver for PC-NET + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "amd79c970.h" + +/* + * Number of PC-NETs supported by this driver + */ +#define NPCNETDRIVER 1 + +/* + * Default number of buffer descriptors set aside for this driver. + * The number of transmit buffer descriptors has to be quite large + * since a single frame often uses four or more buffer descriptors. + * + * Set the number of Tx and Rx buffers, using Log_2(# buffers). + */ +#define LANCE_LOG2_TX_BUFFERS 4 +#define LANCE_LOG2_RX_BUFFERS 4 +#define TX_RING_SIZE (1 << (LANCE_LOG2_TX_BUFFERS)) +#define TX_RING_MOD_MASK (TX_RING_SIZE - 1) +#define TX_RING_LEN_BITS ((LANCE_LOG2_TX_BUFFERS) << 4) +#define RX_RING_SIZE (1 << (LANCE_LOG2_RX_BUFFERS)) +#define RX_RING_MOD_MASK (RX_RING_SIZE - 1) +#define RX_RING_LEN_BITS ((LANCE_LOG2_RX_BUFFERS) << 4) + +/* + * RTEMS event used by interrupt handler to signal daemons. + * This must *not* be the same event used by the KA9Q task synchronization. + */ +#define INTERRUPT_EVENT RTEMS_EVENT_1 + +/* + * Receive buffer size -- Allow for a full ethernet packet plus a pointer + */ +#define ETHPKT_SIZE 1520 +#define RBUF_SIZE (ETHPKT_SIZE + sizeof (struct iface *)) + +/* + * LANCE Register Access Macros + */ +#define PCNET_IO_RD32(dp, reg, value) \ + inport_32(&dp->pPCNet->u.dwio.##reg, value) +#define PCNET_IO_WR32(dp, reg, value) \ + outport_32(&dp->pPCNet->u.dwio.##reg, value) + +/* + * LANCE Register Access Macros + */ +#define RD_CSR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_RD32(dp, rdp, value) + +#define WR_CSR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_WR32(dp, rdp, value) + +#define RD_BCR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_RD32(dp, bdp, value) + +#define WR_BCR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_WR32(dp, bdp, value) + +/* + * Hardware-specific storage + * + * Note that the enetInitBlk field must be aligned to a 16 byte + * boundary + */ +typedef struct amd79c970Context { + rmde_t rxBdBase[RX_RING_SIZE]; + tmde_t txBdBase[TX_RING_SIZE]; + initblk_t initBlk; + pc_net_t *pPCNet; + unsigned32 ulIntVector; + struct mbuf **rxMbuf; + struct mbuf **txMbuf; + int rxBdCount; + int txBdCount; + int txBdHead; + int txBdTail; + int txBdActiveCount; + struct iface *iface; + rtems_id txWaitTid; + + /* + * Statistics + */ + unsigned long rxInterrupts; + unsigned long rxNotFirst; + unsigned long rxNotLast; + unsigned long rxGiant; + unsigned long rxNonOctet; + unsigned long rxRunt; + unsigned long rxBadCRC; + unsigned long rxOverrun; + unsigned long rxCollision; + unsigned long rxDiscarded; + + unsigned long txInterrupts; + unsigned long txDeferred; + unsigned long txHeartbeat; + unsigned long txLateCollision; + unsigned long txRetryLimit; + unsigned long txUnderrun; + unsigned long txLostCarrier; + unsigned long txRawWait; +} amd79c970Context_t; +static amd79c970Context_t *pAmd79c970Context[NPCNETDRIVER]; + +/* + * PC-NET interrupt handler + */ +static rtems_isr +amd79c970_isr (rtems_vector_number v) +{ + unsigned32 ulCSR0, ulCSR4, ulCSR5; + amd79c970Context_t *dp; + int i; + + for(i=0; iulIntVector==v) + { + RD_CSR32(dp, CSR0, ulCSR0); + if(ulCSR0 & CSR0_RINT) + { + /* + * We have recieve data + */ + dp->rxInterrupts++; + rtems_event_send( + dp->iface->rxproc, + INTERRUPT_EVENT); + } + + if(ulCSR0 & CSR0_TINT) + { + /* + * Data tranmitted or error + */ + dp->txInterrupts++; + if(dp->txWaitTid) + { + rtems_event_send( + dp->txWaitTid, + INTERRUPT_EVENT); + } + } + + if((ulCSR0 & CSR0_INTR) && + !(ulCSR0 & (CSR0_RINT | CSR0_TINT))) + { + /* + * Many possible sources + */ + RD_CSR32(dp, CSR4, ulCSR4); + RD_CSR32(dp, CSR5, ulCSR5); + DEBUG_puts("CSR0="); + DEBUG_puth(ulCSR0); + DEBUG_puts(", CSR4="); + DEBUG_puth(ulCSR4); + DEBUG_puts(", CSR5="); + DEBUG_puth(ulCSR5); + DEBUG_puts("\n\r"); + /* + * Clear it + */ + WR_CSR32(dp, CSR4, ulCSR4); + WR_CSR32(dp, CSR5, ulCSR5); + } + + /* + * Clear interrupts + */ + ulCSR0&=CSR0_BABL | CSR0_CERR | CSR0_MISS | + CSR0_MERR | CSR0_RINT | CSR0_TINT | CSR0_IENA; + WR_CSR32(dp, CSR0, ulCSR0); + + RD_CSR32(dp, CSR0, ulCSR0); + } + } +} + +/* + * Initialize the ethernet hardware + */ +static boolean +amd79c970_initialize_hardware (int instance, int broadcastFlag) +{ + amd79c970Context_t *dp; + struct mbuf *bp; + int i; + unsigned8 ucPCIBusCount; + unsigned8 ucBusNumber; + unsigned8 ucSlotNumber; + unsigned32 ulDeviceID; + unsigned32 ulBAR0; + unsigned8 ucIntVector; + unsigned32 ulInitClkPCIAddr; + unsigned32 ulAPROM; + unsigned32 ulCSR0; + + ucPCIBusCount=BusCountPCI(); + + /* + * Scan the available busses for instance of hardware + */ + i=0; + + dp=pAmd79c970Context[instance]; + dp->pPCNet=(pc_net_t *)NULL; + + for(ucBusNumber=0; + (ucBusNumberpPCNet==(pc_net_t *)NULL); + ucBusNumber++) + { + for(ucSlotNumber=0;ucSlotNumberpPCNet=(pc_net_t *)(ulBAR0&~PCI_ADDRESS_IO_SPACE); + + /* + * Read interrupt vector + */ + PCIConfigRead8(ucBusNumber, + ucSlotNumber, + 0, + PCI_CONFIG_INTERRUPTLINE, + &ucIntVector); + dp->ulIntVector=PPCN_60X_IRQ_PCI(ucIntVector); + + /* + * Ensure that device is enabled + */ + PCIConfigWrite16(ucBusNumber, + ucSlotNumber, + 0, + PCI_CONFIG_COMMAND, + PCI_ENABLE_IO_SPACE | + PCI_ENABLE_BUS_MASTER); + break; + } + } + + if(dp->pPCNet==(pc_net_t *)NULL) + { + return(FALSE); + } + + /* + * Read the ethernet number + */ + if(!dp->iface->hwaddr) + { + dp->iface->hwaddr=mallocw (EADDR_LEN); + PCNET_IO_RD32(dp, aprom[0], ulAPROM); + for(i=0;i<4;i++) + { + dp->iface->hwaddr[i]=(ulAPROM>>(i*8))&0xff; + } + PCNET_IO_RD32(dp, aprom[1], ulAPROM); + for(i=0;i<2;i++) + { + dp->iface->hwaddr[i+4]=(ulAPROM>>(i*8))&0xff; + } + } + + /* + * Allocate mbuf pointers + */ + dp->rxMbuf=mallocw (dp->rxBdCount * sizeof(*dp->rxMbuf)); + dp->txMbuf=mallocw (dp->txBdCount * sizeof(*dp->txMbuf)); + + /* + * Allocate space for incoming packets + */ + for(i=0; irxBdCount; i++) + { + dp->rxMbuf[i]=bp=ambufw (RBUF_SIZE); + bp->data += sizeof (struct iface *); + dp->rxBdBase[i].rmde_addr= + Swap32((unsigned32)bp->data+PCI_SYS_MEM_BASE); + dp->rxBdBase[i].rmde_bcnt= + Swap16(-(bp->size-sizeof (struct iface *))); + dp->rxBdBase[i].rmde_flags=Swap16(RFLG_OWN); + } + + /* + * Set up transmit buffer descriptors + */ + for(i=0; itxBdCount; i++) + { + dp->txBdBase[i].tmde_status=Swap16(TST_STP | TST_ENP); + dp->txBdBase[i].tmde_error=0; + dp->txMbuf[i]=NULL; + } + + /* + * Initialise initblk + */ + if(broadcastFlag) + { + dp->initBlk.ib_mode=0; + } + else + { + dp->initBlk.ib_mode=Swap16(CSR15_DRCVBC); + } + + /* + * Set the receive descriptor ring length + */ + dp->initBlk.ib_rlen=RX_RING_LEN_BITS; + /* + * Set the receive descriptor ring address + */ + dp->initBlk.ib_rdra=Swap32((unsigned32)&dp->rxBdBase[0]+ + PCI_SYS_MEM_BASE); + + /* + * Set the transmit descriptor ring length + */ + dp->initBlk.ib_tlen=TX_RING_LEN_BITS; + /* + * Set the tranmit descriptor ring address + */ + dp->initBlk.ib_tdra=Swap32((unsigned32)&dp->txBdBase[0]+ + PCI_SYS_MEM_BASE); + + for(i=0;i<6;i++) + { + dp->initBlk.ib_padr[i]=dp->iface->hwaddr[i]; + } + + /* + * Ensure that we are in DWIO mode + */ + PCNET_IO_WR32(dp, rdp, 0); + + WR_CSR32(dp, 58,CSR58_PCISTYLE); + + WR_CSR32(dp, CSR3, + CSR3_BABLM | CSR3_MERRM | CSR3_IDONM | CSR3_DXSUFLO); + + WR_CSR32(dp, CSR4, + CSR4_APADXMIT | CSR4_MFCOM | CSR4_RCVCCOM | + CSR4_TXSTRTM | CSR4_JABM); + + WR_CSR32(dp, CSR5, 0); + + ulInitClkPCIAddr=(unsigned32)&dp->initBlk+PCI_SYS_MEM_BASE; + /* + * CSR2 must contain the high order 16 bits of the first word in + * the initialization block + */ + WR_CSR32(dp, CSR2, (ulInitClkPCIAddr >> 16) & 0xffff); + /* + * CSR1 must contain the low order 16 bits of the first word in + * the initialization block + */ + WR_CSR32(dp, CSR1, (ulInitClkPCIAddr & 0xffff)); + + /* + * Set up interrupts + */ + set_vector(amd79c970_isr, + dp->ulIntVector, + instance); + + /* + * Start the device + */ + WR_CSR32(dp, CSR0, CSR0_INIT | CSR0_STRT); + + /* + * Wait for 100mS for the device to initialise + */ + for(i=0; i<100; i++) + { + RD_CSR32(dp, CSR0, ulCSR0); + if(ulCSR0 & CSR0_IDON) + { + break; + } + rtems_ka9q_ppause(1); /* 1mS */ + } + if(i >= 100) + { + return(FALSE); + } + + /* + * Enable interrupts + */ + WR_CSR32(dp, CSR0, CSR0_IENA); + + dp->txBdHead=dp->txBdTail=0; + dp->txBdActiveCount=0; + + return(TRUE); +} + +/* + * Soak up buffer descriptors that have been sent + */ +static void +amd79c970_retire_tx_bd (amd79c970Context_t *dp) +{ + unsigned16 status; + unsigned32 error; + int i; + int nRetired; + + i = dp->txBdTail; + nRetired = 0; + while((dp->txBdActiveCount != 0) && + (((status=Swap16(dp->txBdBase[i].tmde_status)) & TST_OWN)==0)) + { + /* + * See if anything went wrong + */ + if(status & TST_ERR) + { + /* + * Check for errors + */ + error=Swap16(dp->txBdBase[i].tmde_error); + + if (error & TERR_LCOL) + dp->txLateCollision++; + if (error & TERR_RTRY) + dp->txRetryLimit++; + if (error & TERR_UFLO) + dp->txUnderrun++; + if (error & TERR_EXDEF) + dp->txDeferred++; + if (error & TERR_LCAR) + dp->txLostCarrier++; + } + nRetired++; + if (status & TST_ENP) + { + /* + * A full frame has been transmitted. + * Free all the associated buffer descriptors. + */ + dp->txBdActiveCount -= nRetired; + while (nRetired) { + nRetired--; + free_mbuf (&dp->txMbuf[dp->txBdTail]); + if (++dp->txBdTail == dp->txBdCount) + dp->txBdTail = 0; + } + } + if (++i == dp->txBdCount) + { + i = 0; + } + } +} + +/* + * Send raw packet (caller provides header). + * This code runs in the context of the interface transmit + * task or in the context of the network task. + */ +static int +amd79c970_raw (struct iface *iface, struct mbuf **bpp) +{ + amd79c970Context_t *dp; + struct mbuf *bp; + tmde_t *firstTxBd, *txBd; + unsigned16 status; + int nAdded; + + dp = pAmd79c970Context[iface->dev]; + + /* + * Fill in some logging data + */ + iface->rawsndcnt++; + iface->lastsent = secclock (); + dump (iface, IF_TRACE_OUT, *bpp); + + /* + * It would not do to have two tasks active in the transmit + * loop at the same time. + * The blocking is simple-minded since the odds of two tasks + * simultaneously attempting to use this code are low. The only + * way that two tasks can try to run here is: + * 1) Task A enters this code and ends up having to + * wait for a transmit buffer descriptor. + * 2) Task B gains control and tries to transmit a packet. + * The RTEMS/KA9Q scheduling semaphore ensures that there + * are no race conditions associated with manipulating the + * txWaitTid variable. + */ + if (dp->txWaitTid) { + dp->txRawWait++; + while (dp->txWaitTid) + rtems_ka9q_ppause (10); + } + + /* + * Free up buffer descriptors + */ + amd79c970_retire_tx_bd (dp); + + /* + * Set up the transmit buffer descriptors. + * No need to pad out short packets since the + * hardware takes care of that automatically. + * No need to copy the packet to a contiguous buffer + * since the hardware is capable of scatter/gather DMA. + */ + bp = *bpp; + nAdded = 0; + txBd = firstTxBd = dp->txBdBase + dp->txBdHead; + for (;;) { + /* + * Wait for buffer descriptor to become available. + */ + if ((dp->txBdActiveCount + nAdded) == dp->txBdCount) { + /* + * Find out who we are + */ + if (dp->txWaitTid == 0) + rtems_task_ident (0, 0, &dp->txWaitTid); + + /* + * Wait for buffer descriptor to become available. + * Note that the buffer descriptors are checked + * *before* * entering the wait loop -- this catches + * the possibility that a buffer descriptor became + * available between the `if' above, and the clearing + * of the event register. + * Also, the event receive doesn't wait forever. + * This is to catch the case where the transmitter + * stops in the middle of a frame -- and only the + * last buffer descriptor in a frame can generate + * an interrupt. + */ + amd79c970_retire_tx_bd (dp); + while ((dp->txBdActiveCount + nAdded) == dp->txBdCount) { + rtems_ka9q_event_receive (INTERRUPT_EVENT, + RTEMS_WAIT|RTEMS_EVENT_ANY, + 1 + 1000000/BSP_Configuration.microseconds_per_tick); + amd79c970_retire_tx_bd (dp); + } + } + + /* + * Fill in the buffer descriptor + */ + txBd->tmde_addr=Swap32((unsigned32)bp->data+PCI_SYS_MEM_BASE); + txBd->tmde_bcnt=Swap16(-bp->cnt); + dp->txMbuf[dp->txBdHead] = bp; + + nAdded++; + if (++dp->txBdHead == dp->txBdCount) + { + dp->txBdHead = 0; + } + + /* + * Set the transmit buffer status. + * Break out of the loop if this mbuf is the last in the frame. + */ + if ((bp = bp->next) == NULL) { + if(txBd==firstTxBd) + { + /* + * There is only one frame + */ + txBd->tmde_status=Swap16(TST_OWN | + TST_STP | + TST_ENP); + } + else + { + /* + * Mark the last buffer + */ + txBd->tmde_status=Swap16(TST_OWN | + TST_ENP); + /* + * Trigger the first transmit + */ + firstTxBd->tmde_status=Swap16(TST_OWN | + TST_STP); + } + /* + * Sync instruction required to overcome the Grackle + * stale data bug + */ + asm volatile("sync"); + dp->txBdActiveCount += nAdded; + break; + } + else if(txBd!=firstTxBd) + { + txBd->tmde_status = Swap16(TST_OWN); + } + txBd = dp->txBdBase + dp->txBdHead; + } + + /* + * Show that we've finished with the packet + */ + dp->txWaitTid = 0; + *bpp = NULL; + return 0; +} + +/* + * PC-NET reader task + */ +static void +amd79c970_rx (int dev, void *p1, void *p2) +{ + struct iface *iface=(struct iface *)p1; + amd79c970Context_t *dp=(amd79c970Context_t *)p2; + struct mbuf *bp; + rtems_unsigned16 status; + rmde_t *rxBd; + int rxBdIndex; + int continuousCount; + + /* + * Input packet handling loop + */ + continuousCount=0; + rxBdIndex=0; + + while(TRUE) + { + rxBd=&dp->rxBdBase[rxBdIndex]; + + /* + * Wait for packet if there's not one ready + */ + if((status=Swap16(rxBd->rmde_flags)) & RFLG_OWN) + { + /* + * Reset `continuous-packet' count + */ + continuousCount=0; + + /* + * Wait for packet + * Note that the buffer descriptor is checked + * *before* the event wait -- this catches the + * possibility that a packet arrived between the + * `if' above, and the clearing of the event register. + */ + while ((status=Swap16(rxBd->rmde_flags)) & RFLG_OWN) + { + rtems_ka9q_event_receive (INTERRUPT_EVENT, + RTEMS_WAIT|RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT); + } + } + + /* + * Check that packet is valid + */ + if((status & RFLG_ERR) || + ((status & (RFLG_STP|RFLG_ENP)) != (RFLG_STP|RFLG_ENP))) + { + /* + * Something went wrong with the reception + */ + if(!(status & RFLG_ENP)) + dp->rxNotLast++; + if(!(status & RFLG_STP)) + dp->rxNotFirst++; + if(status & RFLG_OFLO) + dp->rxGiant++; + if(status & RFLG_FRAM) + dp->rxNonOctet++; + if(status & RFLG_CRC) + dp->rxBadCRC++; + if(status & RFLG_BUFF) + dp->rxOverrun++; + } + else + { + /* + * Pass the packet up the chain + * The mbuf count is reduced to remove + * the frame check sequence at the end + * of the packet. + */ + bp=dp->rxMbuf[rxBdIndex]; + bp->cnt=Swap16(rxBd->rmde_mcnt) - sizeof (uint32); + net_route (iface, &bp); + + /* + * Give the network code a chance to digest the + * packet. This guards against a flurry of + * incoming packets (usually an ARP storm) from + * using up all the available memory. + */ + if(++continuousCount >= dp->rxBdCount) + kwait_null (); + + /* + * Allocate a new mbuf + * FIXME: It seems to me that it would be better + * if there were some way to limit number of mbufs + * in use by this interface, but I don't see any + * way of determining when the mbuf we pass up + * is freed. + */ + dp->rxMbuf[rxBdIndex]=bp=ambufw (RBUF_SIZE); + bp->data += sizeof (struct iface *); + rxBd->rmde_addr=Swap32( + (unsigned32)bp->data+PCI_SYS_MEM_BASE); + rxBd->rmde_bcnt=Swap16( + -(bp->size-sizeof (struct iface *))); + } + + /* + * Reenable the buffer descriptor + */ + rxBd->rmde_flags=Swap16(RFLG_OWN); + + /* + * Move to next buffer descriptor + */ + if(++rxBdIndex==dp->rxBdCount) + rxBdIndex=0; + } +} + +/* + * Shut down the interface + * FIXME: This is a pretty simple-minded routine. It doesn't worry + * about cleaning up mbufs, shutting down daemons, etc. + */ +static int +amd79c970_stop (struct iface *iface) +{ + amd79c970Context_t *dp; + unsigned32 ulCSR0; + int i; + + dp=pAmd79c970Context[iface->dev]; + + /* + * Stop the device + */ + WR_CSR32(dp, CSR0, CSR0_STOP); + + /* + * Wait for 100mS for the device to stop + */ + for(i=0; i<100; i++) + { + RD_CSR32(dp, CSR0, ulCSR0); + if(!(ulCSR0 & (CSR0_RXON | CSR0_TXON))) + { + break; + } + rtems_ka9q_ppause(1); /* 1mS */ + } + if(i >= 100) + { + return(-1); + } + + /* + * Free up all the mbufs we've allocated + */ + for(i=0; irxBdCount; i++) + { + free_mbuf(&dp->rxMbuf[i]); + } + + return 0; +} + +/* + * Show interface statistics + */ +static void +amd79c970_show (struct iface *iface) +{ + int i; + + i=iface->dev; + + printf (" Rx Interrupts:%-8lu", pAmd79c970Context[i]->rxInterrupts); + printf (" Not First:%-8lu", pAmd79c970Context[i]->rxNotFirst); + printf (" Not Last:%-8lu\n", pAmd79c970Context[i]->rxNotLast); + printf (" Giant:%-8lu", pAmd79c970Context[i]->rxGiant); + printf (" Runt:%-8lu", pAmd79c970Context[i]->rxRunt); + printf (" Non-octet:%-8lu\n", pAmd79c970Context[i]->rxNonOctet); + printf (" Bad CRC:%-8lu", pAmd79c970Context[i]->rxBadCRC); + printf (" Overrun:%-8lu", pAmd79c970Context[i]->rxOverrun); + printf (" Collision:%-8lu\n", pAmd79c970Context[i]->rxCollision); + printf (" Discarded:%-8lu\n", pAmd79c970Context[i]->rxDiscarded); + + printf (" Tx Interrupts:%-8lu", pAmd79c970Context[i]->txInterrupts); + printf (" Deferred:%-8lu", pAmd79c970Context[i]->txDeferred); + printf (" Missed Hearbeat:%-8lu\n", pAmd79c970Context[i]->txHeartbeat); + printf (" No Carrier:%-8lu", pAmd79c970Context[i]->txLostCarrier); + printf ("Retransmit Limit:%-8lu", pAmd79c970Context[i]->txRetryLimit); + printf (" Late Collision:%-8lu\n", pAmd79c970Context[i]->txLateCollision); + printf (" Underrun:%-8lu", pAmd79c970Context[i]->txUnderrun); + printf (" Raw output wait:%-8lu\n", pAmd79c970Context[i]->txRawWait); +} + +/* + * Attach an PC-NET driver to the system + * This is the only `extern' function in the driver. + * + * argv[0]: interface label, e.g., "amd79c970" + * argv[1]: maximum transmission unit, bytes, e.g., "1500" + * argv[2]: accept ("broadcast") or ignore ("nobroadcast") broadcast packets + * Following arguments are optional, but if present, must appear in + * the following order: + * Following arguments are optional, but if Ethernet address is + * specified, Internet address must also be specified. + * ###.###.###.### -- IP address + * ##:##:##:##:##:## -- Ethernet address + */ +int +rtems_ka9q_driver_attach (int argc, char *argv[], void *p) +{ + struct iface *iface; + struct amd79c970Context *dp; + char *cp; + int i; + int argIndex; + int broadcastFlag; + + /* + * Find a free driver + */ + for(i=0; iname=strdup (argv[0]); + iface->mtu=atoi (argv[1]); + + /* + * Select broadcast packet handling + */ + cp=argv[2]; + if(strnicmp (cp, "broadcast", strlen (cp))==0) + { + broadcastFlag=1; + } + else if(strnicmp (cp, "nobroadcast", strlen (cp))==0) + { + broadcastFlag=0; + } + else { + printf ("Argument `%s' is neither `broadcast' nor `nobroadcast'.\n", cp); + return -1; + } + argIndex=3; + + /* + * Set receive buffer descriptor count + */ + dp->rxBdCount=RX_RING_SIZE; + + /* + * Set transmit buffer descriptor count + */ + dp->txWaitTid=0; + dp->txBdCount=TX_RING_SIZE; + + /* + * Set Internet address + */ + if(argIndexaddr=resolve (argv[argIndex++]); + else + iface->addr=Ip_addr; + + /* + * Set Ethernet address + */ + if(argIndexhwaddr=mallocw (EADDR_LEN); + gether (iface->hwaddr, argv[argIndex++]); + } + + iface->dev=i; + iface->raw=amd79c970_raw; + iface->stop=amd79c970_stop; + iface->show=amd79c970_show; + dp->iface=iface; + setencap (iface, "Ethernet"); + + /* + * Set up PC-NET hardware + */ + if(!amd79c970_initialize_hardware (i, broadcastFlag)) + { + printf ("Unable to initialize hardware for %s\n", argv[0]); + return -1; + } + + /* + * Chain onto list of interfaces + */ + iface->next=Ifaces; + Ifaces=iface; + + /* + * Start I/O daemons + */ + cp=if_name (iface, " tx"); + iface->txproc=newproc (cp, 1024, if_tx, iface->dev, iface, NULL, 0); + free (cp); + cp=if_name (iface, " rx"); + iface->rxproc=newproc (cp, 1024, amd79c970_rx, iface->dev, iface, dp, 0); + free (cp); + return 0; +} + +/* + * FIXME: There should be an ioctl routine to allow things like + * enabling/disabling reception of broadcast packets. + */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h new file mode 100644 index 0000000000..dd30d90b0d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h @@ -0,0 +1,426 @@ +/* + * 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. + * + */ +#ifndef _PCNET_H +#define _PCNET_H + +/* + * IO space structure for the AMD79C970 device + */ + +typedef volatile struct pc_net +{ + union + { + struct { + unsigned16 aprom[8]; /* 0x00 */ + unsigned16 rdp; /* 0x10 */ + unsigned16 rap; /* 0x14 */ + unsigned16 reset; /* 0x18 */ + unsigned16 bdp; /* 0x1C */ + } wio; + struct { + unsigned32 aprom[4]; /* 0x00 */ + unsigned32 rdp; /* 0x10 */ + unsigned32 rap; /* 0x12 */ + unsigned32 reset; /* 0x14 */ + unsigned32 bdp; /* 0x16 */ + } dwio; + } u; +} pc_net_t; + +/* + * The EEPROM is 2Kbit (128bytes) + */ +#define EEPROM_SIZE 128 +#define EEPROM_HEAD_SIZE 36 + +typedef struct pc_net_eeprom { + unsigned8 EthNumber[6]; + unsigned16 Reserved1; /* Must be 0x0000 */ + unsigned16 Reserved2; /* Must be 0x1000 */ + unsigned16 User1; + unsigned16 checksum; + unsigned16 Reserved3; /* Must be 0x5757 */ + unsigned16 bcr16; + unsigned16 bcr17; + unsigned16 bcr18; + unsigned16 bcr2; + unsigned16 bcr21; + unsigned16 Reserved4; /* Must be 0x0000 */ + unsigned16 Reserved5; /* Must be 0x0000 */ + unsigned8 Reserved6; /* Must be 0x00 */ + unsigned8 checksumAdjust; + unsigned16 Reserved7; /* Must be 0x0000 */ + unsigned16 crc; /* CCITT checksum from Serial[] onwards */ + unsigned8 Serial[16]; /* Radstone Serial Number */ +} pc_net_eeprom_t; + +/* + * PCnet-PCI Single Chip Ethernet Controller for PCI Local Bus + */ +/* + * Register and bit definitions + */ + +#define CSR0 0 +#define CSR1 1 +#define CSR2 2 +#define CSR3 3 +#define CSR4 4 +#define CSR5 5 +#define CSR6 6 +#define CSR7 7 +#define CSR8 8 +#define CSR9 9 +#define CSR15 15 +#define CSR47 47 +#define CSR82 82 /* Bus Activity Timer */ +#define CSR100 100 /* Memory Error Timeout register */ +#define CSR114 114 +#define CSR122 122 /* Receiver Packet Alignment Register */ + +#define BCR2 2 /* Misc. Configuration */ +#define BCR18 18 /* Bus size and burst control */ +#define DEFAULT_BCR18 0x2162 /* default BCR18 value - was 0x21e2*/ +#define BCR19 19 +#define BCR20 20 /* Software Style */ +#define BCR21 21 + +#define APROM0 0x00 +#define APROM1 0x04 +#define APROM2 0x08 + +/* + * CSR0: Bit definitions + */ +#define CSR0_ERR 0x8000 /* error summary */ +#define CSR0_BABL 0x4000 /* babble error */ +#define CSR0_CERR 0x2000 /* collision error */ +#define CSR0_MISS 0x1000 /* missed packet */ +#define CSR0_MERR 0x0800 /* memory error */ +#define CSR0_RINT 0x0400 /* receiver interrupt */ +#define CSR0_TINT 0x0200 /* transmitter interrupt */ +#define CSR0_IDON 0x0100 /* initialization done */ +#define CSR0_INTR 0x0080 /* interrupt flag */ +#define CSR0_IENA 0x0040 /* interrupt enable */ +#define CSR0_RXON 0x0020 /* receiver on */ +#define CSR0_TXON 0x0010 /* transmitter on */ +#define CSR0_TDMD 0x0008 /* transmit demand */ +#define CSR0_STOP 0x0004 /* stop the ilacc */ +#define CSR0_STRT 0x0002 /* start the ilacc */ +#define CSR0_INIT 0x0001 /* initialize the ilacc */ + +#define CSR3_BABLM 0x4000 /* BABL Mask */ +#define CSR3_MISSM 0x1000 /* Missed packet Mask */ +#define CSR3_MERRM 0x0800 /* Memory error Mask */ +#define CSR3_RINTM 0x0400 /* Receive Interrupt Mask */ +#define CSR3_TINTM 0x0200 /* Transmit Interrupt Mask */ +#define CSR3_IDONM 0x0100 /* Initialization Done Mask */ +#define CSR3_DXSUFLO 0x0040 /* Disable tx stop on underrun */ +#define CSR3_LAPPEN 0x0020 /* lookahead packet proc enable */ +#define CSR3_DXMT2PD 0x0010 /* disable 2 part deferral */ +#define CSR3_EMBA 0x0008 /* enable modified backoff */ +#define CSR3_BSWP 0x0004 /* byte swap */ + +#define CSR4_DMAPLUS 0x4000 /* DMA burst transfer until FIFO empty */ +#define CSR4_BACON_68K 0x0040 /* 32 bit 680x0 */ +#define CSR4_TXSTRT 0x0008 /* Transmit STaRT status */ +#define CSR4_TXSTRTM 0x0004 /* Transmit STaRT interrupt Mask */ +#define CSR4_ENTST 0x8000 /* enable test mode */ +#define CSR4_TIMER 0x2000 /* enable bus timer csr82 */ +#define CSR4_DPOLL 0x1000 /* disable tx polling */ +#define CSR4_APADXMIT 0x0800 /* auto pad tx to 64 */ +#define CSR4_ASTRPRCV 0x0400 /* auto strip rx pad and fcs */ +#define CSR4_MFCO 0x0200 /* missed frame counter oflo interrupt */ +#define CSR4_MFCOM 0x0100 /* mask to disable */ +#define CSR4_RCVCCO 0x0020 /* rx collision counter oflo interrupt */ +#define CSR4_RCVCCOM 0x0010 /* mask to disable */ +#define CSR4_JAB 0x0002 /* jabber error 10baseT interrupt */ +#define CSR4_JABM 0x0001 /* mask to disable */ + +#define CSR5_SPND 0x0001 /* Suspend */ + +#define CSR15_PROM 0x8000 /* Promiscuous */ +#define CSR15_DRCVBC 0x4000 /* Disable receiver broadcast */ +#define CSR15_DRCVPA 0x2000 /* Disable receiver phys. addr. */ +#define CSR15_DLNKTST 0x1000 /* Disable link status */ +#define CSR15_DAPC 0x0800 /* Disable auto polarity det. */ +#define CSR15_MENDECL 0x0400 /* MENDEC loopback mode */ +#define CSR15_LRT 0x0200 /* Low receiver threshold */ +#define CSR15_TSEL 0x0200 /* Transmit mode select */ +#define CSR15_INTL 0x0040 /* Internal loopback */ +#define CSR15_DRTY 0x0020 /* Disable retry */ +#define CSR15_FCOLL 0x0010 /* Force collision */ +#define CSR15_DXMTFCS 0x0008 /* Disable transmit CRC */ +#define CSR15_LOOP 0x0004 /* Loopback enable */ +#define CSR15_DTX 0x0002 /* Disable transmitter */ +#define CSR15_DRX 0x0001 /* Disable receiver */ + +#define CSR58_PCISTYLE 0x0002 /* software style */ + +#define CSR80_RCVFW16 (0<<12) /* fifo level to trigger rx dma */ +#define CSR80_RCVFW32 (1<<12) +#define CSR80_RCVFW64 (2<<12) +#define CSR80_XMTSP4 (0<<10) /* fifo level to trigger tx */ +#define CSR80_XMTSP16 (1<<10) +#define CSR80_XMTSP64 (2<<10) +#define CSR80_XMTSP112 (3<<10) +#define CSR80_XMTFW16 (0<<8) /* fifo level to stop dma */ +#define CSR80_XMTFW32 (1<<8) +#define CSR80_XMTFW64 (2<<8) +/* must also clear csr4 CSR4_DMAPLUS: */ +#define CSR80_DMATC(x) ((x)&0xff) /* max transfers per burst. deflt 16 */ +/* + * must also set csr4 CSR4_TIMER: + */ +#define CSR82_DMABAT(x) ((x)&0xffff) /* max burst time nanosecs*100 */ + +#define BCR18_MUSTSET 0x0100 /* this bit must be written as 1 !! */ +#define BCR18_BREADE 0x0040 /* linear burst enable. yes ! on pci */ +#define BCR18_BWRITE 0x0020 /* in write direction */ +#define BCR18_LINBC4 0x0001 /* linear burst count 4 8 or 16 */ +#define BCR18_LINBC8 0x0002 /* NOTE LINBC must be <= fifo trigger*/ +#define BCR18_LINBC16 0x0004 + +#define BCR19_PVALID 0x8000 /* aprom (eeprom) read checksum ok */ + +/* + * initial setting of csr0 + */ +#define CSR0_IVALUE (CSR0_IDON | CSR0_IENA | CSR0_STRT | CSR0_INIT) + +/* + * our setting of csr3 + */ +#define CSR3_VALUE (CSR3_ACON | CSR3_BSWP) + +/* + * Initialization Block. + * Chip initialization includes the reading of the init block to obtain + * the operating parameters. + * + * This essentially consists of 7, 32 bit LE words. In the following the + * fields are ordered so that they map correctly in BE mode, however each + * 16 and 32 byte field will require swapping. + */ + +typedef volatile struct initblk { + /* mode can be set in csr15 */ + unsigned16 ib_mode; /* Chip's operating parameters */ + unsigned8 ib_rlen; /* rx ring length (power of 2) */ + unsigned8 ib_tlen; /* tx ring length (power of 2) */ +/* + * The bytes must be swapped within the word, so that, for example, + * the address 8:0:20:1:25:5a is written in the order + * 0 8 1 20 5a 25 + * For PCI970 that is long word swapped: so no swapping needed, since + * the bus will swap. + */ + unsigned8 ib_padr[8]; /* physical address */ + unsigned16 ib_ladrf[4]; /* logical address filter */ + unsigned32 ib_rdra; /* rcv ring desc addr */ + unsigned32 ib_tdra; /* xmit ring desc addr */ +} initblk_t; + + +/* + * bits in mode register: allows alteration of the chips operating parameters + */ +#define IBM_PROM 0x8000 /* promiscuous mode */ +/* + * mode is also in cr15 + */ +#define MODE_DRCVBC 0x4000 /* disable receive broadcast */ +#define MODE_DRCVPA 0x2000 /* disable receive physical address */ +#define MODE_DLNKTST 0x1000 /* disable link status monitoring 10T */ +#define MODE_DAPC 0x0800 /* disable auto polarity 10T */ +#define MODE_MENDECL 0x0400 /* mendec loopback */ +#define MODE_LRT 0x0200 /* low receive threshold/tx mode sel tmau */ +#define MODE_PORTSEL10T 0x0080 /* port select 10T ?? */ +#define MODE_PORTSELAUI 0x0000 /* port select aui ?? */ +#define IBM_INTL 0x0040 /* internal loopback */ +#define IBM_DRTY 0x0020 /* disable retry */ +#define IBM_COLL 0x0010 /* force collision */ +#define IBM_DTCR 0x0008 /* disable transmit crc */ +#define IBM_LOOP 0x0004 /* loopback */ +#define IBM_DTX 0x0002 /* disable transmitter */ +#define IBM_DRX 0x0001 /* disable receiver */ + +/* + * Buffer Management is accomplished through message descriptors organized + * in ring structures in main memory. There are two rings allocated for the + * device: a receive ring and a transmit ring. The following defines the + * structure of the descriptor rings. + */ + +/* + * Receive List type definition + * + * This essentially consists of 4, 32 bit LE words. In the following the + * fields are ordered so that they map correctly in BE mode, however each + * 16 and 32 byte field will require swapping. + */ + +typedef volatile struct rmde { + unsigned32 rmde_addr; /* buf addr */ + + unsigned16 rmde_bcnt; + unsigned16 rmde_flags; + + unsigned16 rmde_mcnt; + unsigned16 rmde_misc; + + unsigned32 align; +} rmde_t; + + +/* + * bits in the flags field + */ +#define RFLG_OWN 0x8000 /* ownership bit, 1==LANCE */ +#define RFLG_ERR 0x4000 /* error summary */ +#define RFLG_FRAM 0x2000 /* framing error */ +#define RFLG_OFLO 0x1000 /* overflow error */ +#define RFLG_CRC 0x0800 /* crc error */ +#define RFLG_BUFF 0x0400 /* buffer error */ +#define RFLG_STP 0x0200 /* start of packet */ +#define RFLG_ENP 0x0100 /* end of packet */ + +/* + * bits in the buffer byte count field + */ +#define RBCNT_ONES 0xf000 /* must be ones */ +#define RBCNT_BCNT 0x0fff /* buf byte count, in 2's compl */ + +/* + * bits in the message byte count field + */ +#define RMCNT_RES 0xf000 /* reserved, read as zeros */ +#define RMCNT_BCNT 0x0fff /* message byte count */ + +/* + * Transmit List type definition + * + * This essentially consists of 4, 32 bit LE words. In the following the + * fields are ordered so that they map correctly in BE mode, however each + * 16 and 32 byte field will require swapping. + */ +typedef volatile struct tmde { + unsigned32 tmde_addr; /* buf addr */ + + unsigned16 tmde_bcnt; + unsigned16 tmde_status; /* misc error and status bits */ + + unsigned32 tmde_error; + + unsigned32 align; +} tmde_t; + +/* + * bits in the status field + */ +#define TST_OWN 0x8000 /* ownership bit, 1==LANCE */ +#define TST_ERR 0x4000 /* error summary */ +#define TST_RES 0x2000 /* reserved bit */ +#define TST_MORE 0x1000 /* more than one retry was needed */ +#define TST_ONE 0x0800 /* one retry was needed */ +#define TST_DEF 0x0400 /* defer while trying to transmit */ +#define TST_STP 0x0200 /* start of packet */ +#define TST_ENP 0x0100 /* end of packet */ + +/* + * setting of status field when packet is to be transmitted + */ +#define TST_XMIT (TST_STP | TST_ENP | TST_OWN) + +/* + * bits in the buffer byte count field + */ +#define TBCNT_ONES 0xf000 /* must be ones */ +#define TBCNT_BCNT 0x0fff /* buf byte count, in 2's compl */ + +/* + * bits in the error field + */ +#define TERR_BUFF 0x8000 /* buffer error */ +#define TERR_UFLO 0x4000 /* underflow error */ +#define TERR_EXDEF 0x2000 /* excessive deferral */ +#define TERR_LCOL 0x1000 /* late collision */ +#define TERR_LCAR 0x0800 /* loss of carrier */ +#define TERR_RTRY 0x0400 /* retry error */ +#define TERR_TDR 0x03ff /* time domain reflectometry */ + +/* + * Defines pertaining to statistics gathering (diagnostic only) + */ + +/* + * receive errors + */ +#define ERR_FRAM 0 /* framing error */ +#define ERR_OFLO 1 /* overflow error */ +#define ERR_CRC 2 /* crc error */ +#define ERR_RBUFF 3 /* receive buffer error */ + +/* + * transmit errors + */ +#define ERR_MORE 4 /* more than one retry */ +#define ERR_ONE 5 /* one retry */ +#define ERR_DEF 6 /* defer'd packet */ +#define ERR_TBUFF 7 /* transmit buffer error */ +#define ERR_UFLO 8 /* underflow error */ +#define ERR_LCOL 9 /* late collision */ +#define ERR_LCAR 10 /* loss of carrier */ +#define ERR_RTRY 11 /* retry error, >16 retries */ + +/* + * errors reported in csr0 + */ +#define ERR_BABL 12 /* transmitter timeout error */ +#define ERR_MISS 13 /* missed packet */ +#define ERR_MEM 14 /* memory error */ +#define ERR_CERR 15 /* collision errors */ +#define XMIT_INT 16 /* transmit interrupts */ +#define RCV_INT 17 /* receive interrupts */ + +#define NHARD_ERRORS 18 /* error types used in diagnostic */ + +/* + * other statistics + */ +#define ERR_TTOUT 18 /* transmit timeouts */ +#define ERR_ITOUT 19 /* init timeouts */ +#define ERR_INITS 20 /* reinitializations */ +#define ERR_RSILO 21 /* silo ptrs misaligned on recv */ +#define ERR_TSILO 22 /* silo ptrs misaligned on xmit */ +#define ERR_SINTR 23 /* spurious interrupts */ + +#define NUM_ERRORS 24 /* number of errors types */ + +/* + * Bit definitions for BCR19 + */ +#define prom_EDI (unsigned16)0x0001 +#define prom_EDO (unsigned16)0x0001 +#define prom_ESK (unsigned16)0x0002 +#define prom_ECS (unsigned16)0x0004 +#define prom_EEN (unsigned16)0x0010 +#define prom_EEDET (unsigned16)0x2000 +#define prom_PVALID (unsigned16)0x8000 +#define prom_PREAD (unsigned16)0x4000 + +#endif diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/Makefile.in new file mode 100644 index 0000000000..5cf4e06e0e --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/Makefile.in @@ -0,0 +1,56 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/nvram.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=$(NVRAM_PIECES) +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +NVRAM_PIECES=nvram + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/ds1385.h b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/ds1385.h new file mode 100644 index 0000000000..c4861d9c80 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/ds1385.h @@ -0,0 +1,39 @@ +/* + * 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. + * + */ + +/* + * Definitions for the ds1385 NvRAM + */ + +#ifndef _DS1385_H +#define _DS1385_H + +#include "prepnvr.h" + +#define DS1385_NVSIZE 4096 /* size of NVRAM */ +#define DS1385_GESIZE (DS1385_NVSIZE-CONFSIZE-OSAREASIZE-sizeof(HEADER)) +#define DS1385_PORT_BASE 0x74 + +/* Here is the whole map of the DS1385 NVRAM */ +typedef struct _DS1385_NVRAM_MAP { + HEADER Header; + unsigned char GEArea[DS1385_GESIZE]; + unsigned char OSArea[OSAREASIZE]; + unsigned char ConfigArea[CONFSIZE]; + } DS1385_NVRAM_MAP, *PDS1385_NVRAM_MAP; + +#endif /* _DS1385_H */ + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/mk48t18.h b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/mk48t18.h new file mode 100644 index 0000000000..f4aa3be106 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/mk48t18.h @@ -0,0 +1,87 @@ +/* + * 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. + * + */ + +/* + * Definitions for the mk48t18 RTC/NvRAM + */ + +#ifndef _MK48T18_H +#define _MK48T18_H + +#include "prepnvr.h" + +/* + * This structure maps to the top of the NvRAM. It is based on the standard + * CMOS.h file for the ds1385. Feature and system dependant areas are preserved + * for potential compatibility issues. + * + * The CRC's are computed with x**16+x**12+x**5 + 1 polynomial + * The clock is kept in 24 hour BCD mode and should be set to UT(GMT) + */ + +typedef struct _MK48T18_CMOS_MAP { + unsigned8 SystemDependentArea2[8]; + unsigned8 FeatureByte0[1]; + unsigned8 FeatureByte1[1]; + unsigned8 Century; /* century byte in BCD */ + unsigned8 FeatureByte3[1]; + unsigned8 FeatureByte4[1]; + unsigned8 FeatureByte5[1]; + unsigned8 FeatureByte6[1]; + unsigned8 FeatureByte7[1]; + unsigned8 BootPW[14]; + rtems_unsigned16 BootCrc; /* CRC on BootPW */ + unsigned8 ConfigPW[14]; + rtems_unsigned16 ConfigCrc; /* CRC on ConfigPW */ + unsigned8 SystemDependentArea1[8]; + /* + * The following are the RTC registers + */ + volatile unsigned8 Control; + volatile unsigned8 Second:7; /* 0-59 */ + volatile unsigned8 Stop:1; + volatile unsigned8 Minute; /* 0-59 */ + volatile unsigned8 Hour; /* 0-23 */ + volatile unsigned8 Day:3; /* 1-7 */ + volatile unsigned8 Resvd1:3; /* 0 */ + volatile unsigned8 FT:1; /* Frequency test bit - must be 0 */ + volatile unsigned8 Resvd2:1; /* 0 */ + volatile unsigned8 Date; /* 1-31 */ + volatile unsigned8 Month; /* 1-12 */ + volatile unsigned8 Year; /* 0-99 */ +} MK48T18_CMOS_MAP, *PMK48T18_CMOS_MAP; + +/* + * Control register definitions + */ +#define MK48T18_CTRL_WRITE 0x80 +#define MK48T18_CTRL_READ 0x40 +#define MK48T18_CTRL_SIGN 0x20 + +#define MK48T18_NVSIZE 8192-sizeof(MK48T18_CMOS_MAP) +#define MK48T18_GESIZE (MK48T18_NVSIZE-CONFSIZE-OSAREASIZE-sizeof(HEADER)) +#define MK48T18_BASE (PMK48T18_NVRAM_MAP)((unsigned8 *)PCI_MEM_BASE+0x00800000) + +/* Here is the whole map of the MK48T18 NVRAM */ +typedef struct _MK48T18_NVRAM_MAP { + HEADER Header; + unsigned8 GEArea[MK48T18_GESIZE]; + unsigned8 OSArea[OSAREASIZE]; + unsigned8 ConfigArea[CONFSIZE]; + MK48T18_CMOS_MAP CMOS; +} MK48T18_NVRAM_MAP, *PMK48T18_NVRAM_MAP; + +#endif /* _MK48T18_H */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c new file mode 100644 index 0000000000..bf085c968b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c @@ -0,0 +1,515 @@ +/* + * This file contains the NvRAM driver for the PPCn_60x + * + * 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. + * + */ + +#include +#include "ds1385.h" +#include "mk48t18.h" +#include "stk11c68.h" + +/* + * Private types + */ +typedef +void +(*PNVRAMWRITE) +( + unsigned32 ulOffset, + unsigned8 ucByte +); + +typedef +unsigned8 +(*PNVRAMREAD) +( + unsigned32 ulOffset +); + +typedef +void +(*PNVRAMCOMMIT) +( +); + +typedef struct _NVRAM_ENTRY_TABLE +{ + PNVRAMWRITE nvramWrite; + PNVRAMREAD nvramRead; + PNVRAMCOMMIT nvramCommit; + unsigned32 nvramSize; +} NVRAM_ENTRY_TABLE, *PNVRAM_ENTRY_TABLE; + +/* + * Private routines + */ + +/* + * This routine provides a stub for NvRAM devices which + * do not require a commit operation + */ +static void nvramCommitStub(); + +/* + * DS1385 specific routines + */ +static void nvramDsWrite(unsigned32 ulOffset, unsigned8 ucByte); +static unsigned8 nvramDsRead(unsigned32 ulOffset); + +/* + * MK48T18 specific routines + */ +static void nvramMkWrite(unsigned32 ulOffset, unsigned8 ucByte); +static unsigned8 nvramMkRead(unsigned32 ulOffset); + +/* + * STK11C68 specific routines + */ +static void nvramStk11C68Commit(); +/* + * STK11C88 specific routines + */ +static void nvramStk11C88Commit(); + +/* + * NvRAM hook tables + */ +NVRAM_ENTRY_TABLE nvramDsTable = +{ + nvramDsWrite, + nvramDsRead, + nvramCommitStub, + DS1385_NVSIZE +}; + +NVRAM_ENTRY_TABLE nvramMkTable = +{ + nvramMkWrite, + nvramMkRead, + nvramCommitStub, + MK48T18_NVSIZE +}; + +/* + * As the STK devicxe is at the same address as the MK device, + * the MK read/write routines may be used + */ +NVRAM_ENTRY_TABLE nvramStkTable = +{ + nvramMkWrite, + nvramMkRead, + nvramStk11C68Commit, + STK11C68_NVSIZE +}; + +NVRAM_ENTRY_TABLE nvramStk88Table = +{ + nvramMkWrite, + nvramMkRead, + nvramStk11C88Commit, + STK11C88_NVSIZE +}; + +/* + * Private variables + */ +static PNVRAM_ENTRY_TABLE pNvRAMFunc; +static boolean bNvRAMChanged=FALSE; +static unsigned32 ulPRePOSAreaLength; +static unsigned32 ulPRePOSAreaOffset; + +/* + * Mutual-exclusion semaphore + */ +static rtems_id semNvRAM; + +/* + * These routines support the ds1385 + */ +static unsigned8 nvramDsRead(unsigned32 ulOffset) +{ + unsigned8 ucTemp; + + ucTemp = ulOffset & 0xff; + outport_byte(DS1385_PORT_BASE, ucTemp); + + ucTemp = (ulOffset >> 8) & 0xf; + outport_byte((DS1385_PORT_BASE + 1) , ucTemp); + + inport_byte(DS1385_PORT_BASE+3, ucTemp); + return(ucTemp); +} + +static void nvramDsWrite(unsigned32 ulOffset, unsigned8 ucData) +{ + unsigned8 ucTemp; + + ucTemp = (unsigned8)(ulOffset & 0xff); + outport_byte(DS1385_PORT_BASE, (unsigned8) ucTemp); + + ucTemp = (unsigned8)((ulOffset >> 8) & 0xf); + outport_byte((DS1385_PORT_BASE + 1) , (unsigned8)ucTemp); + + outport_byte((DS1385_PORT_BASE+3), ucData); +} + +/* + * These routines support the MK48T18 and STK11C68 + */ +static unsigned8 nvramMkRead(unsigned32 ulOffset) +{ + unsigned8 *pNvRAM = (unsigned8 *)MK48T18_BASE; + + return(pNvRAM[ulOffset]); +} + +static void nvramMkWrite(unsigned32 ulOffset, unsigned8 ucData) +{ + unsigned8 *pNvRAM = (unsigned8 *)MK48T18_BASE; + + pNvRAM[ulOffset]=ucData; +} + +/* + * This routine provides a stub for NvRAM devices which + * do not require a commit operation + */ +static void nvramCommitStub() +{ +} + +/* + * This routine triggers a transfer from the NvRAM to the + * EE array in the STK11C68 device + */ +static void nvramStk11C68Commit() +{ +#if 0 + rtems_interval ticks_per_second; + rtems_status_code status; +#endif + + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + /* + * Issue Store command + */ + EIEIO; + (void)pNvRAMFunc->nvramRead(0x0000); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x1555); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x0aaa); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x1fff); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x10f0); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x0f0f); + EIEIO; + /* + * Delay for 10mS to allow store to + * complete + */ +#if 0 + status = rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_PER_SECOND, + &ticks_per_second + ); + + status = rtems_task_wake_after(ticks_per_second/100); +#endif + bNvRAMChanged=FALSE; + + rtems_semaphore_release(semNvRAM); +} + +/* + * This routine triggers a transfer from the NvRAM to the + * EE array in the STK11C88 device + */ +static void nvramStk11C88Commit() +{ +#if 0 + rtems_interval ticks_per_second; + rtems_status_code status; +#endif + + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + /* + * Issue Store command + */ + EIEIO; + (void)pNvRAMFunc->nvramRead(0x0e38); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x31c7); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x03e0); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x3c1f); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x303f); + EIEIO; + (void)pNvRAMFunc->nvramRead(0x0fc0); + EIEIO; + /* + * Delay for 10mS to allow store to + * complete + */ +#if 0 + status = rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_PER_SECOND, + &ticks_per_second + ); + + status = rtems_task_wake_after(ticks_per_second/100); +#endif + bNvRAMChanged=FALSE; + + rtems_semaphore_release(semNvRAM); +} + +/* + * These are the publically accessable routines + */ +/* + * This routine returns the size of the NvRAM + */ +unsigned32 SizeNvRAM() +{ + return(ulPRePOSAreaLength); +} + +/* + * This routine commits changes to the NvRAM + */ +void CommitNvRAM() +{ + if(bNvRAMChanged) + { + (pNvRAMFunc->nvramCommit)(); + } +} + +/* + * This routine reads a byte from the NvRAM + */ +rtems_status_code ReadNvRAM8(unsigned32 ulOffset, unsigned8 *pucData) +{ + if(ulOffset>ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + *pucData=pNvRAMFunc->nvramRead(ulPRePOSAreaOffset+ulOffset); + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +/* + * This routine writes a byte to the NvRAM + */ +rtems_status_code WriteNvRAM8(unsigned32 ulOffset, unsigned8 ucValue) +{ + if(ulOffset>ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + pNvRAMFunc->nvramWrite(ulPRePOSAreaOffset+ulOffset, ucValue); + bNvRAMChanged=TRUE; + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +/* + * This routine reads a block of bytes from the NvRAM + */ +rtems_status_code ReadNvRAMBlock( + unsigned32 ulOffset, unsigned8 *pucData, unsigned32 length) +{ + unsigned32 i; + + if((ulOffset + length) > ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + for ( i=0 ; invramRead(ulPRePOSAreaOffset+ulOffset+i); + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +/* + * This routine writes a block of bytes to the NvRAM + */ +rtems_status_code WriteNvRAMBlock( + unsigned32 ulOffset, unsigned8 *ucValue, unsigned32 length) +{ + unsigned32 i; + + if((ulOffset + length) > ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + + for ( i=0 ; invramWrite( + ulPRePOSAreaOffset+ulOffset+i, ucValue[i]); + bNvRAMChanged=TRUE; + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +/* + * The NVRAM holds data in Big-Endian format + */ +rtems_status_code ReadNvRAM16 (unsigned32 ulOffset, unsigned16 *pusData) +{ + unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset; + + if(ulOffset>ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + *pusData=(pNvRAMFunc->nvramRead(ulTrueOffset) << 8) + + (pNvRAMFunc->nvramRead(ulTrueOffset + 1)); + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code WriteNvRAM16 (unsigned32 ulOffset, unsigned16 usValue) +{ + unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset; + + if(ulOffset>ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + pNvRAMFunc->nvramWrite(ulTrueOffset, (unsigned8) (usValue >> 8)); + pNvRAMFunc->nvramWrite(ulTrueOffset + 1, (unsigned8) usValue); + bNvRAMChanged=TRUE; + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code ReadNvRAM32 (unsigned32 ulOffset, unsigned32 *pulData) +{ + unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset; + + if(ulOffset>ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + *pulData=(pNvRAMFunc->nvramRead(ulTrueOffset) << 24) + + (pNvRAMFunc->nvramRead(ulTrueOffset + 1) << 16) + + (pNvRAMFunc->nvramRead(ulTrueOffset + 2) << 8) + + (pNvRAMFunc->nvramRead(ulTrueOffset + 3)); + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code WriteNvRAM32 (unsigned32 ulOffset, unsigned32 ulValue) +{ + unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset; + + if(ulOffset>ulPRePOSAreaLength) + { + return RTEMS_INVALID_ADDRESS; + } + rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + pNvRAMFunc->nvramWrite(ulTrueOffset, (unsigned8) (ulValue >> 24)); + pNvRAMFunc->nvramWrite(ulTrueOffset + 1, (unsigned8) (ulValue >> 16)); + pNvRAMFunc->nvramWrite(ulTrueOffset + 2, (unsigned8) (ulValue >> 8)); + pNvRAMFunc->nvramWrite(ulTrueOffset + 3, (unsigned8) ulValue); + bNvRAMChanged=TRUE; + rtems_semaphore_release(semNvRAM); + return(RTEMS_SUCCESSFUL); +} + +void +InitializeNvRAM(void) +{ + PHEADER pNvHeader = (PHEADER)0; + rtems_status_code sc; + unsigned32 ulLength, ulOffset; + + if(ucSystemType==SYS_TYPE_PPC1) + { + if(ucBoardRevMaj<5) + { + pNvRAMFunc=&nvramDsTable; + } + else + { + pNvRAMFunc=&nvramMkTable; + } + } + else if(ucSystemType==SYS_TYPE_PPC1a) + { + pNvRAMFunc=&nvramMkTable; + } + else if(ucSystemType==SYS_TYPE_PPC4) + { + pNvRAMFunc=&nvramStk88Table; + } + else + { + pNvRAMFunc=&nvramStkTable; + } + + /* + * Set up mutex semaphore + */ + sc = rtems_semaphore_create ( + rtems_build_name ('N', 'V', 'R', 's'), + 1, + RTEMS_BINARY_SEMAPHORE | + RTEMS_INHERIT_PRIORITY | + RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &semNvRAM); + if (sc != RTEMS_SUCCESSFUL) + { + rtems_fatal_error_occurred (sc); + } + + /* + * Initially access the whole of NvRAM until we determine where the + * OS Area is located. + */ + ulPRePOSAreaLength=0xffffffff; + ulPRePOSAreaOffset=0; + + /* + * Access the header at the start of NvRAM + */ + ReadNvRAM32((unsigned32)(&pNvHeader->OSAreaLength), &ulLength); + ReadNvRAM32((unsigned32)(&pNvHeader->OSAreaAddress), &ulOffset); + + /* + * Now set limits for future accesses + */ + ulPRePOSAreaLength=ulLength; + ulPRePOSAreaOffset=ulOffset; +} + + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/prepnvr.h b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/prepnvr.h new file mode 100644 index 0000000000..cf55a4525d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/prepnvr.h @@ -0,0 +1,127 @@ +/* Structure map for NVRAM on PowerPC Reference Platform */ + +/* Revision 1 changes (8/25/94): + - Power Management (RESTART_BLOCK struct) + - Normal added to PM_MODE + - OSIRQMask (HEADER struct) */ + +/* All fields are either character/byte strings which are valid either +endian or they are big-endian numbers. + +There are a number of Date and Time fields which are in RTC format, +big-endian. These are stored in UT (GMT). + +For enum's: if given in hex then they are bit significant, i.e. only +one bit is on for each enum. +*/ + +#ifndef _NVRAM_ +#define _NVRAM_ + +#define VERSION 1 +#define REVISION 0 + +#define OSAREASIZE 1024 /* size of OSArea space */ +#define CONFSIZE 512 /* guess at size of Configuration space */ + +typedef struct _SECURITY { + unsigned long BootErrCnt; /* Count of boot password errors */ + unsigned long ConfigErrCnt; /* Count of config password errors */ + unsigned long BootErrorDT[2]; /* Date&Time from RTC of last error in pw */ + unsigned long ConfigErrorDT[2]; /* Date&Time from RTC of last error in pw */ + unsigned long BootCorrectDT[2]; /* Date&Time from RTC of last correct pw */ + unsigned long ConfigCorrectDT[2]; /* Date&Time from RTC of last correct pw */ + unsigned long BootSetDT[2]; /* Date&Time from RTC of last set of pw */ + unsigned long ConfigSetDT[2]; /* Date&Time from RTC of last set of pw */ + unsigned char Serial[16]; /* Box serial number */ + } SECURITY; + +typedef enum _OS_ID { + Unknown = 0, + Firmware = 1, + AIX = 2, + NT = 3, + WPOS2 = 4, + WPAIX = 5, + Taligent = 6, + Solaris = 7, + Netware = 8, + USL = 9, + Low_End_Client = 10, + SCO = 11 + } OS_ID; + +typedef struct _ERROR_LOG { + unsigned char ErrorLogEntry[40]; /* To be architected */ + } ERROR_LOG; + +/*---Revision 1: Change the following struct:---*/ +typedef struct _RESUME_BLOCK { + /* Hibernation Resume Device will be an + environment variable */ + unsigned long CheckSum; /* Checksum of RESUME_BLOCK */ + volatile unsigned long BootStatus; + + void * ResumeAddr; /* For Suspend Resume */ + void * SaveAreaAddr; /* For Suspend Resume */ + unsigned long SaveAreaLength; /* For Suspend Resume */ + + unsigned long HibResumeImageRBA; /* RBA (512B blocks) of compressed OS + memory image to be loaded by FW + on Resume from hibernation */ + unsigned long HibResumeImageRBACount; /* Size of image in 512B blocks*/ + unsigned long Reserved; + } RESUME_BLOCK; + +typedef enum _OSAREA_USAGE { + Empty = 0, + Used = 1 + } OSAREA_USAGE; + +typedef enum _PM_MODE { + Suspend = 0x80, /* Part of state is in memory */ + Hibernate = 0x40, /* Nothing in memory - state saved elsewhere */ +/* Revision 1: Normal added (actually was already here) */ + Normal = 0x00 /* No power management in effect */ + } PMMode; + +typedef struct _HEADER { + unsigned short Size; /* NVRAM size in K(1024) */ + unsigned char Version; /* Structure map different */ + unsigned char Revision; /* Structure map the same - + may be new values in old fields + in other words old code still works */ + unsigned short Crc1; /* check sum from beginning of nvram to OSArea */ + unsigned short Crc2; /* check sum of config */ + unsigned char LastOS; /* OS_ID */ + unsigned char Endian; /* B if big endian, L if little endian */ + unsigned char OSAreaUsage; /* OSAREA_USAGE */ + unsigned char PMMode; /* Shutdown mode */ + RESUME_BLOCK ResumeBlock; + SECURITY Security; + ERROR_LOG ErrorLog[2]; + +/* Global Environment information */ + void * GEAddress; + unsigned long GELength; + /* Date&Time from RTC of last change to Global Environment */ + unsigned long GELastWriteDT[2]; + +/* Configuration information */ + void * ConfigAddress; + unsigned long ConfigLength; + /* Date&Time from RTC of last change to Configuration */ + unsigned long ConfigLastWriteDT[2]; + unsigned long ConfigCount; /* Count of entries in Configuration */ + +/* OS dependent temp area */ + void * OSAreaAddress; + unsigned long OSAreaLength; + /* Date&Time from RTC of last change to OSAreaArea */ + unsigned long OSAreaLastWriteDT[2]; + +/* Revision 1: add this mask - function tbd */ + /*unsigned short OSIRQMask; OS to FW IRQ Mask - "I've used this one" */ + } HEADER, *PHEADER; + + #endif /* ndef _NVRAM_ */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/stk11c68.h b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/stk11c68.h new file mode 100644 index 0000000000..118662905b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/stk11c68.h @@ -0,0 +1,46 @@ +/* + * 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. + * + */ + +/* + * Definitions for the stk11C68 NvRAM + */ + +#ifndef _STK11C68_H +#define _STK11C68_H + +#include "prepnvr.h" + +/* + * STK11C68 definitions + */ +#define STK11C68_NVSIZE 8192 +#define STK11C68_GESIZE (STK11C68_NVSIZE-CONFSIZE-OSAREASIZE-sizeof(HEADER)) +#define STK11C68_BASE (PSTK11C68_NVRAM_MAP)((unsigned8 *)PCI_MEM_BASE+0x00800000) + +/* + * STK11C88 definitions + */ +#define STK11C88_NVSIZE 0x8000-sizeof(MK48T18_CMOS_MAP) + +/* Here is the whole map of the STK11C68 NVRAM */ +typedef struct _STK11C68_NVRAM_MAP { + HEADER Header; + unsigned8 GEArea[STK11C68_GESIZE]; + unsigned8 OSArea[OSAREASIZE]; + unsigned8 ConfigArea[CONFSIZE]; +} STK11C68_NVRAM_MAP, *PSTK11C68_NVRAM_MAP; + +#endif /* _STK11C68_H */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in new file mode 100644 index 0000000000..941fc1ada7 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in @@ -0,0 +1,56 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/pci.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=$(PCI_PIECES) +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +PCI_PIECES=pci + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c new file mode 100644 index 0000000000..909a568d55 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c @@ -0,0 +1,342 @@ +/* + * 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. + * + */ +#include +#include + +/* SCE 97/4/9 + * + * Use PCI configuration space access mechanism 1 + * + * This is the preferred access mechanism and must be used when accessing + * bridged PCI busses. + * + * The address to be written to the PCI_CONFIG_ADDRESS port is constructed + * thus (the representation below is little endian): + * + * 31 30 24 23 16 15 11 10 8 7 2 1 0 + * ---------------------------------------------------------------------- + * | 1 | Resvd | Bus Number | Dev Number | Fn Number | Reg Number | 0 | 0 | + * ---------------------------------------------------------------------- + * + * On bus 0, the first 'real' device is at Device number 11, the Eagle being + * device 0. On all other busses, device numbering starts at 0. + */ +/* + * Normal PCI device numbering on busses other than 0 is such that + * that the first device (0) is attached to AD16, second (1) to AD17 etc. + */ +#define CONFIG_ADDRESS(Bus, Device, Function, Offset) \ + (0x80000000 | (Bus<<16) | \ + ((Device+(((Bus==0)&&(Device>0)) ? 10 : 0))<<11) | \ + (Function<<8) | \ + (Offset&~0x03)) +#define BYTE_LANE_OFFSET(Offset) ((Offset)&0x3) + +/* + * Private data + */ +static unsigned8 ucMaxPCIBus; + +/* + * Public routines + */ +rtems_status_code PCIConfigWrite8( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned8 ucValue +) +{ + ISR_Level Irql; + + /* + * Ensure that accesses to the addr/data ports are indivisible + */ + _ISR_Disable(Irql); + + /* + * Write to the configuration space address register + */ + outport_32(PCI_CONFIG_ADDR, + CONFIG_ADDRESS(ucBusNumber, ucSlotNumber, + ucFunctionNumber, ucOffset)); + /* + * Write to the configuration space data register with the appropriate + * offset + */ + outport_byte(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), ucValue); + + _ISR_Enable(Irql); + + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code PCIConfigWrite16( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned16 usValue +) +{ + ISR_Level Irql; + + /* + * Ensure that accesses to the addr/data ports are indivisible + */ + _ISR_Disable(Irql); + + /* + * Write to the configuration space address register + */ + outport_32(PCI_CONFIG_ADDR, + CONFIG_ADDRESS(ucBusNumber, ucSlotNumber, + ucFunctionNumber, ucOffset)); + /* + * Write to the configuration space data register with the appropriate + * offset + */ + outport_16(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), usValue); + + _ISR_Enable(Irql); + + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code PCIConfigWrite32( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned32 ulValue +) +{ + ISR_Level Irql; + + /* + * Ensure that accesses to the addr/data ports are indivisible + */ + _ISR_Disable(Irql); + + /* + * Write to the configuration space address register + */ + outport_32(PCI_CONFIG_ADDR, + CONFIG_ADDRESS(ucBusNumber, ucSlotNumber, + ucFunctionNumber, ucOffset)); + /* + * Write to the configuration space data register with the appropriate + * offset + */ + outport_32(PCI_CONFIG_DATA, ulValue); + + _ISR_Enable(Irql); + + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code PCIConfigRead8( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned8 *pucValue +) +{ + ISR_Level Irql; + + /* + * Ensure that accesses to the addr/data ports are indivisible + */ + _ISR_Disable(Irql); + + /* + * Write to the configuration space address register + */ + outport_32(PCI_CONFIG_ADDR, + CONFIG_ADDRESS(ucBusNumber, ucSlotNumber, + ucFunctionNumber, ucOffset)); + /* + * Read from the configuration space data register with the appropriate + * offset + */ + inport_byte(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), *pucValue); + + _ISR_Enable(Irql); + + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code PCIConfigRead16( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned16 *pusValue +) +{ + ISR_Level Irql; + + /* + * Ensure that accesses to the addr/data ports are indivisible + */ + _ISR_Disable(Irql); + + /* + * Write to the configuration space address register + */ + outport_32(PCI_CONFIG_ADDR, + CONFIG_ADDRESS(ucBusNumber, ucSlotNumber, + ucFunctionNumber, ucOffset)); + /* + * Read from the configuration space data register with the appropriate + * offset + */ + inport_16(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), *pusValue); + + _ISR_Enable(Irql); + + return(RTEMS_SUCCESSFUL); +} + +rtems_status_code PCIConfigRead32( + unsigned8 ucBusNumber, + unsigned8 ucSlotNumber, + unsigned8 ucFunctionNumber, + unsigned8 ucOffset, + unsigned32 *pulValue +) +{ + ISR_Level Irql; + + /* + * Ensure that accesses to the addr/data ports are indivisible + */ + _ISR_Disable(Irql); + + /* + * Write to the configuration space address register + */ + outport_32(PCI_CONFIG_ADDR, + CONFIG_ADDRESS(ucBusNumber, ucSlotNumber, + ucFunctionNumber, ucOffset)); + /* + * Read from the configuration space data register with the appropriate + * offset + */ + inport_32(PCI_CONFIG_DATA, *pulValue); + + _ISR_Enable(Irql); + + return(RTEMS_SUCCESSFUL); +} + +/* + * This routine determines the maximum bus number in the system + */ +void InitializePCI() +{ + unsigned8 ucSlotNumber, ucFnNumber, ucNumFuncs; + unsigned8 ucHeader; + unsigned8 ucBaseClass, ucSubClass, ucMaxSubordinate; + unsigned32 ulDeviceID; + + /* + * Scan PCI bus 0 looking for PCI-PCI bridges + */ + for(ucSlotNumber=0;ucSlotNumberucMaxPCIBus) + { + ucMaxPCIBus=ucMaxSubordinate; + } + } + } + } +} + +/* + * Return the number of PCI busses in the system + */ +unsigned8 BusCountPCI() +{ + return(ucMaxPCIBus+1); +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/start/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/start/Makefile.in new file mode 100644 index 0000000000..3e7884433a --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/start/Makefile.in @@ -0,0 +1,54 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/start.o + +# C source names, if any, go here -- minus the .c +C_PIECES= +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +S_PIECES=start +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) $(OBJS) $(PGM) + $(INSTALL_VARIANT) -m 555 ${PGM} ${PROJECT_RELEASE}/lib diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/start/start.S b/c/src/lib/libbsp/powerpc/ppcn_60x/start/start.S new file mode 100644 index 0000000000..a8dc4cb3b0 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/start/start.S @@ -0,0 +1,153 @@ +/* + * 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. + * + * $Id$ + */ +#include +#include "ppc-asm.h" +#include "bsp.h" + + .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 _start + .type _start,@function +_start: + /* Set MSR */ + /* + * Enable data and instruction address translation and floating point + */ + li r3,MSR_IR | MSR_DR | MSR_FP + mtmsr r3 + + /* + * The caches are already flushed by the firmware so just enable + */ + mfspr r3,HID0 +#if PPC_USE_DATA_CACHE + /* + * Enable data and instruction cache + */ + ori r3,r3 ,H0_60X_ICE | H0_60X_DCE +#else + /* + * Enable instruction cache only + */ + ori r3,r3 ,H0_60X_ICE +#endif + mtspr HID0,r3 + + /* 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 */ + + li r3, 0 /* argc */ + li r4, 0 /* argv */ + li r5, 0 /* environp */ + + /* 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 diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/Makefile.in new file mode 100644 index 0000000000..25464864d2 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/Makefile.in @@ -0,0 +1,62 @@ +# +# $Id: +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@:@srcdir@/../../../shared +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/startup.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=$(STARTUP_PIECES) +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +S_PIECES=bsptrap +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=linkcmds $(C_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# Files expected to be from the shared directory: +# sbrk main bsplibc bsppost +STARTUP_PIECES=bspstart bspclean sbrk setvec spurious genpvec swap \ + main bsplibc bsppost + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + $(INSTALL) $(srcdir)/linkcmds ${PROJECT_RELEASE}/lib diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspclean.c b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspclean.c new file mode 100644 index 0000000000..7a5db77049 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspclean.c @@ -0,0 +1,30 @@ +/* + * 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. + * + */ +/* + * bsp_cleanup() + */ + +#include +#include + +extern void bsp_trap(); + +void bsp_cleanup( void ) +{ +#if PPCN_60X_USE_DINK + bsp_trap(); +#endif +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspstart.c b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspstart.c new file mode 100644 index 0000000000..e8ecd15472 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bspstart.c @@ -0,0 +1,305 @@ +/* + * 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. + * + */ +/* bspstart.c + * + * This set of routines starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before any of these are invoked. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id: + */ + +#include +#include +#include + +#include + +unsigned char ucSystemType; +unsigned char ucBoardRevMaj; +unsigned char ucBoardRevMin; +unsigned long ulMemorySize; +unsigned long ulCpuBusClock; + +/* + * The bus speed is expressed in MHz + */ +static unsigned long ulBusSpeed[] = { + 56250000, + 60000000, + 64300000, + 66666667, + 75000000, + 83333333, + 100000000, + 66666667 +}; + +/* + * 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; +rtems_unsigned32 bsp_isr_level; + +static int stdin_fd, stdout_fd, stderr_fd; + +/* + * End of RTEMs image imported from linker + */ +extern int end; + +/* + * Use the shared implementations of the following routines + */ + +void bsp_postdriver_hook(void); +void bsp_libc_init( void *, unsigned32, int ); + +/* + * bsp_pretasking_hook + * + * BSP pretasking hook. Called just before drivers are initialized. + * Used to setup libc and install any BSP extensions. + */ + +void bsp_pretasking_hook(void) +{ + rtems_unsigned32 heap_start; + rtems_unsigned32 heap_size; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + heap_size = BSP_Configuration.work_space_start - (void *)&end; + heap_size &= 0xfffffff0; /* keep it as a multiple of 16 bytes */ + + bsp_libc_init((void *) heap_start, heap_size, 0); + + /* + * Initialise RTC hooks based on system type + */ + InitializeRTC(); + + /* + * Initialise NvRAM hooks based on system type + */ + InitializeNvRAM(); + + /* + * Initialise the PCI bus(ses) + */ + InitializePCI(); + + /* + * Initialize the Universe PCI-VME bridge + */ + InitializeUniverse(); + + +#ifdef RTEMS_DEBUG + rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); +#endif + +} + +/* + * bsp_std_close + * + * Simple routine to close all standard IO streams. + */ + +void bsp_std_close( void ) +{ + close(stdin_fd); + close(stdout_fd); + close(stderr_fd); +} + + +/* + * bsp_predriver_hook + * + * Before drivers are setup. + */ +void bsp_predriver_hook(void) +{ + /* bsp_spurious_initialize; ??*/ + initialize_external_exception_vector(); +} + +/* + * bsp_start + * + * This routine does the bulk of the system initialization. + */ + +void bsp_start( void ) +{ + unsigned char *work_space_start; + unsigned char ucBoardRev, ucMothMemType, ucEquipPres1, ucEquipPres2; + unsigned16 usPVR=0; + unsigned8 ucTempl, ucTemph; + unsigned8 ucBanksPresent; + unsigned8 ucSimmPresent; + unsigned32 ulCurBank, ulTopBank; + + /* + * Determine system type + */ + inport_byte(&((PPLANARREGISTERS)0)->MotherboardMemoryType, ucMothMemType); + inport_byte(&((PPLANARREGISTERS)0)->SimmPresent, ucSimmPresent); + + inport_byte(&((PPLANARREGISTERS)0)->EquipmentPresent1, ucEquipPres1); + inport_byte(&((PPLANARREGISTERS)0)->EquipmentPresent2, ucEquipPres2); + ucSystemType=((ucMothMemType&0x03)<<1) | ((ucEquipPres1&0x80)>>7); + ucSystemType^=7; + + /* + * Determine board revision for use by rev. specific code + */ + inport_byte(&((PPLANARREGISTERS)0)->BoardRevision, ucBoardRev); + ucBoardRevMaj=ucBoardRev>>5; + ucBoardRevMin=ucBoardRev&0x1f; + + /* + * Determine the memory size by reading the end address for top + * assigned bank in the memory controller + */ + (void)PCIConfigRead8(0,0,0,0xa0, &ucBanksPresent); + for(ulCurBank=0;ulCurBank<8;ulCurBank++) + { + if((ucBanksPresent>>ulCurBank)&0x01) + { + ulTopBank=ulCurBank; + } + } + + (void)PCIConfigRead8(0,0,0,0x90+ulTopBank, &ucTempl); + (void)PCIConfigRead8(0,0,0,0x98+ulTopBank, &ucTemph); + ulMemorySize=(ucTempl+(ucTemph<<8)+1)<<20; +#if PPCN_60X_USE_DINK + ulMemorySize=0x01fe0000; +#endif + + /* + * Determine processor bus clock + */ + asm volatile ("mfpvr %0" : "=r" ((usPVR)) : "0" ((usPVR))); + + /* + * Determine processor internal clock + */ + if(ucSystemType==SYS_TYPE_PPC4) + { + if(((ucBoardRevMaj==1) && (ucBoardRevMin==0)) || + ((ucSimmPresent&0x40)==0)) + { + /* + * Rev. 1A is always 66MHz + */ + ulCpuBusClock=66666667; + } + else + { + ulCpuBusClock=83333333; + } + } + else if((((usPVR>>16)==MPC603e) && (ucSystemType!=SYS_TYPE_PPC1)) || + ((usPVR>>16)==MPC603ev) || + ((usPVR>>16)==MPC604e)) + { + ulCpuBusClock=ulBusSpeed[(ucEquipPres2&0x1c)>>2]; + } + else + { + if(((ucSystemType>SYS_TYPE_PPC1) || (ucBoardRevMaj>=5)) && + (ucEquipPres1&0x08)) + { + /* + * 66 MHz bus clock for 005 if indicated + */ + ulCpuBusClock=66666667; + } + else + { + /* + * 33 MHz bus clock for 004 always + */ + ulCpuBusClock=33333333; + } + } + + + /* + * Allocate the memory for the RTEMS Work Space. This can come from + * a variety of places: hard coded address, malloc'ed from outside + * RTEMS world (e.g. simulator or primitive memory manager), or (as + * typically done by stock BSPs) by subtracting the required amount + * of work space from the last physical address on the CPU board. + */ + + work_space_start = + (unsigned char *)ulMemorySize - BSP_Configuration.work_space_size; + + if ( work_space_start <= (unsigned char *)&end ) { + DEBUG_puts( "bspstart: Not enough RAM!!!\n" ); + bsp_cleanup(); + } + + BSP_Configuration.work_space_start = work_space_start; + + /* + * Add 1 region for RTEMS Malloc + */ + + BSP_Configuration.RTEMS_api_configuration->maximum_regions++; + + /* + * Account for the console's resources + */ + + console_reserve_resources( &BSP_Configuration ); + + /* + * initialize the CPU table for this BSP + */ + + Cpu_table.exceptions_in_RAM = TRUE; + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + Cpu_table.predriver_hook = bsp_predriver_hook; + Cpu_table.postdriver_hook = bsp_postdriver_hook; + Cpu_table.do_zero_of_workspace = TRUE; + Cpu_table.interrupt_stack_size = (32 * 1024); + Cpu_table.clicks_per_usec = ulCpuBusClock/4000000; + + +} + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bsptrap.S b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bsptrap.S new file mode 100644 index 0000000000..3c6a4c16d4 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/bsptrap.S @@ -0,0 +1,25 @@ +/* + * (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. + * + */ +#include +#include "ppc-asm.h" + + .file "bsptrap.s" + .text +FUNC_START(bsp_trap) + sc +FUNC_END(bsp_trap) diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c new file mode 100644 index 0000000000..d4b8f46274 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c @@ -0,0 +1,355 @@ +/* + * 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. + * + */ +/* genpvec.c + * + * These routines handle the external exception. Multiple ISRs occur off + * of this one interrupt. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id: + */ + +#include +#include "chain.h" +#include + +/* + * Proto types for this file + */ + +rtems_isr external_exception_ISR ( + rtems_vector_number vector /* IN */ +); + +#define NUM_LIRQ_HANDLERS 20 +#define NUM_LIRQ ( MAX_BOARD_IRQS - PPC_IRQ_LAST ) + +/* + * Current 8259 masks + */ +unsigned8 ucMaster8259Mask; +unsigned8 ucSlave8259Mask; + +/* + * Structure to for one of possible multiple interrupt handlers for + * a given interrupt. + */ +typedef struct +{ + Chain_Node Node; + rtems_isr_entry handler; /* isr routine */ + rtems_vector_number vector; /* vector number */ +} EE_ISR_Type; + + +/* Note: The following will not work if we add a method to remove + * handlers at a later time. + */ + EE_ISR_Type ISR_Nodes [NUM_LIRQ_HANDLERS]; + rtems_unsigned16 Nodes_Used; + Chain_Control ISR_Array [NUM_LIRQ]; + +void initialize_external_exception_vector() +{ + rtems_isr_entry previous_isr; + rtems_status_code status; + int i; + + Nodes_Used = 0; + + for (i=0; i handler)( node->vector ); + node = (EE_ISR_Type *)node->Node.next; + } + + /* + * Dismiss the interrupt + */ + if(index&8) + { + /* + * Dismiss the interrupt in Slave first as it + * is cascaded + */ + outport_byte(ISA8259_S_CTRL, NONSPECIFIC_EOI); + } + + /* + * Dismiss the interrupt in Master + */ + outport_byte(ISA8259_M_CTRL, NONSPECIFIC_EOI); +} + +void Dis_Ext_Interrupt(int level) +{ + ISR_Level Irql; + + level-=PPCN_60X_8259_IRQ_BASE; + + if(level==2) + { + /* + * Level 2 is for cascade and must not be fiddled with + */ + return; + } + + /* + * Ensure that accesses to the mask are indivisible + */ + _ISR_Disable(Irql); + + if(level<8) + { + /* + * Interrupt is handled by Master + */ + ucMaster8259Mask|=1<> + * + * rtems_init_executive_late() + * bsp_cleanup() + * + * TODO: + * + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id: + */ + +#include + +/* + * RTEMS program name + * Probably not used by anyone, but it is nice to have it. + * Actually the UNIX version of CPU_INVOKE_DEBUGGER will probably + * need to use it + */ + +char *rtems_progname; +char **rtems_environp; + +#ifdef USE_CONSTRUCTORS_FOR_INIT_EXEC + +class RTEMS { + public: + RTEMS(); + ~RTEMS(); +}; + +RTEMS rtems_constructor; + +RTEMS::RTEMS() +{ + bsp_start(); +} + +RTEMS::~RTEMS() +{ + bsp_cleanup(); +} +#endif + +extern "C" { + int + main(int argc, + char **argv, + char **environp) + { + +#ifndef USE_CONSTRUCTORS_FOR_INIT_EXEC + bsp_start(); +#endif + + if ((argc > 0) && argv && argv[0]) + rtems_progname = argv[0]; + else + rtems_progname = "RTEMS"; + + rtems_environp = environp; + + /* + * Start multitasking + */ + rtems_initialize_executive_late( bsp_isr_level ); + +#ifndef USE_CONSTRUCTORS_FOR_INIT_EXEC + bsp_cleanup(); +#endif + + /* + * Returns when multitasking is stopped + * This allows our destructors to get run normally + */ + + return 0; + } +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/setvec.c b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/setvec.c new file mode 100644 index 0000000000..dd7c39da82 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/setvec.c @@ -0,0 +1,55 @@ +/* set_vector + * + * This routine installs an interrupt vector on the target Board/CPU. + * This routine is allowed to be as board dependent as necessary. + * + * INPUT: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * RETURNS: + * address of previous interrupt handler + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id: + */ + +#include +#include + + +/* + * This routine installs vector number vector. + * + */ +rtems_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + rtems_isr_entry previous_isr; + rtems_status_code status; + + /* + * vectors greater than PPC_IRQ_LAST are handled by the General purpose + * interupt handler. (8259) + */ + if ( vector > PPC_IRQ_LAST ) { + set_EE_vector ( handler, vector ); + } + else { + status = rtems_interrupt_catch + ( handler, vector, (rtems_isr_entry *) &previous_isr ); + } + return previous_isr; +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/spurious.c b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/spurious.c new file mode 100644 index 0000000000..af18752c71 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/spurious.c @@ -0,0 +1,202 @@ +/* + * PPCn_60x Spurious Trap Handler + * + * This is just enough of a trap handler to let us know what + * the likely source of the trap was. + * + * Based upon the SPARC ERC32 version which was developed as + * part of the port of RTEMS to the ERC32 implementation + * of the SPARC by On-Line Applications Research Corporation (OAR) + * under contract to the European Space Agency (ESA). + * + * COPYRIGHT (c) 1995. European Space Agency. + * + * This terms of the RTEMS license apply to this file. + * + * $Id$ + */ + +#include + +#include + +static const char digits[16] = "0123456789abcdef"; + +rtems_isr bsp_stub_handler( + rtems_vector_number trap +) +{ +} + +/* + * bsp_spurious_handler + * + * Print a message on the debug console and then die + */ +rtems_isr bsp_spurious_handler( + rtems_vector_number trap +) +{ + + + + DEBUG_puts( "Spurious Trap" ); + + switch ( trap ) { + case PPC_IRQ_SYSTEM_RESET: + DEBUG_puts( "System reset" ); + break; + case PPC_IRQ_MCHECK: + DEBUG_puts( "Machine check" ); + break; + case PPC_IRQ_PROTECT: + DEBUG_puts( "DSI" ); + break; + case PPC_IRQ_ISI: + DEBUG_puts( "ISI" ); + break; + case PPC_IRQ_EXTERNAL: + DEBUG_puts( "External interupt" ); + break; + case PPC_IRQ_ALIGNMENT: + DEBUG_puts( "Alignment Exception" ); + break; + case PPC_IRQ_PROGRAM: + DEBUG_puts( "Program" ); + break; + case PPC_IRQ_NOFP: + DEBUG_puts( "Floating point unavailable" ); + break; + case PPC_IRQ_DECREMENTER: + DEBUG_puts( "Decrementer" ); + break; + case PPC_IRQ_RESERVED_A: + DEBUG_puts( "Reserved 0x00a00" ); + break; + case PPC_IRQ_RESERVED_B: + DEBUG_puts( "Reserved 0x00b00" ); + break; + case PPC_IRQ_SCALL: + DEBUG_puts( "System call" ); + break; + case PPC_IRQ_TRACE: + DEBUG_puts( "Trace" ); + break; + case PPC_IRQ_FP_ASST: + DEBUG_puts( "Floating point Assist" ); + break; + +#if defined(ppc403) +#error "Please fill in names. " + case PPC_IRQ_CRIT : + DEBUG_puts( "Critical Error "); + break; + case PPC_IRQ_PIT: + DEBUG_puts( "0x01000" ); + break; + case PPC_IRQ_FIT: + DEBUG_puts( "0x01010" ); + break; + case PPC_IRQ_WATCHDOG : + DEBUG_puts( "0x01020" ); + break; + case PPC_IRQ_DEBUG : + DEBUG_puts( "0x02000" ); + break; + +#elif defined(ppc601) +#error "Please fill in names. " + case PPC_IRQ_TRACE : + DEBUG_puts( "0x02000" ); + break; + +#elif defined(ppc603) +#error "Please fill in names. " + case PPC_IRQ_TRANS_MISS : + DEBUG_puts( "0x1000" ); + break; + case PPC_IRQ_DATA_LOAD: + DEBUG_puts( "0x1100" ); + break; + case PPC_IRQ_DATA_STORE: + DEBUG_puts( "0x1200" ); + break; + case PPC_IRQ_ADDR_BRK: + DEBUG_puts( "0x1300" ); + break; + case PPC_IRQ_SYS_MGT: + DEBUG_puts( "0x1400" ); + break; + +#elif defined(ppc603e) + case PPC_TLB_INST_MISS: + DEBUG_puts( "Instruction Translation Miss" ); + break; + case PPC_TLB_LOAD_MISS: + DEBUG_puts( "Data Load Translation Miss" ); + break; + case PPC_TLB_STORE_MISS : + DEBUG_puts( "Data store Translation Miss"); + break; + case PPC_IRQ_ADDRBRK: + DEBUG_puts( "Instruction address break point" ); + break; + case PPC_IRQ_SYS_MGT: + DEBUG_puts( "System management interrupt" ); + break; + +#elif defined(ppc604) +#error "Please fill in names. " + case PPC_IRQ_ADDR_BRK: + DEBUG_puts( "0x1300" ); + break; + case PPC_IRQ_SYS_MGT: + DEBUG_puts( "0x1400" ); + break; +#endif + + default: + DEBUG_puts( "Undefined exception " ); + break; + } + + /* + * What else can we do but stop ... + */ + /* + asm volatile( "" ); + */ +} + +/* + * bsp_spurious_initialize + * + * Install the spurious handler for most traps. + */ + +void bsp_spurious_initialize() +{ + rtems_unsigned32 trap; + + for ( trap=0 ; trap < PPC_IRQ_LAST ; trap++ ) { + + /* + * Skip window overflow, underflow, and flush as well as software + * trap 0 which we will use as a shutdown. + */ + + set_vector( bsp_spurious_handler, trap, 1 ); + } + + set_vector( bsp_stub_handler, PPC_IRQ_DECREMENTER, 1 ); + set_vector( bsp_stub_handler, PPC_IRQ_TRACE, 1 ); + set_vector( bsp_stub_handler, PPC_IRQ_SYS_MGT, 1 ); +} + + + + + + + + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/swap.c b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/swap.c new file mode 100644 index 0000000000..58b3e13dbb --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/swap.c @@ -0,0 +1,64 @@ +/* + * 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. + * + */ + +#include + +/* + * JRS - February 20, 1998 + * + * There is a swap32 in each port. So this should be removed. + * + * Adding a swap16 to the port would be useful. + * + * The end of all this would be to remove this file. + */ + +inline unsigned int Swap32( + unsigned32 ulValue +) +{ + unsigned32 ulSwapped; + + asm volatile( + "rlwimi %0,%1,8,24,31;" + "rlwimi %0,%1,24,16,23;" + "rlwimi %0,%1,8,8,15;" + "rlwimi %0,%1,24,0,7;" : + + "=&r" ((ulSwapped)) : + "r" ((ulValue)) + ); + + return( ulSwapped ); +} + +inline unsigned int Swap16( + unsigned16 usValue +) +{ + unsigned16 usSwapped; + + asm volatile( + "rlwimi %0,%1,24,24,31;" + "rlwimi %0,%1,8,16,23;" : + + "=&r" ((usSwapped)) : + "r" ((usValue)) + ); + + return( usSwapped ); +} + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/timer/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/timer/Makefile.in new file mode 100644 index 0000000000..16665e4de9 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/timer/Makefile.in @@ -0,0 +1,59 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/timer.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=timer +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES= +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/timer/timer.c b/c/src/lib/libbsp/powerpc/ppcn_60x/timer/timer.c new file mode 100644 index 0000000000..c96587a233 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/timer/timer.c @@ -0,0 +1,82 @@ +/* timer.c + * + * This file implements a benchmark timer using the General Purpose Timer. + * + * Notes: + * + * BSP_TIMER_AVG_OVERHEAD and BSP_TIMER_LEAST_VALID are required to be + * provided in bsp.h + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +#include + +rtems_unsigned64 Timer_driver_Start_time; + +rtems_boolean Timer_driver_Find_average_overhead; + +/* + * Timer_initialize + */ +void Timer_initialize() +{ + + /* + * Timer runs long and accurate enough not to require an interrupt. + */ + + Timer_driver_Start_time = PPC_Get_timebase_register(); +} + +/* + * Read_timer + */ +int Read_timer() +{ + rtems_unsigned64 clicks; + rtems_unsigned64 total64; + rtems_unsigned32 total; + + /* approximately CLOCK_SPEED clicks per microsecond */ + + clicks = PPC_Get_timebase_register(); + + assert( clicks > Timer_driver_Start_time ); + + total64 = clicks - Timer_driver_Start_time; + + assert( total64 <= 0xffffffff ); /* fits into a unsigned32 */ + + total = (rtems_unsigned32) total64; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in "clicks" of the decrementer units */ + + if ( total < BSP_TIMER_LEAST_VALID ) + return 0; /* below timer resolution */ + + return BSP_Convert_decrementer(total - BSP_TIMER_AVG_OVERHEAD); +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/tod/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/tod/Makefile.in new file mode 100644 index 0000000000..240373136e --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/tod/Makefile.in @@ -0,0 +1,56 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/tod.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=$(TOD_PIECES) +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +TOD_PIECES=tod + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/tod/cmos.h b/c/src/lib/libbsp/powerpc/ppcn_60x/tod/cmos.h new file mode 100644 index 0000000000..92cd7813a8 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/tod/cmos.h @@ -0,0 +1,95 @@ +/* Structure map for CMOS on PowerPC Reference Platform */ +/* + * 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. + * + */ +/* CMOS is the 64 bytes of RAM in the DS1385 chip */ +/* The CRC's are computed with x**16+x**12+x**5 + 1 polynomial */ +/* The clock is kept in 24 hour BCD mode and should be set to UT(GMT) */ + +#ifndef _CMOS_ +#define _CMOS_ + +/* + * Address port is at 0x70, data at 0x71 + */ +#define RTC_PORT 0x70 + +/* Define Realtime Clock register numbers. */ + +#define RTC_SECOND 0 /* second of minute [0..59] */ +#define RTC_SECOND_ALARM 1 /* seconds to alarm */ +#define RTC_MINUTE 2 /* minute of hour [0..59] */ +#define RTC_MINUTE_ALARM 3 /* minutes to alarm */ +#define RTC_HOUR 4 /* hour of day [0..23] */ +#define RTC_HOUR_ALARM 5 /* hours to alarm */ +#define RTC_DAY_OF_WEEK 6 /* day of week [1..7] */ +#define RTC_DAY_OF_MONTH 7 /* day of month [1..31] */ +#define RTC_MONTH 8 /* month of year [1..12] */ +#define RTC_YEAR 9 /* year [00..99] */ +#define RTC_CONTROL_REGISTERA 10 /* control register A */ +#define RTC_CONTROL_REGISTERB 11 /* control register B */ +#define RTC_CONTROL_REGISTERC 12 /* control register C */ +#define RTC_CONTROL_REGISTERD 13 /* control register D */ +#define RTC_BATTERY_BACKED_UP_RAM 14 /* battery backed up RAM [0..49] */ + +/* Define Control Register A structure. */ +#define DS1385_REGA_UIP 0x80 + +/* Define Control Register B structure. */ +#define DS1385_REGB_SET_TIME 0x80 +#define DS1385_REGB_TIM_IRQ_EN 0x40 +#define DS1385_REGB_ALM_IRQ_EN 0x20 +#define DS1385_REGB_UPD_IRQ_EN 0x10 +#define DS1385_REGB_SQR_EN 0x08 +#define DS1385_REGB_DATA_M 0x04 +#define DS1385_REGB_HOURS_FMT 0x02 +#define DS1385_REGB_DLS_EN 0x01 + +/* Define Control Register C structure. */ +#define DS1385_REGC_IRQ_REQ 0x08 +#define DS1385_REGC_IRQ_TIME 0x04 +#define DS1385_REGC_IRQ_ALM 0x02 +#define DS1385_REGC_IRQ_UPD 0x01 + +/* Define Control Register D structure. */ +#define DS1385_REGD_VALID 0x80 + +typedef struct _CMOS_MAP { + volatile rtems_unsigned8 DateAndTime[14]; + + rtems_unsigned8 SystemDependentArea1[2]; + rtems_unsigned8 SystemDependentArea2[8]; + rtems_unsigned8 FeatureByte0[1]; + rtems_unsigned8 FeatureByte1[1]; /* 19 = PW Flag; + attribute = write protect */ + rtems_unsigned8 Century[1]; /* century byte in BCD, e.g. 0x19 currently */ + rtems_unsigned8 FeatureByte3[1]; + rtems_unsigned8 FeatureByte4[1]; + rtems_unsigned8 FeatureByte5[1]; + rtems_unsigned8 FeatureByte6[1]; + rtems_unsigned8 FeatureByte7[1]; /* 1F = Alternate PW Flag; + attribute = write protect */ + rtems_unsigned8 BootPW[14]; /* Power-on password needed to boot system; + reset value = 0x00000000000000005a5a5a5a5a5a); + attribute = lock */ + rtems_unsigned8 BootCrc[2]; /* CRC on BootPW */ + rtems_unsigned8 ConfigPW[14]; /* Configuration Password needed to + change configuration of system; + reset value = 0x00000000000000005a5a5a5a5a5a); + attribute = lock */ + rtems_unsigned8 ConfigCrc[2]; /* CRC on ConfigPW */ +} CMOS_MAP, *PCMOS_MAP; + +#endif /* _CMOS_ */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/tod/tod.c b/c/src/lib/libbsp/powerpc/ppcn_60x/tod/tod.c new file mode 100644 index 0000000000..80e0ff3116 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/tod/tod.c @@ -0,0 +1,617 @@ +/* + * 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. + * + */ + +#define MIN_YEAR 1996 + +#include +#include "bsp.h" +#include "cmos.h" +#include "../nvram/mk48t18.h" + +#define Bin2BCD(Value) (((Value / 10) << 4) | (Value % 10)) +#define BCD2Bin(BcdValue) ((BcdValue >> 4) * 10 + (BcdValue & 0x0f)) + +/* + * Private types + */ +typedef +void +(*PTIMESET) +( + rtems_time_of_day *pTOD +); + +typedef +boolean +(*PTIMEGET) +( + rtems_time_of_day *pTOD +); + +typedef struct _TIME_ENTRY_TABLE +{ + PTIMESET SetTime; + PTIMEGET GetTime; +} TIME_ENTRY_TABLE, *PTIME_ENTRY_TABLE; + +/* + * Private routines + */ + +/* + * DS1385 specific routines + */ +static void timeDsSet(rtems_time_of_day *pTOD); +static boolean timeDsGet(rtems_time_of_day *pTOD); + +/* + * MK48T18 specific routines + */ +static void timeMkSet(rtems_time_of_day *pTOD); +static boolean timeMkGet(rtems_time_of_day *pTOD); + +TIME_ENTRY_TABLE timeDsTable = +{ + timeDsSet, + timeDsGet +}; + +TIME_ENTRY_TABLE timeMkTable = +{ + timeMkSet, + timeMkGet +}; + +/* + * Private variables + */ +static PTIME_ENTRY_TABLE pTimeFunc; + +/* + * Mutual-exclusion semaphore + */ +static rtems_id semRTC; + +/* + * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) + */ +rtems_unsigned8 +GregorianDay(rtems_time_of_day *pTOD) +{ + boolean isLeap; + unsigned long leapsToDate; + unsigned long lastYear; + unsigned long day; + unsigned long MonthOffset[] = { 0, 31, 59, 90, 120, 151, + 181, 212, 243, 273, 304, 334 }; + + lastYear=pTOD->year-1; + + /* + * Number of leap corrections to apply up to end of last year + */ + leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; + + /* + * This year is a leap year if it is divisible by 4 except when it is + * divisible by 100 unless it is divisible by 400 + * + * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be + */ + isLeap = (pTOD->year%4==0) && + ((pTOD->year%100!=0) || (pTOD->year%400==0)); + + if(isLeap && (pTOD->month>2)) + { + day=1; + } + else + { + day=0; + } + + day += lastYear*365 + leapsToDate + MonthOffset[pTOD->month-1] + + pTOD->day; + + return((rtems_unsigned8)(day%7)); +} + +void +DsWriteRawClockRegister ( + rtems_unsigned8 Register, + rtems_unsigned8 Value +) + +/*++ + +Routine Description: + + This routine reads the specified realtime clock register. + + This function was added to bridge the BCD format of the IBM roms + and the binary formate of NT + + +Arguments: + + Register - Supplies the number of the register whose value is read. + +Return Value: + + The value of the register is returned as the function value. + +--*/ + +{ + outport_byte((rtems_unsigned8 *)RTC_PORT, Register & 0x7f); + + /* Read the realtime clock register value. */ + + outport_byte((rtems_unsigned8 *)(RTC_PORT + 1), Value); + return; +} + +rtems_unsigned8 +DsReadRawClockRegister ( + rtems_unsigned8 Register +) + +/*++ + +Routine Description: + + This routine reads the specified realtime clock register. + + This function was added to bridge the BCD format of the IBM roms + and the binary formate of NT + + +Arguments: + + Register - Supplies the number of the register whose value is read. + +Return Value: + + The value of the register is returned as the function value. + +--*/ + +{ + rtems_unsigned8 ucDataByte; + + outport_byte((rtems_unsigned8 *)RTC_PORT, Register & 0x7f); + + /* Read the realtime clock register value. */ + + inport_byte((rtems_unsigned8 *)(RTC_PORT + 1), ucDataByte); + return ucDataByte; +} + +void +DsWriteClockRegister ( + rtems_unsigned8 Register, + rtems_unsigned8 Value +) + +/*++ + +Routine Description: + + This routine writes the specified value to the specified realtime + clock register. + +Arguments: + + Register - Supplies the number of the register whose value is written. + + Value - Supplies the value that is written to the specified register. + +Return Value: + + The value of the register is returned as the function value. + +--*/ + +{ + rtems_unsigned8 BcdValue; + + BcdValue = Bin2BCD(Value); + DsWriteRawClockRegister(Register, BcdValue); + return; +} + +rtems_unsigned8 +DsReadClockRegister ( + rtems_unsigned8 Register +) + +/*++ + +Routine Description: + + This routine reads the specified realtime clock register. + +Arguments: + + Register - Supplies the number of the register whose value is read. + +Return Value: + + The value of the register is returned as the function value. + +--*/ + +{ + rtems_unsigned8 BcdValue; + + BcdValue = DsReadRawClockRegister(Register); + return BCD2Bin(BcdValue); +} + +void +timeDsSet ( + rtems_time_of_day *pTOD + ) + +/*++ + +Routine Description: + + This routine sets the realtime clock. + + N.B. This routine assumes that the caller has provided any required + synchronization to set the realtime clock information. + +Arguments: + + pTOD - Supplies a pointer to a time structure that specifies the + realtime clock information. + +Return Value: + + If the power to the realtime clock has not failed, then the time + values are written to the realtime clock and a value of TRUE is + returned. Otherwise, a value of FALSE is returned. + +--*/ + +{ + rtems_unsigned8 ucDataByte; + PCMOS_MAP pCMOS = (PCMOS_MAP)0; + + /* If the realtime clock battery is still functioning, then write */ + /* the realtime clock values, and return a function value of TRUE. */ + /* Otherwise, return a function value of FALSE. */ + + ucDataByte = DsReadRawClockRegister(RTC_CONTROL_REGISTERD); + if (ucDataByte&DS1385_REGD_VALID) + { + /* Set the realtime clock control to set the time. */ + + ucDataByte = DS1385_REGB_HOURS_FMT | DS1385_REGB_SET_TIME; + DsWriteRawClockRegister(RTC_CONTROL_REGISTERB, ucDataByte); + + /* Write the realtime clock values. */ + + DsWriteClockRegister(RTC_YEAR, + (rtems_unsigned8)(pTOD->year%100)); + if(pTOD->year>=100) + { + DsWriteClockRegister((rtems_unsigned8) + ((unsigned long)&pCMOS->Century), + pTOD->year/100); + } + DsWriteClockRegister(RTC_MONTH, + (rtems_unsigned8)pTOD->month); + DsWriteClockRegister(RTC_DAY_OF_MONTH, + (rtems_unsigned8)pTOD->day); + DsWriteClockRegister(RTC_DAY_OF_WEEK, + (rtems_unsigned8) + (GregorianDay(pTOD) + 1)); + DsWriteClockRegister(RTC_HOUR, + (rtems_unsigned8)pTOD->hour); + DsWriteClockRegister(RTC_MINUTE, + (rtems_unsigned8)pTOD->minute); + DsWriteClockRegister(RTC_SECOND, + (rtems_unsigned8)pTOD->second); + + /* Set the realtime clock control to update the time. */ + + ucDataByte &= ~DS1385_REGB_SET_TIME; + DsWriteRawClockRegister(RTC_CONTROL_REGISTERB, ucDataByte); + return; + + } + else + { + return; + } +} + +boolean +timeDsGet ( + rtems_time_of_day *pTOD + ) + +/*++ + +Routine Description: + + This routine queries the realtime clock. + +Arguments: + + pTOD - Supplies a pointer to a time structure that receives + the realtime clock information. + +Return Value: + + If the power to the realtime clock has not failed, then the time + values are read from the realtime clock and a value of TRUE is + returned. Otherwise, a value of FALSE is returned. + +--*/ + +{ + rtems_unsigned8 ucDataByte; + PCMOS_MAP pCMOS = (PCMOS_MAP)0; + + /* If the realtime clock battery is still functioning, then read */ + /* the realtime clock values, and return a function value of TRUE. */ + /* Otherwise, return a function value of FALSE. */ + + ucDataByte = DsReadRawClockRegister(RTC_CONTROL_REGISTERD); + if(ucDataByte&DS1385_REGD_VALID) + { + /* Wait until the realtime clock is not being updated. */ + + do + { + ucDataByte=DsReadRawClockRegister(RTC_CONTROL_REGISTERA); + } while (ucDataByte&DS1385_REGA_UIP); + + /* Read the realtime clock values. */ + + pTOD->year=(rtems_unsigned16) + (DsReadClockRegister( + (rtems_unsigned8) + (unsigned long)&pCMOS->Century) + *100 + DsReadClockRegister(RTC_YEAR)); + pTOD->month=DsReadClockRegister(RTC_MONTH); + pTOD->day=DsReadClockRegister(RTC_DAY_OF_MONTH); + pTOD->hour=DsReadClockRegister(RTC_HOUR); + pTOD->minute=DsReadClockRegister(RTC_MINUTE); + pTOD->second=DsReadClockRegister(RTC_SECOND); + return TRUE; + } + else + { + return FALSE; + } +} + +void +timeMkSet ( + rtems_time_of_day *pTOD + ) + +/*++ + +Routine Description: + + This routine sets the realtime clock. + + N.B. This routine assumes that the caller has provided any required + synchronization to set the realtime clock information. + +Arguments: + + pTOD - Supplies a pointer to a time structure that specifies the + realtime clock information. + +Return Value: + + If the power to the realtime clock has not failed, then the time + values are written to the realtime clock and a value of TRUE is + returned. Otherwise, a value of FALSE is returned. + +--*/ + +{ + PMK48T18_NVRAM_MAP pNvRAM = MK48T18_BASE; + + /* + * Set the RTC into write mode + */ + pNvRAM->CMOS.Control|=MK48T18_CTRL_WRITE; + EIEIO; + + /* + * Write the realtime clock values. + */ + + pNvRAM->CMOS.Year = (rtems_unsigned8)Bin2BCD(pTOD->year%100); + if(pTOD->year>=100) + { + pNvRAM->CMOS.Century=(rtems_unsigned8) + Bin2BCD(pTOD->year/100); + } + pNvRAM->CMOS.Month = (rtems_unsigned8)Bin2BCD(pTOD->month); + pNvRAM->CMOS.Date = (rtems_unsigned8)Bin2BCD(pTOD->day); + pNvRAM->CMOS.Day = (rtems_unsigned8)(GregorianDay(pTOD) + 1); + pNvRAM->CMOS.Hour = (rtems_unsigned8)Bin2BCD(pTOD->hour); + pNvRAM->CMOS.Minute = (rtems_unsigned8)Bin2BCD(pTOD->minute); + pNvRAM->CMOS.Second = (rtems_unsigned8)Bin2BCD(pTOD->second); + + /* + * Set the realtime clock control to update the time. + */ + + EIEIO; + pNvRAM->CMOS.Control&=~MK48T18_CTRL_WRITE; +} + +boolean +timeMkGet ( + rtems_time_of_day *pTOD + ) + +/*++ + +Routine Description: + + This routine queries the realtime clock. + + N.B. This routine is required to provide any synchronization necessary + to query the realtime clock information. + +Arguments: + + pTOD - Supplies a pointer to a time structure that receives + the realtime clock information. + +Return Value: + + If the power to the realtime clock has not failed, then the time + values are read from the realtime clock and a value of TRUE is + returned. Otherwise, a value of FALSE is returned. + +--*/ + +{ + PMK48T18_NVRAM_MAP pNvRAM = MK48T18_BASE; + + /* + * Set the RTC into read mode + */ + pNvRAM->CMOS.Control|=MK48T18_CTRL_READ; + EIEIO; + + /* + * Read the realtime clock values. + */ + + pTOD->year = (rtems_unsigned16)(100*BCD2Bin(pNvRAM->CMOS.Century)+ + BCD2Bin(pNvRAM->CMOS.Year)); + pTOD->month = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Month); + pTOD->day = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Date); + pTOD->hour = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Hour); + pTOD->minute = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Minute); + pTOD->second = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Second); + + /* + * Set the realtime clock control to normal mode. + */ + EIEIO; + pNvRAM->CMOS.Control&=~MK48T18_CTRL_READ; + + return TRUE; +} + +/* + * Set up entry table + */ +void +InitializeRTC(void) +{ + rtems_status_code sc; + + switch(ucSystemType) + { + case SYS_TYPE_PPC1: + { + if(ucBoardRevMaj<5) + { + pTimeFunc=&timeDsTable; + break; + } + /* + * For the 005 and later drop through to the PPC1a support + */ + } + + case SYS_TYPE_PPC1a: + { + pTimeFunc=&timeMkTable; + break; + } + + default: + { + pTimeFunc=&timeDsTable; + break; + } + } + + /* + * Set up mutex semaphore + */ + sc = rtems_semaphore_create ( + rtems_build_name ('R', 'T', 'C', 's'), + 1, + RTEMS_BINARY_SEMAPHORE | + RTEMS_INHERIT_PRIORITY | + RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &semRTC); + if (sc != RTEMS_SUCCESSFUL) + { + rtems_fatal_error_occurred (sc); + } +} + +void setRealTimeToRTEMS() +{ + rtems_time_of_day rtc_tod; + + rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + (pTimeFunc->GetTime)(&rtc_tod); + rtems_semaphore_release(semRTC); + + /* + * Millenium fix... + * + * If year is earlier than MIN_YEAR then assume the clock has wrapped from + * 1999 to 1900 so advance by a century + */ + if(rtc_tod.yearSetTime)(&rtc_tod); + rtems_semaphore_release(semRTC); + } + + rtc_tod.ticks=0; + + rtems_clock_set( &rtc_tod ); +} + +void setRealTimeFromRTEMS() +{ + rtems_time_of_day rtems_tod; + + rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod ); + rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + (pTimeFunc->SetTime)(&rtems_tod); + rtems_semaphore_release(semRTC); +} + + +int checkRealTime() +{ + return 0; +} diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/universe/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/universe/Makefile.in new file mode 100644 index 0000000000..9498744792 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/universe/Makefile.in @@ -0,0 +1,54 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/universe.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=universe +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/universe/universe.c b/c/src/lib/libbsp/powerpc/ppcn_60x/universe/universe.c new file mode 100644 index 0000000000..16fb887c44 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/universe/universe.c @@ -0,0 +1,449 @@ +/* + * 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, 1990, 1991, 1992, 1993, 1994, 1997. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $ld: + */ + +#include +#include +#include + +#include +#include + +/******************************************************************** + ******************************************************************** + ********* ********* + ********* Prototypes ********* + ********* ********* + ******************************************************************** + ********************************************************************/ + +typedef struct { + rtems_unsigned32 PCI_ID; /* Offset 0x0000 */ + rtems_unsigned32 PCI_CSR; /* Offset 0x0004 */ + rtems_unsigned32 PCI_CLASS; /* Offset 0x0008 */ + rtems_unsigned32 PCI_MISC0; /* Offset 0x000C */ + rtems_unsigned32 PCI_BS; /* Offset 0x0010 */ + rtems_unsigned32 Buf_Offset_0x0014[ 0x0A ]; /* Offset 0x0014 */ + rtems_unsigned32 PCI_MISC1; /* Offset 0x003C */ + rtems_unsigned32 Buf_Offset_0x0040[ 0x30 ]; /* Offset 0x0040 */ + rtems_unsigned32 LSI0_CTL; /* Offset 0x0100 */ + rtems_unsigned32 LSI0_BS; /* Offset 0x0104 */ + rtems_unsigned32 LSI0_BD; /* Offset 0x0108 */ + rtems_unsigned32 LSI0_TO; /* Offset 0x010C */ + rtems_unsigned32 Buf_Offset_0x0110; /* Offset 0x0110 */ + rtems_unsigned32 LSI1_CTL; /* Offset 0x0114 */ + rtems_unsigned32 LSI1_BS; /* Offset 0x0118 */ + rtems_unsigned32 LSI1_BD; /* Offset 0x011C */ + rtems_unsigned32 LSI1_TO; /* Offset 0x0120 */ + rtems_unsigned32 Buf_Offset_0x0124; /* Offset 0x0124 */ + rtems_unsigned32 LSI2_CTL; /* Offset 0x0128 */ + rtems_unsigned32 LSI2_BS; /* Offset 0x012C */ + rtems_unsigned32 LSI2_BD; /* Offset 0x0130 */ + rtems_unsigned32 LSI2_TO; /* Offset 0x0134 */ + rtems_unsigned32 Buf_Offset_0x0138; /* Offset 0x0138 */ + rtems_unsigned32 LSI3_CTL; /* Offset 0x013C */ + rtems_unsigned32 LSI3_BS; /* Offset 0x0140 */ + rtems_unsigned32 LSI3_BD; /* Offset 0x0144 */ + rtems_unsigned32 LSI3_TO; /* Offset 0x0148 */ + rtems_unsigned32 Buf_Offset_0x014C[ 0x09 ]; /* Offset 0x014C */ + rtems_unsigned32 SCYC_CTL; /* Offset 0x0170 */ + rtems_unsigned32 SCYC_ADDR; /* Offset 0x0174 */ + rtems_unsigned32 SCYC_EN; /* Offset 0x0178 */ + rtems_unsigned32 SCYC_CMP; /* Offset 0x017C */ + rtems_unsigned32 SCYC_SWP; /* Offset 0x0180 */ + rtems_unsigned32 LMISC; /* Offset 0x0184 */ + rtems_unsigned32 SLSI; /* Offset 0x0188 */ + rtems_unsigned32 L_CMDERR; /* Offset 0x018C */ + rtems_unsigned32 LAERR; /* Offset 0x0190 */ + rtems_unsigned32 Buf_Offset_0x0194[ 0x1B ]; /* Offset 0x0194 */ + rtems_unsigned32 DCTL; /* Offset 0x0200 */ + rtems_unsigned32 DTBC; /* Offset 0x0204 */ + rtems_unsigned32 DLA; /* Offset 0x0208 */ + rtems_unsigned32 Buf_Offset_0x020C; /* Offset 0x020C */ + rtems_unsigned32 DVA; /* Offset 0x0210 */ + rtems_unsigned32 Buf_Offset_0x0214; /* Offset 0x0214 */ + rtems_unsigned32 DCPP; /* Offset 0x0218 */ + rtems_unsigned32 Buf_Offset_0x021C; /* Offset 0x021C */ + rtems_unsigned32 DGCS; /* Offset 0x0220 */ + rtems_unsigned32 D_LLUE; /* Offset 0x0224 */ + rtems_unsigned32 Buf_Offset_0x0228[ 0x36 ]; /* Offset 0x0228 */ + rtems_unsigned32 LINT_EN; /* Offset 0x0300 */ + rtems_unsigned32 LINT_STAT; /* Offset 0x0304 */ + rtems_unsigned32 LINT_MAP0; /* Offset 0x0308 */ + rtems_unsigned32 LINT_MAP1; /* Offset 0x030C */ + rtems_unsigned32 VINT_EN; /* Offset 0x0310 */ + rtems_unsigned32 VINT_STAT; /* Offset 0x0314 */ + rtems_unsigned32 VINT_MAP0; /* Offset 0x0318 */ + rtems_unsigned32 VINT_MAP1; /* Offset 0x031C */ + rtems_unsigned32 STATID; /* Offset 0x0320 */ + rtems_unsigned32 V1_STATID; /* Offset 0x0324 */ + rtems_unsigned32 V2_STATID; /* Offset 0x0328 */ + rtems_unsigned32 V3_STATID; /* Offset 0x032C */ + rtems_unsigned32 V4_STATID; /* Offset 0x0330 */ + rtems_unsigned32 V5_STATID; /* Offset 0x0334 */ + rtems_unsigned32 V6_STATID; /* Offset 0x0338 */ + rtems_unsigned32 V7_STATID; /* Offset 0x033C */ + rtems_unsigned32 Buf_Offset_0x0340[ 0x30 ]; /* Offset 0x0340 */ + rtems_unsigned32 MAST_CTL; /* Offset 0x0400 */ + rtems_unsigned32 MISC_CTL; /* Offset 0x0404 */ + rtems_unsigned32 MISC_STAT; /* Offset 0x0408 */ + rtems_unsigned32 USER_AM; /* Offset 0x040C */ + rtems_unsigned32 Buf_Offset_0x0410[ 0x2bc ];/* Offset 0x0410 */ + rtems_unsigned32 VSI0_CTL; /* Offset 0x0F00 */ + rtems_unsigned32 VSI0_BS; /* Offset 0x0F04 */ + rtems_unsigned32 VSI0_BD; /* Offset 0x0F08 */ + rtems_unsigned32 VSI0_TO; /* Offset 0x0F0C */ + rtems_unsigned32 Buf_Offset_0x0f10; /* Offset 0x0F10 */ + rtems_unsigned32 VSI1_CTL; /* Offset 0x0F14 */ + rtems_unsigned32 VSI1_BS; /* Offset 0x0F18 */ + rtems_unsigned32 VSI1_BD; /* Offset 0x0F1C */ + rtems_unsigned32 VSI1_TO; /* Offset 0x0F20 */ + rtems_unsigned32 Buf_Offset_0x0F24; /* Offset 0x0F24 */ + rtems_unsigned32 VSI2_CTL; /* Offset 0x0F28 */ + rtems_unsigned32 VSI2_BS; /* Offset 0x0F2C */ + rtems_unsigned32 VSI2_BD; /* Offset 0x0F30 */ + rtems_unsigned32 VSI2_TO; /* Offset 0x0F34 */ + rtems_unsigned32 Buf_Offset_0x0F38; /* Offset 0x0F38 */ + rtems_unsigned32 VSI3_CTL; /* Offset 0x0F3C */ + rtems_unsigned32 VSI3_BS; /* Offset 0x0F40 */ + rtems_unsigned32 VSI3_BD; /* Offset 0x0F44 */ + rtems_unsigned32 VSI3_TO; /* Offset 0x0F48 */ + rtems_unsigned32 Buf_Offset_0x0F4C[ 0x9 ]; /* Offset 0x0F4C */ + rtems_unsigned32 VRAI_CTL; /* Offset 0x0F70 */ + rtems_unsigned32 VRAI_BS; /* Offset 0x0F74 */ + rtems_unsigned32 Buf_Offset_0x0F78[ 0x2 ]; /* Offset 0x0F78 */ + rtems_unsigned32 VCSR_CTL; /* Offset 0x0F80 */ + rtems_unsigned32 VCSR_TO; /* Offset 0x0F84 */ + rtems_unsigned32 V_AMERR; /* Offset 0x0F88 */ + rtems_unsigned32 VAERR; /* Offset 0x0F8C */ + rtems_unsigned32 Buf_Offset_0x0F90[ 0x19 ]; /* Offset 0x0F90 */ + rtems_unsigned32 VCSR_CLR; /* Offset 0x0FF4 */ + rtems_unsigned32 VCSR_SET; /* Offset 0x0FF8 */ + rtems_unsigned32 VCSR_BS; /* Offset 0x0FFC */ +} Universe_Memory; + +volatile Universe_Memory *UNIVERSE; + +/* + * PCI_bus_write + */ +void PCI_bus_write( + volatile rtems_unsigned32 * _addr, /* IN */ + rtems_unsigned32 _data /* IN */ +) +{ + outport_32(_addr, _data); +} + +rtems_unsigned32 PCI_bus_read( + volatile rtems_unsigned32 * _addr /* IN */ +) +{ + rtems_unsigned32 data; + + inport_32(_addr, data); + return data; +} + +/******************************************************************** + ******************************************************************** + ********* ********* + ********* ********* + ********* ********* + ******************************************************************** + ********************************************************************/ + +/* + * Initializes the UNIVERSE chip. This routine is called automatically + * by the boot code. This routine should be called by user code only if + * a complete PPCn_60x VME initialization is required. + */ + +void InitializeUniverse() +{ + rtems_unsigned32 pci_id; + rtems_unsigned32 universe_temp_value; + + /* + * Verify the UNIVERSE CHIP ID + */ + (void)PCIConfigRead32(0,4,0,PCI_CONFIG_VENDOR_LOW, &pci_id); + + /* + * compare to known ID + */ + if (pci_id != 0x000010e3 ){ + DEBUG_puts ("Invalid PPCN_60X_UNIVERSE_CHIP_ID: "); + rtems_fatal_error_occurred( 0x603e0bad ); + } + + (void)PCIConfigRead32(0,4,0,PCI_CONFIG_BAR_0, &universe_temp_value); + UNIVERSE = (Universe_Memory *)(universe_temp_value & ~PCI_ADDRESS_IO_SPACE); + + /* + * Set the UNIVERSE PCI Configuration Space Control and Status Register to + * medium speed device, Target Back to Back Capable, Master Enable, Target + * Memory Enable and Target IO Enable + */ + PCIConfigWrite32(0,4,0,PCI_CONFIG_COMMAND, PCI_ENABLE_IO_SPACE | + PCI_ENABLE_MEMORY_SPACE | + PCI_ENABLE_BUS_MASTER); + + /* + * Turn off the sysfail by setting SYSFAIL bit to 1 on the VCSR_CLR register + */ + PCI_bus_write( &UNIVERSE->VCSR_CLR, 0x40000000 ); + +#if 0 + /* + * Set VMEbus Slave Image 0 Base Address to 0x04000000 on VSI0_BS register. + */ + PCI_bus_write( &UNIVERSE->VSI0_BS, 0x04000000 ); + + /* + * Set VMEbus Slave Image 0 Bound Address to 0x05000000 on VSI0_BD register. + */ + PCI_bus_write( &UNIVERSE->VSI0_BD, 0x05000000 ); + + /* + * VMEbus Slave Image 0 Translation Offset to 0x7C000000 on VSI0_TO + * register. Map the VME base address 0x4000000 to local memory address 0x0 + */ + PCI_bus_write( &UNIVERSE->VSI0_TO, 0x7C000000 ); + + /* + * Set the VMEbus Slave Image 0 Control register with write posted, + * read prefetch and AM code set for program, data, supervisor and user mode + */ + PCI_bus_write( &UNIVERSE->VSI0_CTL, 0xE0F20000 ); +#endif + + /* + * Set the VMEbus Master Control register with retry forever, 256 bytes + * posted write transfer count, VMEbus request level 3, RWD, PCI 32 bytes + * aligned burst size and PCI bus number to be zero + */ + PCI_bus_write( &UNIVERSE->MAST_CTL, 0x01C00000 ); + + /* + * VMEbus DMA Transfer Control register with 32 bit VMEbus Maximum Data + * width, A32 VMEbus Address Space, AM code to be data, none-privilleged, + * single and BLT cycles on VME bus and 64-bit PCI Bus Transactions enable + PCI_bus_write( &UNIVERSE->DCTL, 0x00820180 ); + */ + + PCI_bus_write( &UNIVERSE->LSI0_CTL, 0x80700040 ); + PCI_bus_write( &UNIVERSE->LSI0_BS, 0x04000000 ); + PCI_bus_write( &UNIVERSE->LSI0_BD, 0x05000000 ); + PCI_bus_write( &UNIVERSE->LSI0_TO, 0x7C000000 ); + + +#if 0 + /* + * Set the PCI Slave Image 0 Control register with posted write enable, + * 32 bit data width, A32 VMEbus address base, AM code to be data, + * none-privilleged, single and BLT cycles on VME bus with PCI + * bus memory space. + PCI_bus_write( &UNIVERSE->LSI0_CTL, 0xC0820100 ); + */ + PCI_bus_write( &UNIVERSE->LSI0_CTL, 0x80700040 ); + + /* + * Set the PCI Slave Image 0 Base Address to be + * 0x0 on LSI0_BS register. + */ + PCI_bus_write( &UNIVERSE->LSI0_BS, 0x00FF0000 ); + + /* + * Set the PCI Slave Image 0 Bound Address to be + * 0xFFFFF000 on VSI0_BD register. + */ + PCI_bus_write( &UNIVERSE->LSI0_BD, 0x00FFF000 ); + + /* + * Set the PCI Slave Image 0 Translation Offset to be + * 0x0 on VSI0_TO register. + * Note: If the actual VME address is bigger than 0x40000000, we need + * to set the PCI Slave Image 0 Translation Offset = 0x40000000 + * register. + * i.e. if actual VME ADRR = 0x50000000, then we + * need to subtract it by 0x40000000 and set + * the LSI0_T0 register to be 0x40000000 and then + * perform a PCI data access by adding 0xC0000000 to + * 0x10000000 -- which is came form the result of + * (0x50000000 - 0x40000000). + */ + PCI_bus_write( &UNIVERSE->LSI0_TO, 0x0 ); +#endif + + /* + * Remove the Universe from VMEbus BI-Mode (bus-isolation). Once out of + * BI-Mode VMEbus accesses can be made. + */ + + universe_temp_value = PCI_bus_read( &UNIVERSE->MISC_CTL ); + + if (universe_temp_value & 0x100000) + PCI_bus_write( &UNIVERSE->MISC_CTL,(universe_temp_value | ~0xFF0FFFFF)); +} + +/* + * Set the slave VME base address to the specified base address. + * Note: Lower 12 bits[11:0] will be masked out prior to setting the VMEbus + * Slave Image 0 registers. + */ +void set_vme_base_address ( + rtems_unsigned32 base_address +) +{ + volatile rtems_unsigned32 temp; + + /* + * Calculate the current size of the Slave VME image 0 + */ + temp = ( PCI_bus_read( &UNIVERSE->VSI0_BD) & 0xFFFFF000) - + ( PCI_bus_read( &UNIVERSE->VSI0_BS) & 0xFFFFF000); + + /* + * Set the VMEbus Slave Image 0 Base Address to be + * the specifed base address on VSI0_BS register. + */ + PCI_bus_write( &UNIVERSE->VSI0_BS, (base_address & 0xFFFFF000) ); + + /* + * Update the VMEbus Slave Image 0 Bound Address. + */ + PCI_bus_write( &UNIVERSE->VSI0_BD, temp ); + + /* + * Update the VMEbus Slave Image 0 Translation Offset + */ + temp = 0xFFFFFFFF - (base_address & 0xFFFFF000) + 1 + 0x80000000; + PCI_bus_write( &UNIVERSE->VSI0_TO, temp ); +} + +/* + * Gets the VME base address + */ +rtems_unsigned32 get_vme_base_address () +{ + volatile rtems_unsigned32 temp; + + temp = PCI_bus_read( &UNIVERSE->VSI0_BS ); + temp &= 0xFFFFF000; + return (temp); +} + +rtems_unsigned32 get_vme_slave_size() +{ + volatile rtems_unsigned32 temp; + temp = PCI_bus_read( &UNIVERSE->VSI0_BD); + temp &= 0xFFFFF000; + temp = temp - get_vme_base_address (); + return temp; +} + +/* + * Set the size of the VME slave image + * Note: The maximum size is up to 24 M bytes. (00000000 - 017FFFFF) + */ +void set_vme_slave_size (rtems_unsigned32 size) +{ + volatile rtems_unsigned32 temp; + + if (size<0) + size = 0; + + if (size > 0x17FFFFF) + size = 0x17FFFFF; + + /* + * Read the VME slave image base address + */ + temp = get_vme_base_address (); + + /* + * Update the VMEbus Slave Image 0 Bound Address. + */ + temp = temp + (size & 0xFFFFF000); + PCI_bus_write( &UNIVERSE->VSI0_BD, temp ); +} + +#if 0 +/* XXXXX */ +/* + * Returns the 16 bit location specified by vme_ptr, which must be a + * pointer to VME D16 space + */ +rtems_unsigned16 get_vme( + rtems_unsigned16 *vme_ptr +) +{ + rtems_unsigned16 result; + + if (vme_ptr > (rtems_unsigned16 *)0x3EFFFFFF) + { + /* + * LSI0_TO register to 0x3EFFF000 if it had not been updated already + */ + if (( PCI_bus_read( &UNIVERSE->LSI0_TO ) & 0xFFFFF000) != 0x3EFFF000) + PCI_bus_write( &UNIVERSE->LSI0_TO, 0x3EFFF000 ); + + result = (*(rtems_unsigned16 *)( + ((rtems_unsigned32)vme_ptr - 0x3EFFF000)+ + PPCN_60X_PCI_MEM_BASE) ); + } + else + result = (*(rtems_unsigned16 *) + ((rtems_unsigned32)vme_ptr+PPCN_60X_PCI_MEM_BASE)); + + return result; +} + +/* + * Stores the 16 bit word at the location specified by vme_ptr, which must + * be a pointer to VME D16 space + */ +void put_vme( + rtems_unsigned16 *vme_ptr, + rtems_unsigned16 value +) +{ + + if (vme_ptr > (rtems_unsigned16 *)0x3EFFFFFF) { + /* + * LSI0_TO register to 0x3EFFF000 if it had not been updated already + */ + if (( PCI_bus_read( &UNIVERSE->LSI0_TO) & 0xFFFFF000) != 0x3EFFF000) + PCI_bus_write( &UNIVERSE->LSI0_TO, 0x3EFFF000 ); + + *(rtems_unsigned16 *) (((rtems_unsigned32)vme_ptr - 0x3EFFF000) + + PPCN_60X_PCI_MEM_BASE) = value; + } + else + *(rtems_unsigned16 *)((rtems_unsigned32)vme_ptr + + PPCN_60X_PCI_MEM_BASE) = value; +} +#endif + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/Makefile.in new file mode 100644 index 0000000000..d17e897c7d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/Makefile.in @@ -0,0 +1,59 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/vectors.rel + +# C source names, if any, go here -- minus the .c +C_PIECES= +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +S_PIECES=vectors +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/README b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/README new file mode 100644 index 0000000000..4081ae2525 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/README @@ -0,0 +1,25 @@ +# +# $Id$ +# + +The location of the vectors file object is critical. + +From the comments at the head of vectors.s: + + The issue with this file is getting it loaded at the right place. + The first vector MUST be at address 0x????0100. + How this is achieved is dependant on the tool chain. + + However the basic mechanism for ELF assemblers is to create a + section called ".vectors", which will be loaded to an address + between 0x????0000 and 0x????0100 (inclusive) via a link script. + + The basic mechanism for XCOFF assemblers is to place it in the + normal text section, and arrange for this file to be located + at an appropriate position on the linker command line. + + The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the + offset from 0x????0000 to the first location in the file. This + will usually be 0x0000 or 0x0100. + +Andrew Bray 18/8/1995 diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/align_h.S b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/align_h.S new file mode 100644 index 0000000000..d16298343d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/align_h.S @@ -0,0 +1,434 @@ +/* align_h.s 1.1 - 95/12/04 + * + * This file contains the assembly code for the PowerPC 403 + * alignment exception handler for RTEMS. + * + * Based upon IBM provided code with the following release: + * + * This source code has been made available to you by IBM on an AS-IS + * basis. Anyone receiving this source is licensed under IBM + * copyrights to use it in any way he or she deems fit, including + * copying it, modifying it, compiling it, and redistributing it either + * with or without modifications. No license under IBM patents or + * patent applications is to be implied by the copyright license. + * + * Any user of this software should understand that IBM cannot provide + * technical support for this software and will not be responsible for + * any consequences resulting from the use of this software. + * + * Any person who transfers this source code or any derivative work + * must include the IBM copyright notice, this paragraph, and the + * preceding two paragraphs in the transferred software. + * + * COPYRIGHT I B M CORPORATION 1995 + * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M + * + * Modifications: + * + * Author: Andrew Bray + * + * COPYRIGHT (c) 1995 by i-cubed ltd. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of i-cubed limited not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * i-cubed limited makes no representations about the suitability + * of this software for any purpose. + * + * $Id$ + */ + +#include "asm.h" +#include "bsp.h" + +.set CACHE_SIZE,16 # cache line size of 32 bytes +.set CACHE_SIZE_L2,4 # cache line size, log 2 + +.set Open_gpr0,0 +.set Open_gpr1,4 +.set Open_gpr2,8 +.set Open_gpr3,12 +.set Open_gpr4,16 +.set Open_gpr5,20 +.set Open_gpr6,24 +.set Open_gpr7,28 +.set Open_gpr8,32 +.set Open_gpr9,36 +.set Open_gpr10,40 +.set Open_gpr11,44 +.set Open_gpr12,48 +.set Open_gpr13,52 +.set Open_gpr14,56 +.set Open_gpr15,60 +.set Open_gpr16,64 +.set Open_gpr17,68 +.set Open_gpr18,72 +.set Open_gpr19,76 +.set Open_gpr20,80 +.set Open_gpr21,84 +.set Open_gpr22,88 +.set Open_gpr23,92 +.set Open_gpr24,96 +.set Open_gpr25,100 +.set Open_gpr26,104 +.set Open_gpr27,108 +.set Open_gpr28,112 +.set Open_gpr29,116 +.set Open_gpr30,120 +.set Open_gpr31,124 +.set Open_xer,128 +.set Open_lr,132 +.set Open_ctr,136 +.set Open_cr,140 +.set Open_srr2,144 +.set Open_srr3,148 +.set Open_srr0,152 +.set Open_srr1,156 + + +/* + * This code makes several assumptions for processing efficiency + * * General purpose registers are continuous in the image, beginning with + * Open_gpr0 + * * Hash table is highly dependent on opcodes - opcode changes *will* + * require rework of the instruction decode mechanism. + */ + + .text + .globl align_h + + .align CACHE_SIZE_L2 +align_h: + /*----------------------------------------------------------------------- + * Store GPRs in Open Reg save area + * Set up r2 as base reg, r1 pointing to Open Reg save area + *----------------------------------------------------------------------*/ + stmw r0,ALIGN_REGS(r0) + li r1,ALIGN_REGS + /*----------------------------------------------------------------------- + * Store special purpose registers in reg save area + *----------------------------------------------------------------------*/ + mfxer r7 + mflr r8 + mfcr r9 + mfctr r10 + stw r7,Open_xer(r1) + stw r8,Open_lr(r1) + stw r9,Open_cr(r1) + stw r10,Open_ctr(r1) + mfspr r7, srr2 /* SRR 2 */ + mfspr r8, srr3 /* SRR 3 */ + mfspr r9, srr0 /* SRR 0 */ + mfspr r10, srr1 /* SRR 1 */ + stw r7,Open_srr2(r1) + stw r8,Open_srr3(r1) + stw r9,Open_srr0(r1) + stw r10,Open_srr1(r1) + +/* Set up common registers */ + mfspr r5, dear /* DEAR: R5 is data exception address */ + lwz r9,Open_srr0(r1) /* get faulting instruction */ + addi r7,r9,4 /* bump instruction */ + stw r7,Open_srr0(r1) /* restore to image */ + lwz r9, 0(r9) /* retrieve actual instruction */ + rlwinm r6,r9,18,25,29 /* r6 is RA * 4 field from instruction */ + rlwinm r7,r9,6,26,31 /* r7 is primary opcode */ + bl ref_point /* establish addressibility */ +ref_point: + mflr r11 /* r11 is the anchor point for ref_point */ + addi r10, r7, -31 /* r10 = r7 - 31 */ + rlwinm r10,r10,2,2,31 /* r10 *= 4 */ + add r10, r10, r11 /* r10 += anchor point */ + lwz r10, primary_jt-ref_point(r10) + mtlr r10 + rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */ + la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */ + blr +primary_jt: + .long xform + .long lwz + .long lwzu + .long 0 + .long 0 + .long stw + .long stwu + .long 0 + .long 0 + .long lhz + .long lhzu + .long lha + .long lhau + .long sth + .long sthu + .long lmw + .long stmw +/* + * handlers + */ +/* + * xform instructions require an additional decode. Fortunately, a relatively + * simple hash step breaks the instructions out with no collisions + */ +xform: + rlwinm r7,r9,31,22,31 /* r7 is secondary opcode */ + rlwinm r10,r7,27,5,31 /* r10 = r7 >> 5 */ + add r10,r7,r10 /* r10 = r7 + r10 */ + rlwinm r10,r10,2,25,29 /* r10 = (r10 & 0x1F) * 4 */ + add r10,r10,r11 /* r10 += anchor point */ + lwz r10, secondary_ht-ref_point(r10) + mtlr r10 + la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */ + rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */ + blrl + +secondary_ht: + .long lhzux /* b 0 0x137 */ + .long lhax /* b 1 0x157 */ + .long lhaux /* b 2 0x177 */ + .long sthx /* b 3 0x197 */ + .long sthux /* b 4 0x1b7 */ + .long 0 /* b 5 */ + .long lwbrx /* b 6 0x216 */ + .long 0 /* b 7 */ + .long 0 /* b 8 */ + .long 0 /* b 9 */ + .long stwbrx /* b A 0x296 */ + .long 0 /* b B */ + .long 0 /* b C */ + .long 0 /* b D */ + .long lhbrx /* b E 0x316 */ + .long 0 /* b F */ + .long 0 /* b 10 */ + .long 0 /* b 11 */ + .long sthbrx /* b 12 0x396 */ + .long 0 /* b 13 */ + .long lwarx /* b 14 0x014 */ + .long dcbz /* b 15 0x3f6 */ + .long 0 /* b 16 */ + .long lwzx /* b 17 0x017 */ + .long lwzux /* b 18 0x037 */ + .long 0 /* b 19 */ + .long stwcx /* b 1A 0x096 */ + .long stwx /* b 1B 0x097 */ + .long stwux /* b 1C 0x0B7 */ + .long 0 /* b 1D */ + .long 0 /* b 1E */ + .long lhzx /* b 1F 0x117 */ + +/* + * for all handlers + * r4 - Addressability to interrupt context + * r5 - DEAR address (faulting data address) + * r6 - RA field * 4 + * r7 - Address of GPR 0 in image + * r8 - RD field * 4 + * r9 - Failing instruction + */ + +/* Load halfword algebraic with update */ +lhau: +/* Load halfword algebraic with update indexed */ +lhaux: + stwx r5,r7,r6 /* update RA with effective addr */ + +/* Load halfword algebraic */ +lha: +/* Load halfword algebraic indexed */ +lhax: + lswi r10,r5,2 /* load two bytes into r10 */ + srawi r10,r10,16 /* shift right 2 bytes, extending sign */ + stwx r10,r7,r8 /* update reg image */ + b align_complete /* return */ + +/* Load Half Word Byte-Reversed Indexed */ +lhbrx: + lswi r10,r5,2 /* load two bytes from DEAR into r10 */ + rlwinm r10,r10,0,0,15 /* mask off lower 2 bytes */ + stwbrx r10,r7,r8 /* store reversed in reg image */ + b align_complete /* return */ + +/* Load Half Word and Zero with Update */ +lhzu: +/* Load Half Word and Zero with Update Indexed */ +lhzux: + stwx r5,r7,r6 /* update RA with effective addr */ + +/* Load Half Word and Zero */ +lhz: +/* Load Half Word and Zero Indexed */ +lhzx: + lswi r10,r5,2 /* load two bytes from DEAR into r10 */ + rlwinm r10,r10,16,16,31 /* shift right 2 bytes, with zero fill */ + stwx r10,r7,r8 /* update reg image */ + b align_complete /* return */ + +/* + * Load Multiple Word + */ +lmw: + lwzx r9,r6,r7 /* R9 contains saved value of RA */ + addi r10,r7,32*4 /* r10 points to r31 in image + 4 */ + rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */ + subfic r8,r8,32 /* r8 is reg count to load */ + mtctr r8 /* load counter */ + addi r8,r8,-1 /* r8-- */ + rlwinm r8,r8,2,2,31 /* r8 *= 4 */ + add r5,r5,r8 /* update DEAR to point to last reg */ +lwmloop: + lswi r11,r5,4 /* load r11 with 4 bytes from DEAR */ + stwu r11,-4(r10) /* load image and decrement pointer */ + addi r5,r5,-4 /* decrement effective address */ + bdnz lwmloop + stwx r9,r6,r7 /* restore RA (in case it was trashed) */ + b align_complete /* return */ + +/* + * Load Word and Reserve Indexed + */ +lwarx: + lswi r10,r5,4 /* load four bytes from DEAR into r10 */ + stwx r10,r7,r8 /* update reg image */ + rlwinm r5,r5,0,0,29 /* Word align address */ + lwarx r10,0,r5 /* Set reservation */ + b align_complete /* return */ + +/* + * Load Word Byte-Reversed Indexed + */ +lwbrx: + lswi r10,r5,4 /* load four bytes from DEAR into r10 */ + stwbrx r10,r7,r8 /* store reversed in reg image */ + b align_complete /* return */ + +/* Load Word and Zero with Update */ +lwzu: +/* Load Word and Zero with Update Indexed */ +lwzux: + stwx r5,r7,r6 /* update RA with effective addr */ + +/* Load Word and Zero */ +lwz: +/* Load Word and Zero Indexed */ +lwzx: + lswi r10,r5,4 /* load four bytes from DEAR into r10 */ + stwx r10,r7,r8 /* update reg image */ + b align_complete /* return */ + +/* Store instructions */ + +/* */ +/* Store Half Word and Update */ +sthu: +/* Store Half Word and Update Indexed */ +sthux: + stwx r5,r7,r6 /* Update RA with effective address */ + +/* Store Half Word */ +sth: +/* Store Half Word Indexed */ +sthx: + lwzx r10,r8,r7 /* retrieve source register value */ + rlwinm r10,r10,16,0,15 /* move two bytes to high end of reg */ + stswi r10,r5,2 /* store bytes to DEAR address */ + b align_complete /* return */ + +/* */ +/* Store Half Word Byte-Reversed Indexed */ +sthbrx: + lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */ + stswi r10,r5,2 /* move two bytes to DEAR address */ + b align_complete /* return */ + +/* */ +/* Store Multiple Word */ +stmw: + addi r10,r7,32*4 /* r10 points to r31 in image + 4 */ + rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */ + subfic r8,r8,32 /* r8 is reg count to load */ + mtctr r8 /* load counter */ + addi r8,r8,-1 /* r8-- */ + rlwinm r8,r8,2,2,31 /* r8 *= 4 */ + add r5,r5,r8 /* update DEAR to point to last reg */ +stmloop: + lwzu r11,-4(r10) /* get register value */ + stswi r11,r5,4 /* output to DEAR address */ + addi r5,r5,-4 /* decrement effective address */ + bdnz stmloop + b align_complete /* return */ + +/* */ +/* Store Word and Update */ +stwu: +/* Store Word and Update Indexed */ +stwux: + stwx r5,r7,r6 /* Update RA with effective address */ + +/* Store Word */ +stw: +/* Store Word Indexed */ +stwx: + lwzx r10,r8,r7 /* retrieve source register value */ + stswi r10,r5,4 /* store bytes to DEAR address */ + b align_complete /* return */ + +/* */ +/* Store Word Byte-Reversed Indexed */ +stwbrx: + lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */ + stswi r10,r5,4 /* move two bytes to DEAR address */ + b align_complete /* return */ + +/* */ +/* Store Word Conditional Indexed */ +stwcx: + rlwinm r10,r5,0,0,29 /* r10 = word aligned DEAR */ + lwz r11,0(r10) /* save original value of store */ + stwcx. r11,r0,r10 /* attempt store to address */ + bne stwcx_moveon /* store failed, move on */ + stw r11,0(r10) /* repair damage */ + lwzx r9,r7,r8 /* get register value */ + stswi r10,r5,4 /* store bytes to DEAR address */ +stwcx_moveon: + mfcr r11 /* get condition reg */ + lwz r9,Open_cr(r1) /* get condition reg image */ + rlwimi r9,r11,0,0,2 /* insert 3 CR bits into cr image */ + lwz r11,Open_xer(r1) /* get XER reg */ + rlwimi r9,r11,29,2,2 /* insert XER SO bit into cr image */ + stw r9,Open_cr(r1) /* store cr image */ + b align_complete /* return */ + +/* */ +/* Data Cache Block Zero */ +dcbz: + rlwinm r5,r5,0,0,31-CACHE_SIZE_L2 + /* get address to nearest Cache line */ + addi r5,r5,-4 /* adjust by a word */ + addi r10,r0,CACHE_SIZE/4 /* set counter value */ + mtctr r10 + addi r11,r0,0 /* r11 = 0 */ +dcbz_loop: + stwu r11,4(r5) /* store a word and update EA */ + bdnz dcbz_loop + b align_complete /* return */ + +align_complete: + /*----------------------------------------------------------------------- + * Restore regs and return from the interrupt + *----------------------------------------------------------------------*/ + lmw r24,Open_xer+ALIGN_REGS(r0) + mtxer r24 + mtlr r25 + mtctr r26 + mtcrf 0xFF, r27 + mtspr srr2, r28 /* SRR 2 */ + mtspr srr3, r29 /* SRR 3 */ + mtspr srr0, r30 /* SRR 0 */ + mtspr srr1, r31 /* SRR 1 */ + lmw r1,Open_gpr1+ALIGN_REGS(r0) + lwz r0,Open_gpr0+ALIGN_REGS(r0) + rfi diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/vectors.S b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/vectors.S new file mode 100644 index 0000000000..787dbf1eb9 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/vectors/vectors.S @@ -0,0 +1,297 @@ +/* + * (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. + * + */ +/* vectors.s 1.1 - 95/12/04 + * + * This file contains the assembly code for the PowerPC + * interrupt veneers for RTEMS. + * + */ + +/* + * The issue with this file is getting it loaded at the right place. + * The first vector MUST be at address 0x????0100. + * How this is achieved is dependant on the tool chain. + * + * However the basic mechanism for ELF assemblers is to create a + * section called ".vectors", which will be loaded to an address + * between 0x????0000 and 0x????0100 (inclusive) via a link script. + * + * The basic mechanism for XCOFF assemblers is to place it in the + * normal text section, and arrange for this file to be located + * at an appropriate position on the linker command line. + * + * The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the + * offset from 0x????0000 to the first location in the file. This + * will usually be 0x0000 or 0x0100. + * + * $Id$ + */ + +#include "asm.h" +#include "bsp.h" + +#ifndef PPC_VECTOR_FILE_BASE +#error "PPC_VECTOR_FILE_BASE is not defined." +#endif + + .set IP_LINK, 0 +#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27) + .set IP_0, (IP_LINK + 56) +#else + .set IP_0, (IP_LINK + 8) +#endif + .set IP_2, (IP_0 + 4) + + .set IP_3, (IP_2 + 4) + .set IP_4, (IP_3 + 4) + .set IP_5, (IP_4 + 4) + .set IP_6, (IP_5 + 4) + + .set IP_7, (IP_6 + 4) + .set IP_8, (IP_7 + 4) + .set IP_9, (IP_8 + 4) + .set IP_10, (IP_9 + 4) + + .set IP_11, (IP_10 + 4) + .set IP_12, (IP_11 + 4) + .set IP_13, (IP_12 + 4) + .set IP_28, (IP_13 + 4) + + .set IP_29, (IP_28 + 4) + .set IP_30, (IP_29 + 4) + .set IP_31, (IP_30 + 4) + .set IP_CR, (IP_31 + 4) + + .set IP_CTR, (IP_CR + 4) + .set IP_XER, (IP_CTR + 4) + .set IP_LR, (IP_XER + 4) + .set IP_PC, (IP_LR + 4) + + .set IP_MSR, (IP_PC + 4) + + .set IP_END, (IP_MSR + 16) + + /* Where this file will be loaded */ + .set file_base, PPC_VECTOR_FILE_BASE + + /* Vector offsets */ + .set reset_vector,0x0100 + .set mach_vector,0x0200 + .set prot_vector,0x0300 + .set isi_vector,0x0400 + .set ext_vector,0x0500 + .set align_vector,0x0600 + .set prog_vector,0x0700 + .set float_vector,0x0800 + .set dec_vector,0x0900 + .set sys_vector,0x00C00 + .set trace_vector, 0x0d00 + .set itm_vector,0x01000 + .set dltm_vector,0x1100 + .set dstm_vector,0x1200 + .set addr_vector,0x1300 + .set sysmgmt_vector,0x1400 + +/* Go to the right section */ +#if PPC_ASM == PPC_ASM_ELF + .section .vectors,"awx",@progbits +#elif PPC_ASM == PPC_ASM_XCOFF + .csect .text[PR] +#endif + + PUBLIC_VAR (__vectors) +SYM (__vectors): + +#if PPCN_60X_USE_DINK + .org reset_vector - file_base + /* This is where the DINK soft reset handler is located */ + ba 0xfff00180 + + .org mach_vector - file_base + ba 0xfff00200 + + .org prot_vector - file_base + ba 0xfff00300 + + .org isi_vector - file_base + ba 0xfff00400 + + .org ext_vector - file_base + rfi + + .org align_vector - file_base + ba 0xfff00600 + + .org prog_vector - file_base + ba 0xfff00700 + + .org float_vector - file_base + ba 0xfff00800 + + .org dec_vector - file_base + rfi + + .org sys_vector - file_base + ba 0xfff00C00 + + .org trace_vector - file_base + ba 0xfff00d00 + + .org itm_vector - file_base + ba 0xfff01000 + + .org dltm_vector - file_base + ba 0xfff01100 + + .org dstm_vector - file_base + ba 0xfff01200 + + .org addr_vector - file_base + ba 0xfff01300 + + .org sysmgmt_vector - file_base + ba 0xfff01400 +#else + .org reset_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,1 +display_exc: + stw r3,IP_3(r1) + stw r5,IP_5(r1) + /* + * Enable data and instruction address translation + */ + li r3,MSR_IR | MSR_DR + mtmsr r3 + lis r3,0x8000 + stb r4,0x860(r3) + addi r4,r4,0x30 +waitfortx: + lbz r5,0x3fd(r3) + andi. r5,r5,0x20 + beq waitfortx + stb r4,0x3f8(r3) + li r5,0 + stw r4,0x00(r5) + mfsrr0 r4 + stw r4,0x04(r5) + mfsrr1 r4 + stw r4,0x08(r5) + lwz r4,IP_4(r1) + lwz r5,IP_5(r1) + lwz r3,IP_3(r1) + addi r1,r1,IP_END + rfi + + .org mach_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + stw r3,IP_3(r1) + lis r4,0 + mfspr r3,srr0 + stw r3,0x00(r4) + mfspr r3,srr1 + stw r3,0x04(r4) + stw r5,0x08(r4) + stw r2,0x0c(r4) + stw r11,0x10(r4) + stw r12,0x14(r4) + dcbst 0,r4 + li r4,0x02 + b display_exc + + .org prot_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x03 + b display_exc + + .org isi_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x04 + b display_exc + + .org ext_vector - file_base + rfi + + .org align_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x06 + b display_exc + + .org prog_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x07 + b display_exc + + .org float_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x08 + b display_exc + + .org dec_vector - file_base + rfi + + .org sys_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x0a + b display_exc + + .org trace_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x0b + b display_exc + + .org itm_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x0c + b display_exc + + .org dltm_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x0d + b display_exc + + .org dstm_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x0e + b display_exc + + .org addr_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x0f + b display_exc + + .org sysmgmt_vector - file_base + stwu r1, -(IP_END)(r1) + stw r4,IP_4(r1) + li r4,0x00 + b display_exc +#endif + diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/wrapup/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/wrapup/Makefile.in new file mode 100644 index 0000000000..d6b2ed0bad --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/wrapup/Makefile.in @@ -0,0 +1,59 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +# We only build the network device driver if HAS_NETWORK was defined +NETWORK_DRIVER_yes_V = network +NETWORK_DRIVER = $(NETWORK_DRIVER_$(HAS_NETWORK)_V) + +BSP_PIECES=startup clock console timer tod \ + $(NETWORK_DRIVER) nvram universe pci vectors +# pieces to pick up out of libcpu/$(RTEMS_CPU) +CPU_PIECES= +GENERIC_PIECES= + +# bummer; have to use $foreach since % pattern subst rules only replace 1x +OBJS=$(foreach piece, $(BSP_PIECES), ../$(piece)/$(ARCH)/$(piece).rel) \ + $(foreach piece, $(CPU_PIECES), \ + ../../../../libcpu/$(RTEMS_CPU)/$(piece)/$(ARCH)/$(piece).rel) \ + $(foreach piece, $(GENERIC_PIECES), \ + ../../../$(piece)/$(ARCH)/$(piece).rel) +LIB=$(ARCH)/libbsp.a + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/lib.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +$(LIB): ${OBJS} + $(make-library) + +all: ${ARCH} $(SRCS) $(LIB) + $(INSTALL_VARIANT) -m 644 $(LIB) ${PROJECT_RELEASE}/lib + -- cgit v1.2.3