summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/ep1a/console
diff options
context:
space:
mode:
authorJennifer Averett <Jennifer.Averett@OARcorp.com>2005-04-28 14:05:14 +0000
committerJennifer Averett <Jennifer.Averett@OARcorp.com>2005-04-28 14:05:14 +0000
commit0329aae1b2cd18215ac8d19cbb1a69f502eddd71 (patch)
tree84188ee210ca807c9af4393c93684ff491a789ee /c/src/lib/libbsp/powerpc/ep1a/console
parent2005-04-27 Ralf Corsepius <ralf.corsepius@rtems.org> (diff)
downloadrtems-0329aae1b2cd18215ac8d19cbb1a69f502eddd71.tar.bz2
2005-04-28 Jennifer Averett <jennifer.averett@oarcorp.com>
* acinclude.m4: Initial release of ep1a bsp * ep1a/Makefile.am, ep1a/bsp_specs, ep1a/configure.ac, ep1a/console/alloc360.c, ep1a/console/console.c, ep1a/console/console.h, ep1a/console/init68360.c, ep1a/console/m68360.h, ep1a/console/mc68360_scc.c, ep1a/console/ns16550cfg.c, ep1a/console/ns16550cfg.h, ep1a/console/rsPMCQ1.c, ep1a/console/rsPMCQ1.h, ep1a/include/bsp.h, ep1a/irq/irq.c, ep1a/irq/irq_init.c, ep1a/pci/no_host_bridge.c, ep1a/start/start.S, ep1a/startup/bspstart.c, ep1a/startup/linkcmds, ep1a/vme/vmeconfig.c: New files.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/ep1a/console')
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c104
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/console.c350
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/console.h38
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/init68360.c670
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/m68360.h973
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c836
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c47
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h57
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c558
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h148
10 files changed, 3781 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c b/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c
new file mode 100644
index 0000000000..1ed1aca3f4
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c
@@ -0,0 +1,104 @@
+/*
+ * MC68360 buffer descriptor allocation routines
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include "m68360.h"
+#include <rtems/error.h>
+#include "rsPMCQ1.h"
+#include <rtems/bspIo.h>
+
+void M360SetupMemory( M68360_t ptr ){
+ volatile m360_t *m360;
+
+ m360 = ptr->m360;
+
+ ptr->bdregions[0].base = (char *)&m360->dpram1[0];
+ ptr->bdregions[0].size = sizeof m360->dpram1;
+ ptr->bdregions[0].used = 0;
+
+ ptr->bdregions[1].base = (char *)&m360->dpram3[0];
+ ptr->bdregions[1].size = sizeof m360->dpram3;
+ ptr->bdregions[1].used = 0;
+
+ ptr->bdregions[2].base = (char *)&m360->dpram0[0];
+ ptr->bdregions[2].size = sizeof m360->dpram0;
+ ptr->bdregions[2].used = 0;
+
+ ptr->bdregions[3].base = (char *)&m360->dpram2[0];
+ ptr->bdregions[3].size = sizeof m360->dpram2;
+ ptr->bdregions[3].used = 0;
+}
+
+
+/*
+ * Send a command to the CPM RISC processer
+ */
+void *
+M360AllocateBufferDescriptors (M68360_t ptr, int count)
+{
+ unsigned int i;
+ ISR_Level level;
+ void *bdp = NULL;
+ unsigned int want = count * sizeof(m360BufferDescriptor_t);
+ int have;
+
+ /*
+ * Running with interrupts disabled is usually considered bad
+ * form, but this routine is probably being run as part of an
+ * initialization sequence so the effect shouldn't be too severe.
+ */
+ _ISR_Disable (level);
+
+ for (i = 0 ; i < M360_NUM_DPRAM_REAGONS ; i++) {
+
+ /*
+ * Verify that the region exists.
+ * This test is necessary since some chips have
+ * less dual-port RAM.
+ */
+ if (ptr->bdregions[i].used == 0) {
+ volatile unsigned char *cp = ptr->bdregions[i].base;
+ *cp = 0xAA;
+ if (*cp != 0xAA) {
+ ptr->bdregions[i].used = ptr->bdregions[i].size;
+ continue;
+ }
+ *cp = 0x55;
+ if (*cp != 0x55) {
+ ptr->bdregions[i].used = ptr->bdregions[i].size;
+ continue;
+ }
+ *cp = 0x0;
+ }
+
+ have = ptr->bdregions[i].size - ptr->bdregions[i].used;
+ if (have >= want) {
+ bdp = ptr->bdregions[i].base + ptr->bdregions[i].used;
+ ptr->bdregions[i].used += want;
+ break;
+ }
+ }
+ _ISR_Enable (level);
+ if (bdp == NULL){
+ printk("rtems_panic can't allocate %d buffer descriptor(s).\n");
+ rtems_panic ("Can't allocate %d buffer descriptor(s).\n", count);
+ }
+ return bdp;
+}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/console.c b/c/src/lib/libbsp/powerpc/ep1a/console/console.c
new file mode 100644
index 0000000000..87f40d1c3c
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/console.c
@@ -0,0 +1,350 @@
+/*
+ * This file contains the TTY driver for the ep1a
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <termios.h>
+
+#include "console.h"
+#include <rtems/bspIo.h>
+
+/*
+ * Load configuration table
+ */
+#include "config.c"
+
+#define NUM_CONSOLE_PORTS (sizeof(Console_Port_Tbl)/sizeof(console_tbl))
+
+console_data Console_Port_Data[NUM_CONSOLE_PORTS];
+unsigned long Console_Port_Count;
+rtems_device_minor_number Console_Port_Minor;
+
+/* PAGE
+ *
+ * console_open
+ *
+ * open a port as a termios console.
+ *
+ */
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_status_code status;
+ rtems_libio_open_close_args_t *args = arg;
+ rtems_libio_ioctl_args_t IoctlArgs;
+ struct termios Termios;
+ rtems_termios_callbacks Callbacks;
+ console_fns *c;
+
+ /*
+ * Verify the port number is valid.
+ */
+ if(minor>Console_Port_Count)
+ {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ /*
+ * open the port as a termios console driver.
+ */
+ c = Console_Port_Tbl[minor].pDeviceFns;
+ Callbacks.firstOpen = c->deviceFirstOpen;
+ Callbacks.lastClose = c->deviceLastClose;
+ Callbacks.pollRead = c->deviceRead;
+ Callbacks.write = c->deviceWrite;
+ Callbacks.setAttributes = c->deviceSetAttributes;
+ Callbacks.stopRemoteTx =
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx;
+ Callbacks.startRemoteTx =
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx;
+ Callbacks.outputUsesInterrupts = c->deviceOutputUsesInterrupts;
+ status = rtems_termios_open ( major, minor, arg, &Callbacks);
+ Console_Port_Data[minor].termios_data = args->iop->data1;
+
+ if(minor!=Console_Port_Minor)
+ {
+ /*
+ * If this is not the console we do not want ECHO and
+ * so forth
+ */
+ IoctlArgs.iop=args->iop;
+ IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
+ IoctlArgs.buffer=&Termios;
+ rtems_termios_ioctl(&IoctlArgs);
+ Termios.c_lflag=ICANON;
+ IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
+ rtems_termios_ioctl(&IoctlArgs);
+ }
+
+ if((args->iop->flags&LIBIO_FLAGS_READ) &&
+ Console_Port_Tbl[minor].pDeviceFlow &&
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx)
+ {
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
+ }
+
+ return status;
+}
+
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_open_close_args_t *args = arg;
+
+ if((args->iop->flags&LIBIO_FLAGS_READ) &&
+ Console_Port_Tbl[minor].pDeviceFlow &&
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx)
+ {
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
+ }
+
+ return rtems_termios_close (arg);
+}
+
+rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_read (arg);
+}
+
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_write (arg);
+}
+
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_ioctl (arg);
+}
+
+/* PAGE
+ *
+ * console_initialize
+ *
+ * Routine called to initialize the console device driver.
+ */
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+
+ /*
+ * initialize the termio interface.
+ */
+ rtems_termios_initialize();
+
+ Console_Port_Count=NUM_CONSOLE_PORTS;
+
+ for(minor=0;
+ minor<Console_Port_Count;
+ minor++)
+ {
+ /*
+ * First perform the configuration dependant probe, then the
+ * device dependant probe
+ */
+ if((!Console_Port_Tbl[minor].deviceProbe ||
+ Console_Port_Tbl[minor].deviceProbe(minor)) &&
+ Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
+ {
+ /*
+ * Use this device for the console
+ */
+ break;
+ }
+ }
+ if(minor==Console_Port_Count)
+ {
+ /*
+ * Failed to find a working device
+ */
+ rtems_fatal_error_occurred(RTEMS_IO_ERROR);
+ }
+
+ Console_Port_Minor=minor;
+
+ /*
+ * Register Device Names
+ */
+
+ status = rtems_io_register_name("/dev/console",
+ major,
+ Console_Port_Minor );
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+ if ( Console_Port_Tbl[minor].pDeviceFns->deviceInitialize )
+ Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(
+ Console_Port_Minor);
+
+ for(minor++;minor<Console_Port_Count;minor++)
+ {
+ /*
+ * First perform the configuration dependant probe, then the
+ * device dependant probe
+ */
+ if((!Console_Port_Tbl[minor].deviceProbe ||
+ Console_Port_Tbl[minor].deviceProbe(minor)) &&
+ Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
+ {
+ status = rtems_io_register_name(
+ Console_Port_Tbl[minor].sDeviceName,
+ major,
+ minor );
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+
+ /*
+ * Initialize the hardware device.
+ */
+ if ( Console_Port_Tbl[minor].pDeviceFns->deviceInitialize )
+ Console_Port_Tbl[minor].pDeviceFns->deviceInitialize( minor);
+ }
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * DEBUG_puts
+ *
+ * This should be safe in the event of an error. It attempts to ensure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * string - pointer to debug output string
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void DEBUG_puts(
+ char *string
+)
+{
+ char *s;
+ unsigned32 Irql;
+
+ rtems_interrupt_disable(Irql);
+
+ for ( s = string ; *s ; s++ )
+ {
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, *s);
+ }
+
+ rtems_interrupt_enable(Irql);
+}
+
+/* PAGE
+ *
+ * DEBUG_puth
+ *
+ * This should be safe in the event of an error. It attempts to ensure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * ulHexNum - value to display
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void
+DEBUG_puth(
+ unsigned32 ulHexNum
+ )
+{
+ unsigned long i,d;
+ unsigned32 Irql;
+
+ rtems_interrupt_disable(Irql);
+
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, '0');
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, 'x');
+
+ for(i=32;i;)
+ {
+ i-=4;
+ d=(ulHexNum>>i)&0xf;
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor,
+ (d<=9) ? d+'0' : d+'a'-0xa);
+ }
+
+ rtems_interrupt_enable(Irql);
+}
+
+
+/* const char arg to be compatible with BSP_output_char decl. */
+void
+debug_putc_onlcr(const char c)
+{
+ volatile int i;
+
+ /*
+ * Note: Hack to get printk to work. Depends upon bit
+ * and silverchip to initialize the port and just
+ * forces a character to be polled out of com1
+ * regardless of where the console is.
+ */
+
+ volatile unsigned char *ptr = (void *)0xff800000;
+
+ if ('\n'==c){
+ *ptr = '\r';
+ asm volatile("sync");
+ for (i=0;i<0x0fff;i++);
+ }
+
+ *ptr = c;
+ asm volatile("sync");
+ for (i=0;i<0x0fff;i++);
+}
+
+BSP_output_char_function_type BSP_output_char = debug_putc_onlcr;
+/* const char arg to be compatible with BSP_output_char decl. */
+
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/console.h b/c/src/lib/libbsp/powerpc/ep1a/console/console.h
new file mode 100644
index 0000000000..1ea45595bd
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/console.h
@@ -0,0 +1,38 @@
+/*
+ * This file contains the TTY driver table definition for the PPCn_60x
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+*/
+
+#include <rtems/ringbuf.h>
+#include <libchip/serial.h>
+#include <libchip/ns16550.h>
+
+extern console_tbl Console_Port_Tbl[];
+extern console_data Console_Port_Data[];
+extern unsigned long Console_Port_Count;
+
+boolean Console_Port_Tbl_Init_ppc8245(int minor);
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/init68360.c b/c/src/lib/libbsp/powerpc/ep1a/console/init68360.c
new file mode 100644
index 0000000000..1bc1be3aad
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/init68360.c
@@ -0,0 +1,670 @@
+/*
+ * MC68360 support routines
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include "m68360.h"
+
+/*
+ * Send a command to the CPM RISC processer
+ */
+
+void M360ExecuteRISC( volatile m360_t *m360, rtems_unsigned16 command)
+{
+ rtems_unsigned16 sr;
+
+ rtems_interrupt_disable(sr);
+ while (m360->cr & M360_CR_FLG)
+ continue;
+ m360->cr = command | M360_CR_FLG;
+ rtems_interrupt_enable(sr);
+}
+
+
+#if 0
+/*
+ * Initialize MC68360
+ */
+void _Init68360 (void)
+{
+ int i;
+ m68k_isr_entry *vbr;
+ unsigned long ramSize;
+ extern void _CopyDataClearBSSAndStart (unsigned long ramSize);
+
+#if (defined (__mc68040__))
+ /*
+ *******************************************
+ * Motorola 68040 and companion-mode 68360 *
+ *******************************************
+ */
+
+ /*
+ * Step 6: Is this a power-up reset?
+ * For now we just ignore this and do *all* the steps
+ * Someday we might want to:
+ * if (Hard, Loss of Clock, Power-up)
+ * Do all steps
+ * else if (Double bus fault, watchdog or soft reset)
+ * Skip to step 12
+ * else (must be a reset command)
+ * Skip to step 14
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external 25 MHz oscillator.
+ */
+ m360.clkocr = 0x83; /* No more writes, full-power CLKO2 */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT standard M68000 family interrupt level encoding
+ * CF1MODE=10 (BCLRO* output)
+ * No RAS1* double drive
+ * A31 - A28
+ * AMUX output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ */
+ m360.pepar = 0x3440;
+
+ /*
+ * Step 11: Remap Chip Select 0 (CS0*), set up GMR
+ */
+ /*
+ * 512 addresses per DRAM page (256K DRAM chips)
+ * 70 nsec DRAM
+ * 180 nsec ROM (3 wait states)
+ */
+ m360.gmr = M360_GMR_RCNT(23) | M360_GMR_RFEN |
+ M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
+ M360_GMR_DPS_32BIT | M360_GMR_NCS |
+ M360_GMR_TSS40;
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_32BIT;
+
+ /*
+ * Step 12: Initialize the system RAM
+ */
+ /*
+ * Set up option/base registers
+ * 1M DRAM
+ * 70 nsec DRAM
+ * Enable burst mode
+ * No parity checking
+ * Wait for chips to power up
+ * Perform 8 read cycles
+ */
+ ramSize = 1 * 1024 * 1024;
+ m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
+ M360_MEMC_OR_1MB |
+ M360_MEMC_OR_DRAM;
+ m360.memc[1].br = (unsigned long)&_RamBase |
+ M360_MEMC_BR_BACK40 |
+ M360_MEMC_BR_V;
+ for (i = 0; i < 50000; i++)
+ continue;
+ for (i = 0; i < 8; ++i)
+ *((volatile unsigned long *)(unsigned long)&_RamBase);
+
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Bus request MC68040 Arbitration ID 3
+ * Bus asynchronous timing mode (work around bug in Rev. B)
+ * Arbitration asynchronous timing mode
+ * Disable timers during FREEZE
+ * Disable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ * No show cycles
+ * User/supervisor access
+ * Bus clear in arbitration ID level 3
+ * SIM60 interrupt sources higher priority than CPM
+ */
+ m360.mcr = 0x6000EC3F;
+
+#elif (defined (M68360_ATLAS_HSB))
+ /*
+ ******************************************
+ * Standalone Motorola 68360 -- ATLAS HSB *
+ ******************************************
+ */
+
+ /*
+ * Step 6: Is this a power-up reset?
+ * For now we just ignore this and do *all* the steps
+ * Someday we might want to:
+ * if (Hard, Loss of Clock, Power-up)
+ * Do all steps
+ * else if (Double bus fault, watchdog or soft reset)
+ * Skip to step 12
+ * else (must be a CPU32+ reset command)
+ * Skip to step 14
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external 25 MHz oscillator.
+ */
+ m360.clkocr = 0x8F; /* No more writes, no clock outputs */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT not used (CPU32+ mode)
+ * CF1MODE=00 (CONFIG1 input)
+ * RAS1* double drive
+ * WE0* - WE3*
+ * OE* output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ * HARDWARE:
+ * Change if you are using a different memory configuration
+ * (static RAM, external address multiplexing, etc).
+ */
+ m360.pepar = 0x0180;
+
+ /*
+ * Step 11: Remap Chip Select 0 (CS0*), set up GMR
+ */
+ m360.gmr = M360_GMR_RCNT(12) | M360_GMR_RFEN |
+ M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
+ M360_GMR_DPS_32BIT | M360_GMR_DWQ |
+ M360_GMR_GAMX;
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_8BIT;
+
+ /*
+ * Step 12: Initialize the system RAM
+ */
+ ramSize = 2 * 1024 * 1024;
+ /* first bank 1MByte DRAM */
+ m360.memc[1].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
+ m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
+
+ /* second bank 1MByte DRAM */
+ m360.memc[2].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
+ m360.memc[2].br = ((unsigned long)&_RamBase + 0x100000) |
+ M360_MEMC_BR_V;
+
+ /* flash rom socket U6 on CS5 */
+ m360.memc[5].br = (unsigned long)ATLASHSB_ROM_U6 | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[5].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
+ M360_MEMC_OR_8BIT;
+
+ /* CSRs on CS7 */
+ m360.memc[7].or = M360_MEMC_OR_TCYC(4) | M360_MEMC_OR_64KB |
+ M360_MEMC_OR_8BIT;
+ m360.memc[7].br = ATLASHSB_ESR | 0x01;
+ for (i = 0; i < 50000; i++)
+ continue;
+ for (i = 0; i < 8; ++i)
+ *((volatile unsigned long *)(unsigned long)&_RamBase);
+
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Disable timers during FREEZE
+ * Enable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ */
+
+#elif (defined (GEN68360_WITH_SRAM))
+ /*
+ ***************************************************
+ * Generic Standalone Motorola 68360 *
+ * As described in MC68360 User's Manual *
+ * But uses SRAM instead of DRAM *
+ * CS0* - 512kx8 flash memory *
+ * CS1* - 512kx32 static RAM *
+ * CS2* - 512kx32 static RAM *
+ ***************************************************
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external oscillator which
+ * oscillates at the system clock rate.
+ */
+ m360.clkocr = 0x8F; /* No more writes, no clock outputs */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT not used (CPU32+ mode)
+ * CF1MODE=00 (CONFIG1 input)
+ * IPIPE1*
+ * WE0* - WE3*
+ * OE* output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ * HARDWARE:
+ * Change if you are using a different memory configuration
+ * (static RAM, external address multiplexing, etc).
+ */
+ m360.pepar = 0x0080;
+
+ /*
+ * Step 11: Set up GMR
+ *
+ */
+ m360.gmr = 0x0;
+
+ /*
+ * Step 11a: Remap 512Kx8 flash memory on CS0*
+ * 2 wait states
+ * Make it read-only for now
+ */
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
+ M360_MEMC_OR_8BIT;
+ /*
+ * Step 12: Set up main memory
+ * 512Kx32 SRAM on CS1*
+ * 512Kx32 SRAM on CS2*
+ * 0 wait states
+ */
+ ramSize = 4 * 1024 * 1024;
+ m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
+ m360.memc[1].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
+ M360_MEMC_OR_32BIT;
+ m360.memc[2].br = ((unsigned long)&_RamBase + 0x200000) | M360_MEMC_BR_V;
+ m360.memc[2].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
+ M360_MEMC_OR_32BIT;
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Disable timers during FREEZE
+ * Enable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ * No show cycles
+ * User/supervisor access
+ * Bus clear interrupt service level 7
+ * SIM60 interrupt sources higher priority than CPM
+ */
+ m360.mcr = 0x4C7F;
+
+#else
+ /*
+ ***************************************************
+ * Generic Standalone Motorola 68360 *
+ * As described in MC68360 User's Manual *
+ * Atlas ACE360 *
+ ***************************************************
+ */
+
+ /*
+ * Step 6: Is this a power-up reset?
+ * For now we just ignore this and do *all* the steps
+ * Someday we might want to:
+ * if (Hard, Loss of Clock, Power-up)
+ * Do all steps
+ * else if (Double bus fault, watchdog or soft reset)
+ * Skip to step 12
+ * else (must be a CPU32+ reset command)
+ * Skip to step 14
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external 25 MHz oscillator.
+ */
+ m360.clkocr = 0x8F; /* No more writes, no clock outputs */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT not used (CPU32+ mode)
+ * CF1MODE=00 (CONFIG1 input)
+ * RAS1* double drive
+ * WE0* - WE3*
+ * OE* output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ * HARDWARE:
+ * Change if you are using a different memory configuration
+ * (static RAM, external address multiplexing, etc).
+ */
+ m360.pepar = 0x0180;
+
+ /*
+ * Step 11: Remap Chip Select 0 (CS0*), set up GMR
+ * 32-bit DRAM
+ * Internal DRAM address multiplexing
+ * 60 nsec DRAM
+ * 180 nsec ROM (3 wait states)
+ * 15.36 usec DRAM refresh interval
+ * The DRAM page size selection is not modified since this
+ * startup code may be running in a bootstrap PROM or in
+ * a program downloaded by the bootstrap PROM.
+ */
+ m360.gmr = (m360.gmr & 0x001C0000) | M360_GMR_RCNT(23) |
+ M360_GMR_RFEN | M360_GMR_RCYC(0) |
+ M360_GMR_DPS_32BIT | M360_GMR_NCS |
+ M360_GMR_GAMX;
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_8BIT;
+
+ /*
+ * Step 12: Initialize the system RAM
+ * Do this only if the DRAM has not already been set up
+ */
+ if ((m360.memc[1].br & M360_MEMC_BR_V) == 0) {
+ /*
+ * Set up GMR DRAM page size, option and base registers
+ * Assume 16Mbytes of DRAM
+ * 60 nsec DRAM
+ */
+ m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(5);
+ m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
+ M360_MEMC_OR_16MB |
+ M360_MEMC_OR_DRAM;
+ m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
+
+ /*
+ * Wait for chips to power up
+ * Perform 8 read cycles
+ */
+ for (i = 0; i < 50000; i++)
+ continue;
+ for (i = 0; i < 8; ++i)
+ *((volatile unsigned long *)(unsigned long)&_RamBase);
+
+ /*
+ * Determine memory size (1, 4, or 16 Mbytes)
+ * Set GMR DRAM page size appropriately.
+ * The OR is left at 16 Mbytes. The bootstrap PROM places its
+ * .data and .bss segments at the top of the 16 Mbyte space.
+ * A 1 Mbyte or 4 Mbyte DRAM will show up several times in
+ * the memory map, but will work with the same bootstrap PROM.
+ */
+ *(volatile char *)&_RamBase = 0;
+ *((volatile char *)&_RamBase+0x00C01800) = 1;
+ if (*(volatile char *)&_RamBase) {
+ m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(1);
+ }
+ else {
+ *((volatile char *)&_RamBase+0x00801000) = 1;
+ if (*(volatile char *)&_RamBase) {
+ m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(3);
+ }
+ }
+
+ /*
+ * Enable parity checking
+ */
+ m360.memc[1].br |= M360_MEMC_BR_PAREN;
+ }
+ switch (m360.gmr & 0x001C0000) {
+ default: ramSize = 4 * 1024 * 1024; break;
+ case M360_GMR_PGS(1): ramSize = 1 * 1024 * 1024; break;
+ case M360_GMR_PGS(3): ramSize = 4 * 1024 * 1024; break;
+ case M360_GMR_PGS(5): ramSize = 16 * 1024 * 1024; break;
+ }
+
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Disable timers during FREEZE
+ * Enable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ * No show cycles
+ * User/supervisor access
+ * Bus clear interrupt service level 7
+ * SIM60 interrupt sources higher priority than CPM
+ */
+ m360.mcr = 0x4C7F;
+#endif
+
+ /*
+ * Copy data, clear BSS, switch stacks and call main()
+ * Must pass ramSize as argument since the data/bss segment
+ * may be overwritten.
+ */
+ _CopyDataClearBSSAndStart (ramSize);
+}
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h b/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h
new file mode 100644
index 0000000000..b5c972107a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h
@@ -0,0 +1,973 @@
+/*
+ * MOTOROLA MC68360 QUAD INTEGRATED COMMUNICATIONS CONTROLLER (QUICC)
+ *
+ * HARDWARE DECLARATIONS
+ *
+ *
+ * Submitted By:
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * 107 North Road
+ * Saskatoon, Saskatchewan, CANADA
+ * S7N 5C6
+ *
+ * eric@skatter.usask.ca
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __MC68360_h
+#define __MC68360_h
+
+#include "rsPMCQ1.h"
+
+/*
+ *************************************************************************
+ * REGISTER SUBBLOCKS *
+ *************************************************************************
+ */
+
+/*
+ * Memory controller registers
+ */
+typedef struct m360MEMCRegisters_ {
+ uint32_t br;
+ uint32_t or;
+ uint32_t _pad[2];
+} m360MEMCRegisters_t;
+
+
+#define M360_GSMR_RFW 0x00000020
+#define M360_GSMR_TDCR_16X 0x00020000
+#define M360_GSMR_RDCR_16X 0x00008000
+#define M360_GSMR_MODE_UART 0x00000004
+#define M360_GSMR_DIAG_LLOOP 0x00000040
+#define M360_GSMR_ENR 0x00000020
+#define M360_GSMR_ENT 0x00000010
+
+#define M360_PSMR_FLC 0x8000
+#define M360_PSMR_SL 0x4000
+#define M360_PSMR_CL8 0x3000
+#define M360_PSMR_UM_NORMAL 0x0000
+#define M360_PSMR_FRZ 0x0200
+#define M360_PSMR_RZS 0x0100
+#define M360_PSMR_SYN 0x0080
+#define M360_PSMR_DRT 0x0040
+#define M360_PSMR_PEN 0x0010
+#define M360_PSMR_RPM_ODD 0x0000
+#define M360_PSMR_RPM_LOW 0x0004
+#define M360_PSMR_RPM_EVEN 0x0008
+#define M360_PSMR_RPM_HI 0x000c
+#define M360_PSMR_TPM_ODD 0x0000
+#define M360_PSMR_TPM_LOW 0x0001
+#define M360_PSMR_TPM_EVEN 0x0002
+#define M360_PSMR_TPM_HI 0x0003
+
+/*
+ * Serial Communications Controller registers
+ */
+typedef struct m360SCCRegisters_ {
+ uint32_t gsmr_l;
+ uint32_t gsmr_h;
+ uint16_t psmr;
+ uint16_t _pad0;
+ uint16_t todr;
+ uint16_t dsr;
+ uint16_t scce;
+ uint16_t _pad1;
+ uint16_t sccm;
+ uint8_t _pad2;
+ uint8_t sccs;
+ uint32_t _pad3[2];
+} m360SCCRegisters_t;
+
+/*
+ * Serial Management Controller registers
+ */
+typedef struct m360SMCRegisters_ {
+ uint16_t _pad0;
+ uint16_t smcmr;
+ uint16_t _pad1;
+ uint8_t smce;
+ uint8_t _pad2;
+ uint16_t _pad3;
+ uint8_t smcm;
+ uint8_t _pad4;
+ uint32_t _pad5;
+} m360SMCRegisters_t;
+
+
+/*
+ *************************************************************************
+ * Miscellaneous Parameters *
+ *************************************************************************
+ */
+typedef struct m360MiscParms_ {
+ uint16_t rev_num;
+ uint16_t _res1;
+ uint32_t _res2;
+ uint32_t _res3;
+} m360MiscParms_t;
+
+/*
+ *************************************************************************
+ * RISC Timers *
+ *************************************************************************
+ */
+typedef struct m360TimerParms_ {
+ uint16_t tm_base;
+ uint16_t _tm_ptr;
+ uint16_t _r_tmr;
+ uint16_t _r_tmv;
+ uint32_t tm_cmd;
+ uint32_t tm_cnt;
+} m360TimerParms_t;
+
+/*
+ * RISC Controller Configuration Register (RCCR)
+ * All other bits in this register are either reserved or
+ * used only with a Motorola-supplied RAM microcode packge.
+ */
+#define M360_RCCR_TIME (1<<15) /* Enable timer */
+#define M360_RCCR_TIMEP(x) ((x)<<8) /* Timer period */
+
+/*
+ * Command register
+ * Set up this register before issuing a M360_CR_OP_SET_TIMER command.
+ */
+#define M360_TM_CMD_V (1<<31) /* Set to enable timer */
+#define M360_TM_CMD_R (1<<30) /* Set for automatic restart */
+#define M360_TM_CMD_TIMER(x) ((x)<<16) /* Select timer */
+#define M360_TM_CMD_PERIOD(x) (x) /* Timer period (16 bits) */
+
+/*
+ *************************************************************************
+ * DMA Controllers *
+ *************************************************************************
+ */
+typedef struct m360IDMAparms_ {
+ uint16_t ibase;
+ uint16_t ibptr;
+ uint32_t _istate;
+ uint32_t _itemp;
+} m360IDMAparms_t;
+
+/*
+ *************************************************************************
+ * Serial Communication Controllers *
+ *************************************************************************
+ */
+typedef struct m360SCCparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+ uint32_t _rcrc;
+ uint32_t _tcrc;
+ union {
+ struct {
+ uint32_t _res0;
+ uint32_t _res1;
+ uint16_t max_idl;
+ uint16_t _idlc;
+ uint16_t brkcr;
+ uint16_t parec;
+ uint16_t frmec;
+ uint16_t nosec;
+ uint16_t brkec;
+ uint16_t brklen;
+ uint16_t uaddr[2];
+ uint16_t _rtemp;
+ uint16_t toseq;
+ uint16_t character[8];
+ uint16_t rccm;
+ uint16_t rccr;
+ uint16_t rlbc;
+ } uart;
+ struct {
+ uint32_t crc_p;
+ uint32_t crc_c;
+ } transparent;
+
+ } un;
+} m360SCCparms_t;
+
+typedef struct m360SCCENparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+ uint32_t _rcrc;
+ uint32_t _tcrc;
+ union {
+ struct {
+ uint32_t _res0;
+ uint32_t _res1;
+ uint16_t max_idl;
+ uint16_t _idlc;
+ uint16_t brkcr;
+ uint16_t parec;
+ uint16_t frmec;
+ uint16_t nosec;
+ uint16_t brkec;
+ uint16_t brklen;
+ uint16_t uaddr[2];
+ uint16_t _rtemp;
+ uint16_t toseq;
+ uint16_t character[8];
+ uint16_t rccm;
+ uint16_t rccr;
+ uint16_t rlbc;
+ } uart;
+ struct {
+ uint32_t c_pres;
+ uint32_t c_mask;
+ uint32_t crcec;
+ uint32_t alec;
+ uint32_t disfc;
+ uint16_t pads;
+ uint16_t ret_lim;
+ uint16_t _ret_cnt;
+ uint16_t mflr;
+ uint16_t minflr;
+ uint16_t maxd1;
+ uint16_t maxd2;
+ uint16_t _maxd;
+ uint16_t dma_cnt;
+ uint16_t _max_b;
+ uint16_t gaddr1;
+ uint16_t gaddr2;
+ uint16_t gaddr3;
+ uint16_t gaddr4;
+ uint32_t _tbuf0data0;
+ uint32_t _tbuf0data1;
+ uint32_t _tbuf0rba0;
+ uint32_t _tbuf0crc;
+ uint16_t _tbuf0bcnt;
+ uint16_t paddr_h;
+ uint16_t paddr_m;
+ uint16_t paddr_l;
+ uint16_t p_per;
+ uint16_t _rfbd_ptr;
+ uint16_t _tfbd_ptr;
+ uint16_t _tlbd_ptr;
+ uint32_t _tbuf1data0;
+ uint32_t _tbuf1data1;
+ uint32_t _tbuf1rba0;
+ uint32_t _tbuf1crc;
+ uint16_t _tbuf1bcnt;
+ uint16_t _tx_len;
+ uint16_t iaddr1;
+ uint16_t iaddr2;
+ uint16_t iaddr3;
+ uint16_t iaddr4;
+ uint16_t _boff_cnt;
+ uint16_t taddr_h;
+ uint16_t taddr_m;
+ uint16_t taddr_l;
+ } ethernet;
+ struct {
+ uint32_t crc_p;
+ uint32_t crc_c;
+ } transparent;
+ } un;
+} m360SCCENparms_t;
+
+/*
+ * Receive and transmit function code register bits
+ * These apply to the function code registers of all devices, not just SCC.
+ */
+#define M360_RFCR_MOT (1<<4)
+#define M360_RFCR_DMA_SPACE 0x8
+#define M360_TFCR_MOT (1<<4)
+#define M360_TFCR_DMA_SPACE 0x8
+
+/*
+ *************************************************************************
+ * Serial Management Controllers *
+ *************************************************************************
+ */
+typedef struct m360SMCparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+ union {
+ struct {
+ uint16_t max_idl;
+ uint16_t _pad0;
+ uint16_t brklen;
+ uint16_t brkec;
+ uint16_t brkcr;
+ uint16_t _r_mask;
+ } uart;
+ struct {
+ uint16_t _pad0[5];
+ } transparent;
+ } un;
+} m360SMCparms_t;
+
+/*
+ * Mode register
+ */
+#define M360_SMCMR_CLEN(x) ((x)<<11) /* Character length */
+#define M360_SMCMR_2STOP (1<<10) /* 2 stop bits */
+#define M360_SMCMR_PARITY (1<<9) /* Enable parity */
+#define M360_SMCMR_EVEN (1<<8) /* Even parity */
+#define M360_SMCMR_SM_GCI (0<<4) /* GCI Mode */
+#define M360_SMCMR_SM_UART (2<<4) /* UART Mode */
+#define M360_SMCMR_SM_TRANSPARENT (3<<4) /* Transparent Mode */
+#define M360_SMCMR_DM_LOOPBACK (1<<2) /* Local loopback mode */
+#define M360_SMCMR_DM_ECHO (2<<2) /* Echo mode */
+#define M360_SMCMR_TEN (1<<1) /* Enable transmitter */
+#define M360_SMCMR_REN (1<<0) /* Enable receiver */
+
+/*
+ * Event and mask registers (SMCE, SMCM)
+ */
+#define M360_SMCE_BRK (1<<4)
+#define M360_SMCE_BSY (1<<2)
+#define M360_SMCE_TX (1<<1)
+#define M360_SMCE_RX (1<<0)
+
+/*
+ *************************************************************************
+ * Serial Peripheral Interface *
+ *************************************************************************
+ */
+typedef struct m360SPIparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+} m360SPIparms_t;
+
+/*
+ * Mode register (SPMODE)
+ */
+#define M360_SPMODE_LOOP (1<<14) /* Local loopback mode */
+#define M360_SPMODE_CI (1<<13) /* Clock invert */
+#define M360_SPMODE_CP (1<<12) /* Clock phase */
+#define M360_SPMODE_DIV16 (1<<11) /* Divide BRGCLK by 16 */
+#define M360_SPMODE_REV (1<<10) /* Reverse data */
+#define M360_SPMODE_MASTER (1<<9) /* SPI is master */
+#define M360_SPMODE_EN (1<<8) /* Enable SPI */
+#define M360_SPMODE_CLEN(x) ((x)<<4) /* Character length */
+#define M360_SPMODE_PM(x) (x) /* Prescaler modulus */
+
+/*
+ * Mode register (SPCOM)
+ */
+#define M360_SPCOM_STR (1<<7) /* Start transmit */
+
+/*
+ * Event and mask registers (SPIE, SPIM)
+ */
+#define M360_SPIE_MME (1<<5) /* Multi-master error */
+#define M360_SPIE_TXE (1<<4) /* Tx error */
+#define M360_SPIE_BSY (1<<2) /* Busy condition*/
+#define M360_SPIE_TXB (1<<1) /* Tx buffer */
+#define M360_SPIE_RXB (1<<0) /* Rx buffer */
+
+/*
+ *************************************************************************
+ * SDMA (SCC, SMC, SPI) Buffer Descriptors *
+ *************************************************************************
+ */
+typedef struct m360BufferDescriptor_ {
+ uint16_t status;
+ uint16_t length;
+ uint32_t buffer; /* this is a void * to the 360 */
+} m360BufferDescriptor_t;
+
+/*
+ * Bits in receive buffer descriptor status word
+ */
+#define M360_BD_EMPTY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_WRAP (1<<13) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_INTERRUPT (1<<12) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_LAST (1<<11) /* Ethernet, SPI */
+#define M360_BD_CONTROL_CHAR (1<<11) /* SCC UART */
+#define M360_BD_FIRST_IN_FRAME (1<<10) /* Ethernet */
+#define M360_BD_ADDRESS (1<<10) /* SCC UART */
+#define M360_BD_CONTINUOUS (1<<9) /* SCC UART, SMC UART, SPI */
+#define M360_BD_MISS (1<<8) /* Ethernet */
+#define M360_BD_IDLE (1<<8) /* SCC UART, SMC UART */
+#define M360_BD_ADDRSS_MATCH (1<<7) /* SCC UART */
+#define M360_BD_LONG (1<<5) /* Ethernet */
+#define M360_BD_BREAK (1<<5) /* SCC UART, SMC UART */
+#define M360_BD_NONALIGNED (1<<4) /* Ethernet */
+#define M360_BD_FRAMING_ERROR (1<<4) /* SCC UART, SMC UART */
+#define M360_BD_SHORT (1<<3) /* Ethernet */
+#define M360_BD_PARITY_ERROR (1<<3) /* SCC UART, SMC UART */
+#define M360_BD_CRC_ERROR (1<<2) /* Ethernet */
+#define M360_BD_OVERRUN (1<<1) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_COLLISION (1<<0) /* Ethernet */
+#define M360_BD_CARRIER_LOST (1<<0) /* SCC UART */
+#define M360_BD_MASTER_ERROR (1<<0) /* SPI */
+
+/*
+ * Bits in transmit buffer descriptor status word
+ * Many bits have the same meaning as those in receiver buffer descriptors.
+ */
+#define M360_BD_READY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_PAD (1<<14) /* Ethernet */
+#define M360_BD_CTS_REPORT (1<<11) /* SCC UART */
+#define M360_BD_TX_CRC (1<<10) /* Ethernet */
+#define M360_BD_DEFER (1<<9) /* Ethernet */
+#define M360_BD_HEARTBEAT (1<<8) /* Ethernet */
+#define M360_BD_PREAMBLE (1<<8) /* SCC UART, SMC UART */
+#define M360_BD_LATE_COLLISION (1<<7) /* Ethernet */
+#define M360_BD_NO_STOP_BIT (1<<7) /* SCC UART */
+#define M360_BD_RETRY_LIMIT (1<<6) /* Ethernet */
+#define M360_BD_RETRY_COUNT(x) (((x)&0x3C)>>2) /* Ethernet */
+#define M360_BD_UNDERRUN (1<<1) /* Ethernet, SPI */
+#define M360_BD_CARRIER_LOST (1<<0) /* Ethernet */
+#define M360_BD_CTS_LOST (1<<0) /* SCC UART */
+
+/*
+ *************************************************************************
+ * IDMA Buffer Descriptors *
+ *************************************************************************
+ */
+typedef struct m360IDMABufferDescriptor_ {
+ uint16_t status;
+ uint16_t _pad;
+ uint32_t length;
+ void *source;
+ void *destination;
+} m360IDMABufferDescriptor_t;
+
+/*
+ *************************************************************************
+ * RISC Communication Processor Module Command Register (CR) *
+ *************************************************************************
+ */
+#define M360_CR_RST (1<<15) /* Reset communication processor */
+#define M360_CR_OP_INIT_RX_TX (0<<8) /* SCC, SMC UART, SMC GCI, SPI */
+#define M360_CR_OP_INIT_RX (1<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_INIT_TX (2<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_INIT_HUNT (3<<8) /* SCC, SMC UART */
+#define M360_CR_OP_STOP_TX (4<<8) /* SCC, SMC UART */
+#define M360_CR_OP_GR_STOP_TX (5<<8) /* SCC */
+#define M360_CR_OP_INIT_IDMA (5<<8) /* IDMA */
+#define M360_CR_OP_RESTART_TX (6<<8) /* SCC, SMC UART */
+#define M360_CR_OP_CLOSE_RX_BD (7<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_SET_GRP_ADDR (8<<8) /* SCC */
+#define M360_CR_OP_SET_TIMER (8<<8) /* Timer */
+#define M360_CR_OP_GCI_TIMEOUT (9<<8) /* SMC GCI */
+#define M360_CR_OP_RESERT_BCS (10<<8) /* SCC */
+#define M360_CR_OP_GCI_ABORT (10<<8) /* SMC GCI */
+#define M360_CR_CHAN_SCC1 (0<<4) /* Channel selection */
+#define M360_CR_CHAN_SCC2 (4<<4)
+#define M360_CR_CHAN_SPI (5<<4)
+#define M360_CR_CHAN_TIMER (5<<4)
+#define M360_CR_CHAN_SCC3 (8<<4)
+#define M360_CR_CHAN_SMC1 (9<<4)
+#define M360_CR_CHAN_IDMA1 (9<<4)
+#define M360_CR_CHAN_SCC4 (12<<4)
+#define M360_CR_CHAN_SMC2 (13<<4)
+#define M360_CR_CHAN_IDMA2 (13<<4)
+#define M360_CR_FLG (1<<0) /* Command flag */
+
+/*
+ *************************************************************************
+ * System Protection Control Register (SYPCR) *
+ *************************************************************************
+ */
+#define M360_SYPCR_SWE (1<<7) /* Software watchdog enable */
+#define M360_SYPCR_SWRI (1<<6) /* Software watchdog reset select */
+#define M360_SYPCR_SWT1 (1<<5) /* Software watchdog timing bit 1 */
+#define M360_SYPCR_SWT0 (1<<4) /* Software watchdog timing bit 0 */
+#define M360_SYPCR_DBFE (1<<3) /* Double bus fault monitor enable */
+#define M360_SYPCR_BME (1<<2) /* Bus monitor external enable */
+#define M360_SYPCR_BMT1 (1<<1) /* Bus monitor timing bit 1 */
+#define M360_SYPCR_BMT0 (1<<0) /* Bus monitor timing bit 0 */
+
+/*
+ *************************************************************************
+ * Memory Control Registers *
+ *************************************************************************
+ */
+#define M360_GMR_RCNT(x) ((x)<<24) /* Refresh count */
+#define M360_GMR_RFEN (1<<23) /* Refresh enable */
+#define M360_GMR_RCYC(x) ((x)<<21) /* Refresh cycle length */
+#define M360_GMR_PGS(x) ((x)<<18) /* Page size */
+#define M360_GMR_DPS_32BIT (0<<16) /* DRAM port size */
+#define M360_GMR_DPS_16BIT (1<<16)
+#define M360_GMR_DPS_8BIT (2<<16)
+#define M360_GMR_DPS_DSACK (3<<16)
+#define M360_GMR_WBT40 (1<<15) /* Wait between 040 transfers */
+#define M360_GMR_WBTQ (1<<14) /* Wait between 360 transfers */
+#define M360_GMR_SYNC (1<<13) /* Synchronous external access */
+#define M360_GMR_EMWS (1<<12) /* External master wait state */
+#define M360_GMR_OPAR (1<<11) /* Odd parity */
+#define M360_GMR_PBEE (1<<10) /* Parity bus error enable */
+#define M360_GMR_TSS40 (1<<9) /* TS* sample for 040 */
+#define M360_GMR_NCS (1<<8) /* No CPU space */
+#define M360_GMR_DWQ (1<<7) /* Delay write for 360 */
+#define M360_GMR_DW40 (1<<6) /* Delay write for 040 */
+#define M360_GMR_GAMX (1<<5) /* Global address mux enable */
+
+#define M360_MEMC_BR_FC(x) ((x)<<7) /* Function code limit */
+#define M360_MEMC_BR_TRLXQ (1<<6) /* Relax timing requirements */
+#define M360_MEMC_BR_BACK40 (1<<5) /* Burst acknowledge to 040 */
+#define M360_MEMC_BR_CSNT40 (1<<4) /* CS* negate timing for 040 */
+#define M360_MEMC_BR_CSNTQ (1<<3) /* CS* negate timing for 360 */
+#define M360_MEMC_BR_PAREN (1<<2) /* Enable parity checking */
+#define M360_MEMC_BR_WP (1<<1) /* Write Protect */
+#define M360_MEMC_BR_V (1<<0) /* Base/Option register are valid */
+
+#define M360_MEMC_OR_TCYC(x) ((x)<<28) /* Cycle length (clocks) */
+#define M360_MEMC_OR_WAITS(x) M360_MEMC_OR_TCYC((x)+1)
+#define M360_MEMC_OR_2KB 0x0FFFF800 /* Address range */
+#define M360_MEMC_OR_4KB 0x0FFFF000
+#define M360_MEMC_OR_8KB 0x0FFFE000
+#define M360_MEMC_OR_16KB 0x0FFFC000
+#define M360_MEMC_OR_32KB 0x0FFF8000
+#define M360_MEMC_OR_64KB 0x0FFF0000
+#define M360_MEMC_OR_128KB 0x0FFE0000
+#define M360_MEMC_OR_256KB 0x0FFC0000
+#define M360_MEMC_OR_512KB 0x0FF80000
+#define M360_MEMC_OR_1MB 0x0FF00000
+#define M360_MEMC_OR_2MB 0x0FE00000
+#define M360_MEMC_OR_4MB 0x0FC00000
+#define M360_MEMC_OR_8MB 0x0F800000
+#define M360_MEMC_OR_16MB 0x0F000000
+#define M360_MEMC_OR_32MB 0x0E000000
+#define M360_MEMC_OR_64MB 0x0C000000
+#define M360_MEMC_OR_128MB 0x08000000
+#define M360_MEMC_OR_256MB 0x00000000
+#define M360_MEMC_OR_FCMC(x) ((x)<<7) /* Function code mask */
+#define M360_MEMC_OR_BCYC(x) ((x)<<5) /* Burst cycle length (clocks) */
+#define M360_MEMC_OR_PGME (1<<3) /* Page mode enable */
+#define M360_MEMC_OR_32BIT (0<<1) /* Port size */
+#define M360_MEMC_OR_16BIT (1<<1)
+#define M360_MEMC_OR_8BIT (2<<1)
+#define M360_MEMC_OR_DSACK (3<<1)
+#define M360_MEMC_OR_DRAM (1<<0) /* Dynamic RAM select */
+
+/*
+ *************************************************************************
+ * SI Mode Register (SIMODE) *
+ *************************************************************************
+ */
+#define M360_SI_SMC2_BITS 0xFFFF0000 /* All SMC2 bits */
+#define M360_SI_SMC2_TDM (1<<31) /* Multiplexed SMC2 */
+#define M360_SI_SMC2_BRG1 (0<<28) /* SMC2 clock souce */
+#define M360_SI_SMC2_BRG2 (1<<28)
+#define M360_SI_SMC2_BRG3 (2<<28)
+#define M360_SI_SMC2_BRG4 (3<<28)
+#define M360_SI_SMC2_CLK5 (0<<28)
+#define M360_SI_SMC2_CLK6 (1<<28)
+#define M360_SI_SMC2_CLK7 (2<<28)
+#define M360_SI_SMC2_CLK8 (3<<28)
+#define M360_SI_SMC1_BITS 0x0000FFFF /* All SMC1 bits */
+#define M360_SI_SMC1_TDM (1<<15) /* Multiplexed SMC1 */
+#define M360_SI_SMC1_BRG1 (0<<12) /* SMC1 clock souce */
+#define M360_SI_SMC1_BRG2 (1<<12)
+#define M360_SI_SMC1_BRG3 (2<<12)
+#define M360_SI_SMC1_BRG4 (3<<12)
+#define M360_SI_SMC1_CLK1 (0<<12)
+#define M360_SI_SMC1_CLK2 (1<<12)
+#define M360_SI_SMC1_CLK3 (2<<12)
+#define M360_SI_SMC1_CLK4 (3<<12)
+
+/*
+ *************************************************************************
+ * SDMA Configuration Register (SDMA) *
+ *************************************************************************
+ */
+#define M360_SDMA_FREEZE (2<<13) /* Freeze on next bus cycle */
+#define M360_SDMA_SISM_7 (7<<8) /* Normal interrupt service mask */
+#define M360_SDMA_SAID_4 (4<<4) /* Normal arbitration ID */
+#define M360_SDMA_INTE (1<<1) /* SBER interrupt enable */
+#define M360_SDMA_INTB (1<<0) /* SBKP interrupt enable */
+
+/*
+ *************************************************************************
+ * Baud (sic) Rate Generators *
+ *************************************************************************
+ */
+#define M360_BRG_RST (1<<17) /* Reset generator */
+#define M360_BRG_EN (1<<16) /* Enable generator */
+#define M360_BRG_EXTC_BRGCLK (0<<14) /* Source is BRGCLK */
+#define M360_BRG_EXTC_CLK2 (1<<14) /* Source is CLK2 pin */
+#define M360_BRG_EXTC_CLK6 (2<<14) /* Source is CLK6 pin */
+#define M360_BRG_ATB (1<<13) /* Autobaud */
+#define M360_BRG_115200 (13<<1) /* Assume 25 MHz clock */
+#define M360_BRG_57600 (26<<1)
+#define M360_BRG_38400 (40<<1)
+#define M360_BRG_19200 (80<<1)
+#define M360_BRG_9600 (162<<1)
+#define M360_BRG_4800 (324<<1)
+#define M360_BRG_2400 (650<<1)
+#define M360_BRG_1200 (1301<<1)
+#define M360_BRG_600 (2603<<1)
+#define M360_BRG_300 ((324<<1) | 1)
+#define M360_BRG_150 ((650<<1) | 1)
+#define M360_BRG_75 ((1301<<1) | 1)
+
+/*
+ *************************************************************************
+ * sccm Bit Settings *
+ *************************************************************************
+ */
+#define M360_SCCE_TX 0x02
+#define M360_SCCE_RX 0x01
+
+#define M360_CR_INIT_TX_RX_PARAMS 0x0000
+#define M360_CR_CH_NUM 0x0040
+
+#define M360_NUM_DPRAM_REAGONS 4
+/*
+ *************************************************************************
+ * MC68360 DUAL-PORT RAM AND REGISTERS *
+ *************************************************************************
+ */
+typedef struct m360_ {
+ /*
+ * Dual-port RAM
+ */
+ volatile uint8_t dpram0[0x400]; /* Microcode program */
+ volatile uint8_t dpram1[0x200];
+ volatile uint8_t dpram2[0x100]; /* Microcode scratch */
+ volatile uint8_t dpram3[0x100]; /* Not on REV A or B masks */
+ volatile uint8_t _rsv0[0xC00-0x800];
+ volatile m360SCCENparms_t scc1p;
+ volatile uint8_t _rsv1[0xCB0-0xC00-sizeof(m360SCCENparms_t)];
+ volatile m360MiscParms_t miscp;
+ volatile uint8_t _rsv2[0xD00-0xCB0-sizeof(m360MiscParms_t)];
+ volatile m360SCCparms_t scc2p;
+ volatile uint8_t _rsv3[0xD80-0xD00-sizeof(m360SCCparms_t)];
+ volatile m360SPIparms_t spip;
+ volatile uint8_t _rsv4[0xDB0-0xD80-sizeof(m360SPIparms_t)];
+ volatile m360TimerParms_t tmp;
+ volatile uint8_t _rsv5[0xE00-0xDB0-sizeof(m360TimerParms_t)];
+ volatile m360SCCparms_t scc3p;
+ volatile uint8_t _rsv6[0xE70-0xE00-sizeof(m360SCCparms_t)];
+ volatile m360IDMAparms_t idma1p;
+ volatile uint8_t _rsv7[0xE80-0xE70-sizeof(m360IDMAparms_t)];
+ volatile m360SMCparms_t smc1p;
+ volatile uint8_t _rsv8[0xF00-0xE80-sizeof(m360SMCparms_t)];
+ volatile m360SCCparms_t scc4p;
+ volatile uint8_t _rsv9[0xF70-0xF00-sizeof(m360SCCparms_t)];
+ volatile m360IDMAparms_t idma2p;
+ volatile uint8_t _rsv10[0xF80-0xF70-sizeof(m360IDMAparms_t)];
+ volatile m360SMCparms_t smc2p;
+ volatile uint8_t _rsv11[0x1000-0xF80-sizeof(m360SMCparms_t)];
+
+ /*
+ * SIM Block
+ */
+ volatile uint32_t mcr;
+ volatile uint32_t _pad00;
+ volatile uint8_t avr;
+ volatile uint8_t rsr;
+ volatile uint16_t _pad01;
+ volatile uint8_t clkocr;
+ volatile uint8_t _pad02;
+ volatile uint16_t _pad03;
+ volatile uint16_t pllcr;
+ volatile uint16_t _pad04;
+ volatile uint16_t cdvcr;
+ volatile uint16_t pepar;
+ volatile uint32_t _pad05[2];
+ volatile uint16_t _pad06;
+ volatile uint8_t sypcr;
+ volatile uint8_t swiv;
+ volatile uint16_t _pad07;
+ volatile uint16_t picr;
+ volatile uint16_t _pad08;
+ volatile uint16_t pitr;
+ volatile uint16_t _pad09;
+ volatile uint8_t _pad10;
+ volatile uint8_t swsr;
+ volatile uint32_t bkar;
+ volatile uint32_t bcar;
+ volatile uint32_t _pad11[2];
+
+ /*
+ * MEMC Block
+ */
+ volatile uint32_t gmr;
+ volatile uint16_t mstat;
+ volatile uint16_t _pad12;
+ volatile uint32_t _pad13[2];
+ volatile m360MEMCRegisters_t memc[8];
+ volatile uint8_t _pad14[0xF0-0xD0];
+ volatile uint8_t _pad15[0x100-0xF0];
+ volatile uint8_t _pad16[0x500-0x100];
+
+ /*
+ * IDMA1 Block
+ */
+ volatile uint16_t iccr;
+ volatile uint16_t _pad17;
+ volatile uint16_t cmr1;
+ volatile uint16_t _pad18;
+ volatile uint32_t sapr1;
+ volatile uint32_t dapr1;
+ volatile uint32_t bcr1;
+ volatile uint8_t fcr1;
+ volatile uint8_t _pad19;
+ volatile uint8_t cmar1;
+ volatile uint8_t _pad20;
+ volatile uint8_t csr1;
+ volatile uint8_t _pad21;
+ volatile uint16_t _pad22;
+
+ /*
+ * SDMA Block
+ */
+ volatile uint8_t sdsr;
+ volatile uint8_t _pad23;
+ volatile uint16_t sdcr;
+ volatile uint32_t sdar;
+
+ /*
+ * IDMA2 Block
+ */
+ volatile uint16_t _pad24;
+ volatile uint16_t cmr2;
+ volatile uint32_t sapr2;
+ volatile uint32_t dapr2;
+ volatile uint32_t bcr2;
+ volatile uint8_t fcr2;
+ volatile uint8_t _pad26;
+ volatile uint8_t cmar2;
+ volatile uint8_t _pad27;
+ volatile uint8_t csr2;
+ volatile uint8_t _pad28;
+ volatile uint16_t _pad29;
+ volatile uint32_t _pad30;
+
+ /*
+ * CPIC Block
+ */
+ volatile uint32_t cicr;
+ volatile uint32_t cipr;
+ volatile uint32_t cimr;
+ volatile uint32_t cisr;
+
+ /*
+ * Parallel I/O Block
+ */
+ volatile uint16_t padir;
+ volatile uint16_t papar;
+ volatile uint16_t paodr;
+ volatile uint16_t padat;
+ volatile uint32_t _pad31[2];
+ volatile uint16_t pcdir;
+ volatile uint16_t pcpar;
+ volatile uint16_t pcso;
+ volatile uint16_t pcdat;
+ volatile uint16_t pcint;
+ volatile uint16_t _pad32;
+ volatile uint32_t _pad33[5];
+
+ /*
+ * TIMER Block
+ */
+ volatile uint16_t tgcr;
+ volatile uint16_t _pad34;
+ volatile uint32_t _pad35[3];
+ volatile uint16_t tmr1;
+ volatile uint16_t tmr2;
+ volatile uint16_t trr1;
+ volatile uint16_t trr2;
+ volatile uint16_t tcr1;
+ volatile uint16_t tcr2;
+ volatile uint16_t tcn1;
+ volatile uint16_t tcn2;
+ volatile uint16_t tmr3;
+ volatile uint16_t tmr4;
+ volatile uint16_t trr3;
+ volatile uint16_t trr4;
+ volatile uint16_t tcr3;
+ volatile uint16_t tcr4;
+ volatile uint16_t tcn3;
+ volatile uint16_t tcn4;
+ volatile uint16_t ter1;
+ volatile uint16_t ter2;
+ volatile uint16_t ter3;
+ volatile uint16_t ter4;
+ volatile uint32_t _pad36[2];
+
+ /*
+ * CP Block
+ */
+ volatile uint16_t cr;
+ volatile uint16_t _pad37;
+ volatile uint16_t rccr;
+ volatile uint16_t _pad38;
+ volatile uint32_t _pad39[3];
+ volatile uint16_t _pad40;
+ volatile uint16_t rter;
+ volatile uint16_t _pad41;
+ volatile uint16_t rtmr;
+ volatile uint32_t _pad42[5];
+
+ /*
+ * BRG Block
+ */
+ volatile uint32_t brgc1;
+ volatile uint32_t brgc2;
+ volatile uint32_t brgc3;
+ volatile uint32_t brgc4;
+
+ /*
+ * SCC Block
+ */
+ volatile m360SCCRegisters_t scc1;
+ volatile m360SCCRegisters_t scc2;
+ volatile m360SCCRegisters_t scc3;
+ volatile m360SCCRegisters_t scc4;
+
+ /*
+ * SMC Block
+ */
+ volatile m360SMCRegisters_t smc1;
+ volatile m360SMCRegisters_t smc2;
+
+ /*
+ * SPI Block
+ */
+ volatile uint16_t spmode;
+ volatile uint16_t _pad43[2];
+ volatile uint8_t spie;
+ volatile uint8_t _pad44;
+ volatile uint16_t _pad45;
+ volatile uint8_t spim;
+ volatile uint8_t _pad46[2];
+ volatile uint8_t spcom;
+ volatile uint16_t _pad47[2];
+
+ /*
+ * PIP Block
+ */
+ volatile uint16_t pipc;
+ volatile uint16_t _pad48;
+ volatile uint16_t ptpr;
+ volatile uint32_t pbdir;
+ volatile uint32_t pbpar;
+ volatile uint16_t _pad49;
+ volatile uint16_t pbodr;
+ volatile uint32_t pbdat;
+ volatile uint32_t _pad50[6];
+
+ /*
+ * SI Block
+ */
+ volatile uint32_t simode;
+ volatile uint8_t sigmr;
+ volatile uint8_t _pad51;
+ volatile uint8_t sistr;
+ volatile uint8_t sicmr;
+ volatile uint32_t _pad52;
+ volatile uint32_t sicr;
+ volatile uint16_t _pad53;
+ volatile uint16_t sirp[2];
+ volatile uint16_t _pad54;
+ volatile uint32_t _pad55[2];
+ volatile uint8_t siram[256];
+} m360_t;
+
+struct bdregions_t {
+ char *base;
+ unsigned int size;
+ unsigned int used;
+};
+
+#define M68360_RX_BUF_SIZE 1
+#define M68360_TX_BUF_SIZE 0x100
+
+struct _m68360_per_chip;
+typedef struct _m68360_per_chip *M68360_t;
+
+typedef struct _m68360_per_port {
+ uint32_t channel;
+ M68360_t chip;
+ volatile uint32_t *pBRGC; /* m360->brgc# */
+ volatile m360SCCparms_t *pSCCB; /* m360->scc#p */
+ volatile m360SCCRegisters_t *pSCCR; /* m360->scc# */
+ uint32_t baud;
+ int minor;
+ volatile uint8_t *rxBuf;
+ volatile uint8_t *txBuf;
+ volatile m360BufferDescriptor_t *sccRxBd;
+ volatile m360BufferDescriptor_t *sccTxBd;
+}m68360_per_port_t, *M68360_serial_ports_t;
+
+typedef struct _m68360_per_chip {
+ struct _m68360_per_chip *next;
+ struct bdregions_t bdregions[4];
+ volatile m360_t *m360; /* Pointer to base Address */
+ int m360_interrupt;
+ int m360_clock_rate;
+ PPMCQ1BoardData board_data;
+ m68360_per_port_t port[4];
+} m68360_per_chip_t;
+
+extern M68360_t M68360_chips;
+
+void M360SetupMemory( M68360_t ptr );
+void *M360AllocateBufferDescriptors (M68360_t ptr, int count);
+void M360ExecuteRISC( volatile m360_t *m360, uint16_t command);
+int mc68360_scc_create_chip( PPMCQ1BoardData BoardData, uint8_t int_vector );
+
+#endif /* __MC68360_h */
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c b/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c
new file mode 100644
index 0000000000..773f85b93a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c
@@ -0,0 +1,836 @@
+/* This file contains the termios TTY driver for the Motorola MC68360 SCC ports.
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <termios.h>
+#include <bsp.h>
+#include <libcpu/io.h>
+#include <rtems/libio.h>
+#include <bsp/pci.h>
+#include <bsp/irq.h>
+#include <libchip/serial.h>
+#include "m68360.h"
+#include <libchip/sersupp.h>
+#include <stdlib.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+
+#define MC68360_LENGHT_SIZE 100
+int mc68360_length_array[ MC68360_LENGHT_SIZE ];
+int mc68360_length_count=0;
+
+void mc68360_Show_length_array() {
+ int i;
+ for (i=0; i<MC68360_LENGHT_SIZE; i++)
+ printf(" %d", mc68360_length_array[i] );
+ printf("\n\n");
+}
+
+M68360_t M68360_chips = NULL;
+
+#define SYNC eieio
+
+void mc68360_scc_nullFunc() {}
+
+uint8_t scc_read8(
+ const char *name,
+ volatile uint8_t *address
+)
+{
+ uint8_t value;
+
+#ifdef DEBUG_360
+ printk( "RD8 %s 0x%08x ", name, address );
+#endif
+ value = *address;
+#ifdef DEBUG_360
+ printk( "0x%02x\n", value );
+#endif
+
+ return value;
+}
+
+void scc_write8(
+ const char *name,
+ volatile uint8_t *address,
+ uint8_t value
+)
+{
+#ifdef DEBUG_360
+ printk( "WR8 %s 0x%08x 0x%02x\n", name, address, value );
+#endif
+ *address = value;
+}
+
+
+uint16_t scc_read16(
+ const char *name,
+ volatile uint16_t *address
+)
+{
+ uint16_t value;
+
+#ifdef DEBUG_360
+ printk( "RD16 %s 0x%08x ", name, address );
+#endif
+ value = *address;
+#ifdef DEBUG_360
+ printk( "0x%04x\n", value );
+#endif
+
+ return value;
+}
+
+void scc_write16(
+ const char *name,
+ volatile uint16_t *address,
+ uint16_t value
+)
+{
+#ifdef DEBUG_360
+ printk( "WR16 %s 0x%08x 0x%04x\n", name, address, value );
+#endif
+ *address = value;
+}
+
+
+uint32_t scc_read32(
+ const char *name,
+ volatile uint32_t *address
+)
+{
+ uint32_t value;
+
+#ifdef DEBUG_360
+ printk( "RD32 %s 0x%08x ", name, address );
+#endif
+ value = *address;
+#ifdef DEBUG_360
+ printk( "0x%08x\n", value );
+#endif
+
+ return value;
+}
+
+void scc_write32(
+ const char *name,
+ volatile uint32_t *address,
+ uint32_t value
+)
+{
+#ifdef DEBUG_360
+ printk( "WR32 %s 0x%08x 0x%08x\n", name, address, value );
+#endif
+ *address = value;
+}
+
+void mc68360_sccShow_Regs(int minor){
+ M68360_serial_ports_t ptr;
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+
+ printk( "scce 0x%08x", &ptr->pSCCR->scce );
+ printk( " 0x%04x\n", ptr->pSCCR->scce );
+
+}
+
+#define TX_BUFFER_ADDRESS( _ptr ) \
+ ((char *)ptr->txBuf - (char *)ptr->chip->board_data->baseaddr)
+#define RX_BUFFER_ADDRESS( _ptr ) \
+ ((char *)ptr->rxBuf - (char *)ptr->chip->board_data->baseaddr)
+
+
+/**************************************************************************
+ * Function: mc68360_sccBRGC *
+ **************************************************************************
+ * Description: *
+ * *
+ * This function is called to compute the divisor register values for *
+ * a given baud rate. *
+ * *
+ * *
+ * Inputs: *
+ * *
+ * int baud - Baud rate (in bps). *
+ * *
+ * Output: *
+ * *
+ * int - baud rate generator configuration. *
+ * *
+ **************************************************************************/
+static int
+mc68360_sccBRGC(int baud, int m360_clock_rate)
+{
+ int data;
+
+ /*
+ * configure baud rate generator for 16x bit rate, where.....
+ * b = desired baud rate
+ * clk = system clock (33mhz)
+ * d = clock dividor value
+ *
+ * for b > 300 : d = clk/(b*16)
+ * for b<= 300 : d = (clk/ (b*16*16))-1)
+ */
+
+ SYNC();
+ if( baud > 300 ) data = 33333333 / (baud * 16 );
+ else data = (33333333 / (baud * 16 * 16) ) - 1;
+ data *= 2;
+ data &= 0x00001ffe ;
+
+ /* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
+ data |= ((baud>300)? 0 : 1 ) ;
+ data |= 0x010000 ;
+
+ return data;
+}
+
+
+/**************************************************************************
+ * Function: sccInterruptHandler *
+ **************************************************************************
+ * Description: *
+ * *
+ * This is the interrupt service routine for the console UART. It *
+ * handles both receive and transmit interrupts. The bulk of the *
+ * work is done by termios. *
+ * *
+ * Inputs: *
+ * *
+ * chip - structure of chip specific information *
+ * *
+ * Output: *
+ * *
+ * none *
+ * *
+ **************************************************************************/
+void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle )
+{
+ volatile m360_t *m360;
+ int port;
+ uint16_t status;
+ uint16_t length;
+ int i;
+ char data;
+ int clear_isr;
+ M68360_t chip = (M68360_t)handle;
+
+ for (port=0; port<4; port++) {
+
+ clear_isr = FALSE;
+ m360 = chip->m360;
+
+ /*
+ * Handle a RX interrupt.
+ */
+ if ( scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x1)
+ {
+ clear_isr = TRUE;
+ scc_write16("scce", &chip->port[port].pSCCR->scce, 0x1 );
+ status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
+ while ((status & M360_BD_EMPTY) == 0)
+ {
+ length= scc_read16("sccRxBd->length",&chip->port[port].sccRxBd->length);
+ for (i=0;i<length;i++) {
+ data= chip->port[port].rxBuf[i];
+ rtems_termios_enqueue_raw_characters(
+ Console_Port_Data[ chip->port[port].minor ].termios_data,
+ &data,
+ 1);
+ }
+ scc_write16( "sccRxBd->status", &chip->port[port].sccRxBd->status,
+ M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
+ status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
+ }
+ }
+
+ /*
+ * Handle a TX interrupt.
+ */
+ if (scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x2)
+ {
+ clear_isr = TRUE;
+ scc_write16("scce", &chip->port[port].pSCCR->scce, 0x2);
+ status = scc_read16("sccTxBd->status", &chip->port[port].sccTxBd->status);
+ if ((status & M360_BD_EMPTY) == 0)
+ {
+ scc_write16("sccTxBd->status",&chip->port[port].sccTxBd->status,0);
+ rtems_termios_dequeue_characters(
+ Console_Port_Data[chip->port[port].minor].termios_data,
+ chip->port[port].sccTxBd->length);
+ }
+ }
+
+ /*
+ * Clear SCC interrupt-in-service bit.
+ */
+ if ( clear_isr )
+ scc_write32( "cisr", &m360->cisr, (0x80000000 >> chip->port[port].channel) );
+ }
+}
+
+/*
+ * mc68360_scc_open
+ *
+ * This function opens a port for communication.
+ *
+ * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
+ */
+
+int mc68360_scc_open(
+ int major,
+ int minor,
+ void * arg
+)
+{
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * mc68360_scc_initialize_interrupts
+ *
+ * This routine initializes the console's receive and transmit
+ * ring buffers and loads the appropriate vectors to handle the interrupts.
+ */
+
+void mc68360_scc_initialize_interrupts(int minor)
+{
+ M68360_serial_ports_t ptr;
+ volatile m360_t *m360;
+ uint32_t data;
+ uint32_t buffers_start;
+ uint32_t tmp_u32;
+
+#ifdef DEBUG_360
+ printk("mc68360_scc_initialize_interrupts: minor %d\n", minor );
+ printk("Console_Port_Tbl[minor].pDeviceParams 0x%08x\n",
+ Console_Port_Tbl[minor].pDeviceParams );
+#endif
+
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+ m360 = ptr->chip->m360;
+#ifdef DEBUG_360
+ printk("m360 0x%08x baseaddr 0x%08x\n",
+ m360, ptr->chip->board_data->baseaddr);
+#endif
+
+ buffers_start = ptr->chip->board_data->baseaddr + 0x00200000 +
+ ( (M68360_RX_BUF_SIZE + M68360_TX_BUF_SIZE) * (ptr->channel-1));
+ ptr->rxBuf = (uint8_t *) buffers_start;
+ ptr->txBuf = (uint8_t *)(buffers_start + M68360_RX_BUF_SIZE);
+#ifdef DEBUG_360
+ printk("rxBuf 0x%08x txBuf 0x%08x\n", ptr->rxBuf, ptr->txBuf );
+#endif
+ /*
+ * Set Channel Drive Enable bits in EPLD
+ */
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
+ SYNC();
+ data |= (PMCQ1_DRIVER_ENABLE_3 | PMCQ1_DRIVER_ENABLE_2 |
+ PMCQ1_DRIVER_ENABLE_1 | PMCQ1_DRIVER_ENABLE_0);
+ PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE, data);
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
+ SYNC();
+
+ /*
+ * Disable the receiver and the transmitter.
+ */
+
+ SYNC();
+ tmp_u32 = scc_read32( "gsmr_l", &ptr->pSCCR->gsmr_l );
+ tmp_u32 &= (~(M360_GSMR_ENR | M360_GSMR_ENT ) ) ;
+ scc_write32( "gsmr_l", &ptr->pSCCR->gsmr_l, tmp_u32 );
+
+ /*
+ * Disable Interrupt Error and Interrupt Breakpoint
+ * Set SAID to 4 XXX - Shouldn't it be 7 for slave mode
+ * Set SAISM to 7
+ */
+ SYNC();
+ scc_write16( "sdcr", &m360->sdcr, 0x0740 );
+
+ /*
+ * Clear status -- reserved interrupt, SDMA channel error, SDMA breakpoint
+ */
+ scc_write8( "sdsr", &m360->sdsr, 0x07 );
+ SYNC();
+
+ /*
+ * Initialize timer information in RISC Controller Configuration Register
+ */
+ scc_write16( "rccr", &m360->rccr, 0x8100 );
+ SYNC();
+
+ /*
+ * XXX
+ */
+ scc_write16( "papar", &m360->papar, 0xffff );
+ scc_write16( "padir", &m360->padir, 0x5500 ); /* From Memo */
+ scc_write16( "paodr", &m360->paodr, 0x0000 );
+ SYNC();
+
+ /*
+ * XXX
+ */
+ scc_write32( "pbpar", &m360->pbpar, 0x00000000 );
+ scc_write32( "pbdir", &m360->pbdir, 0x0003ffff );
+ scc_write32( "pbdat", &m360->pbdat, 0x0000003f );
+ SYNC();
+
+ /*
+ * XXX
+ */
+ scc_write16( "pcpar", &m360->pcpar, 0x0000 );
+ scc_write16( "pcdir", &m360->pcdir, 0x0000 );
+ scc_write16( "pcso", &m360->pcso, 0x0000 );
+ SYNC();
+
+ /*
+ * configure baud rate generator for 16x bit rate, where.....
+ * b = desired baud rate
+ * clk = system clock (33mhz)
+ * d = clock dividor value
+ *
+ * for b > 300 : d = clk/(b*16)
+ * for b<= 300 : d = (clk/ (b*16*16))-1)
+ */
+ SYNC();
+ if( ptr->baud > 300 ) data = 33333333 / (ptr->baud * 16 );
+ else data = (33333333 / (ptr->baud * 16 * 16) ) - 1;
+ data *= 2 ;
+ data &= 0x00001ffe ;
+
+ /* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
+ data |= ((ptr->baud>300)? 0 : 1 ) ;
+ data |= 0x010000 ;
+
+ scc_write32( "pBRGC", ptr->pBRGC, data );
+
+ data = (((ptr->channel-1)*8) | (ptr->channel-1)) ;
+ data = data << ((ptr->channel-1)*8) ;
+ data |= scc_read32( "sicr", &m360->sicr );
+ scc_write32( "sicr", &m360->sicr, data );
+
+ /*
+ * initialise SCC parameter ram
+ */
+ SYNC();
+ scc_write16( "pSCCB->rbase", &ptr->pSCCB->rbase,
+ (char *)(ptr->sccRxBd) - (char *)m360 );
+ scc_write16( "pSCCB->tbase", &ptr->pSCCB->tbase,
+ (char *)(ptr->sccTxBd) - (char *)m360 );
+
+ scc_write8( "pSCCB->rfcr", &ptr->pSCCB->rfcr, 0x15 ); /* 0x15 0x18 */
+ scc_write8( "pSCCB->tfcr", &ptr->pSCCB->tfcr, 0x15 ); /* 0x15 0x18 */
+
+ scc_write16( "pSCCB->mrblr", &ptr->pSCCB->mrblr, M68360_RX_BUF_SIZE );
+
+ /*
+ * initialise tx and rx scc parameters
+ */
+ SYNC();
+ data = M360_CR_INIT_TX_RX_PARAMS | 0x01;
+ data |= (M360_CR_CH_NUM * (ptr->channel-1) );
+ scc_write16( "CR", &m360->cr, data );
+
+ /*
+ * initialise uart specific parameter RAM
+ */
+ SYNC();
+ scc_write16( "pSCCB->un.uart.max_idl", &ptr->pSCCB->un.uart.max_idl, 15000 );
+ scc_write16( "pSCCB->un.uart.brkcr", &ptr->pSCCB->un.uart.brkcr, 0x0001 );
+ scc_write16( "pSCCB->un.uart.parec", &ptr->pSCCB->un.uart.parec, 0x0000 );
+
+ scc_write16( "pSCCB->un,uart.frmec", &ptr->pSCCB->un.uart.frmec, 0x0000 );
+
+ scc_write16( "pSCCB->un.uart.nosec", &ptr->pSCCB->un.uart.nosec, 0x0000 );
+ scc_write16( "pSCCB->un.uart.brkec", &ptr->pSCCB->un.uart.brkec, 0x0000 );
+ scc_write16( "pSCCB->un.uart.uaddr0", &ptr->pSCCB->un.uart.uaddr[0], 0x0000 );
+ scc_write16( "pSCCB->un.uart.uaddr1", &ptr->pSCCB->un.uart.uaddr[1], 0x0000 );
+ scc_write16( "pSCCB->un.uart.toseq", &ptr->pSCCB->un.uart.toseq, 0x0000 );
+ scc_write16( "pSCCB->un.uart.char0",
+ &ptr->pSCCB->un.uart.character[0], 0x0039 );
+ scc_write16( "pSCCB->un.uart.char1",
+ &ptr->pSCCB->un.uart.character[1], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char2",
+ &ptr->pSCCB->un.uart.character[2], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char3",
+ &ptr->pSCCB->un.uart.character[3], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char4",
+ &ptr->pSCCB->un.uart.character[4], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char5",
+ &ptr->pSCCB->un.uart.character[5], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char6",
+ &ptr->pSCCB->un.uart.character[6], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char7",
+ &ptr->pSCCB->un.uart.character[7], 0x8000 );
+
+ scc_write16( "pSCCB->un.uart.rccm", &ptr->pSCCB->un.uart.rccm, 0xc0ff );
+
+ /*
+ * setup buffer descriptor stuff
+ */
+ SYNC();
+ scc_write16( "sccRxBd->status", &ptr->sccRxBd->status, 0x0000 );
+ SYNC();
+ scc_write16( "sccRxBd->length", &ptr->sccRxBd->length, 0x0000 );
+ scc_write16( "sccRxBd->status", &ptr->sccRxBd->status,
+ M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
+ /* XXX Radstone Example writes RX buffer ptr as two u16's */
+ scc_write32( "sccRxBd->buffer", &ptr->sccRxBd->buffer,
+ RX_BUFFER_ADDRESS( ptr ) );
+
+ SYNC();
+ scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0x0000 );
+ SYNC();
+ scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, 0x0000 );
+ /* XXX Radstone Example writes TX buffer ptr as two u16's */
+ scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
+ TX_BUFFER_ADDRESS( ptr ) );
+
+ /*
+ * clear previous events and set interrupt priorities
+ */
+ scc_write16( "pSCCR->scce", &ptr->pSCCR->scce, 0x1bef ); /* From memo */
+ SYNC();
+ SYNC();
+ scc_write32( "cicr", &m360->cicr, 0x001b9f40 );
+ SYNC();
+
+ /* scc_write32( "cicr", &m360->cicr, scc_read32( "cicr", &m360->cicr ) ); */
+
+ scc_write16( "pSCCR->sccm", &ptr->pSCCR->sccm, M360_SCCE_TX | M360_SCCE_RX );
+
+ data = scc_read32("cimr", &m360->cimr);
+ data |= (0x80000000 >> ptr->channel);
+ scc_write32( "cimr", &m360->cimr, data );
+ SYNC();
+ scc_write32( "cipr", &m360->cipr, scc_read32( "cipr", &m360->cipr ) );
+
+ scc_write32( "pSCCR->gsmr_h", &ptr->pSCCR->gsmr_h, M360_GSMR_RFW );
+ scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
+ (M360_GSMR_TDCR_16X | M360_GSMR_RDCR_16X | M360_GSMR_MODE_UART) );
+
+ scc_write16( "pSCCR->dsr", &ptr->pSCCR->dsr, 0x7e7e );
+ SYNC();
+
+ scc_write16( "pSCCR->psmr", &ptr->pSCCR->psmr,
+ (M360_PSMR_CL8 | M360_PSMR_UM_NORMAL | M360_PSMR_TPM_ODD) );
+ SYNC();
+
+ /*
+ * Enable the receiver and the transmitter.
+ */
+
+ SYNC();
+ data = scc_read32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l);
+ scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
+ (data | M360_GSMR_ENR | M360_GSMR_ENT) );
+
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK );
+ data &= (~PMCQ1_INT_MASK_QUICC);
+ PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK, data );
+
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS );
+ data &= (~PMCQ1_INT_STATUS_QUICC);
+ PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS, data );
+}
+
+/*
+ * mc68360_scc_write_support_int
+ *
+ * Console Termios output entry point when using interrupt driven output.
+ */
+
+int mc68360_scc_write_support_int(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ rtems_interrupt_level Irql;
+ M68360_serial_ports_t ptr;
+
+ mc68360_length_array[ mc68360_length_count ] = len;
+ mc68360_length_count++;
+ if ( mc68360_length_count >= MC68360_LENGHT_SIZE )
+ mc68360_length_count=0;
+
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+
+ /*
+ * We are using interrupt driven output and termios only sends us
+ * one character at a time.
+ */
+
+ if ( !len )
+ return 0;
+
+ /*
+ *
+ */
+#ifdef DEBUG_360
+ printk("mc68360_scc_write_support_int: char 0x%x length %d\n",
+ (unsigned int)*buf, len );
+#endif
+ /*
+ * We must copy the data from the global memory space to MC68360 space
+ */
+
+ rtems_interrupt_disable(Irql);
+
+ scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0 );
+ memcpy((void *) ptr->txBuf, buf, len);
+ scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
+ TX_BUFFER_ADDRESS(ptr->txBuf) );
+ scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, len );
+ scc_write16( "sccTxBd->status", &ptr->sccTxBd->status,
+ (M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT) );
+
+ rtems_interrupt_enable(Irql);
+
+ return len;
+}
+
+/*
+ * mc68360_scc_write_polled
+ *
+ * This routine polls out the requested character.
+ */
+
+void mc68360_scc_write_polled(
+ int minor,
+ char cChar
+)
+{
+#ifdef DEBUG_360
+ printk("mc68360_scc_write_polled: %c\n", cChar);
+#endif
+}
+
+/*
+ * mc68681_set_attributes
+ *
+ * This function sets the DUART channel to reflect the requested termios
+ * port settings.
+ */
+
+int mc68360_scc_set_attributes(
+ int minor,
+ const struct termios *t
+)
+{
+ int baud;
+ volatile m360_t *m360;
+ M68360_serial_ports_t ptr;
+
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+ m360 = ptr->chip->m360;
+
+ switch (t->c_cflag & CBAUD)
+ {
+ case B50: baud = 50; break;
+ case B75: baud = 75; break;
+ case B110: baud = 110; break;
+ case B134: baud = 134; break;
+ case B150: baud = 150; break;
+ case B200: baud = 200; break;
+ case B300: baud = 300; break;
+ case B600: baud = 600; break;
+ case B1200: baud = 1200; break;
+ case B1800: baud = 1800; break;
+ case B2400: baud = 2400; break;
+ case B4800: baud = 4800; break;
+ case B9600: baud = 9600; break;
+ case B19200: baud = 19200; break;
+ case B38400: baud = 38400; break;
+ case B57600: baud = 57600; break;
+ case B115200: baud = 115200; break;
+ case B230400: baud = 230400; break;
+ case B460800: baud = 460800; break;
+ default: baud = -1; break;
+ }
+
+ if (baud > 0)
+ {
+ scc_write32(
+ "pBRGC",
+ ptr->pBRGC,
+ mc68360_sccBRGC(baud, ptr->chip->m360_clock_rate)
+ );
+ }
+
+ return 0;
+}
+
+/*
+ * mc68360_scc_close
+ *
+ * This function shuts down the requested port.
+ */
+
+int mc68360_scc_close(
+ int major,
+ int minor,
+ void *arg
+)
+{
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * mc68360_scc_inbyte_nonblocking_polled
+ *
+ * Console Termios polling input entry point.
+ */
+
+int mc68360_scc_inbyte_nonblocking_polled(
+ int minor
+)
+{
+ return -1;
+}
+
+/*
+ * mc68360_scc_write_support_polled
+ *
+ * Console Termios output entry point when using polled output.
+ *
+ */
+
+int mc68360_scc_write_support_polled(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ printk("mc68360_scc_write_support_polled: minor %d char %c len %d\n",
+ minor, buf, len );
+ return 0;
+}
+
+/*
+ * mc68360_scc_init
+ *
+ * This function initializes the DUART to a quiecsent state.
+ */
+
+void mc68360_scc_init(int minor)
+{
+#ifdef DEBUG_360
+ printk("mc68360_scc_init\n");
+#endif
+}
+
+int mc68360_scc_create_chip( PPMCQ1BoardData BoardData, uint8_t int_vector )
+{
+ M68360_t chip;
+ int i;
+
+#ifdef DEBUG_360
+ printk("mc68360_scc_create_chip\n");
+#endif
+
+ /*
+ * Create console structure for this card
+ * XXX - Note Does this need to be moved up to if a QUICC is fitted
+ * section?
+ */
+ if ((chip = malloc(sizeof(struct _m68360_per_chip))) == NULL)
+ {
+ printk("Error Unable to allocate memory for _m68360_per_chip\n");
+ return RTEMS_IO_ERROR;
+ }
+
+ chip->next = M68360_chips;
+ chip->m360 = (void *)BoardData->baseaddr;
+ chip->m360_interrupt = int_vector;
+ chip->m360_clock_rate = 25000000;
+ chip->board_data = BoardData;
+ M68360_chips = chip;
+
+ for (i=1; i<=4; i++) {
+ chip->port[i-1].channel = i;
+ chip->port[i-1].chip = chip;
+ chip->port[i-1].baud = 9600;
+
+ switch( i ) {
+ case 1:
+ chip->port[i-1].pBRGC = &chip->m360->brgc1;
+ chip->port[i-1].pSCCB = (m360SCCparms_t *) &chip->m360->scc1p;
+ chip->port[i-1].pSCCR = &chip->m360->scc1;
+ M360SetupMemory( chip ); /* Do this first time through */
+ break;
+ case 2:
+ chip->port[i-1].pBRGC = &chip->m360->brgc2;
+ chip->port[i-1].pSCCB = &chip->m360->scc2p;
+ chip->port[i-1].pSCCR = &chip->m360->scc2;
+ break;
+ case 3:
+ chip->port[i-1].pBRGC = &chip->m360->brgc3;
+ chip->port[i-1].pSCCB = &chip->m360->scc3p;
+ chip->port[i-1].pSCCR = &chip->m360->scc3;
+ break;
+ case 4:
+ chip->port[i-1].pBRGC = &chip->m360->brgc4;
+ chip->port[i-1].pSCCB = &chip->m360->scc4p;
+ chip->port[i-1].pSCCR = &chip->m360->scc4;
+ break;
+ default:
+ printk("Invalid mc68360 channel %d\n", i);
+ return RTEMS_IO_ERROR;
+ }
+
+ /*
+ * Allocate buffer descriptors.
+ */
+
+ chip->port[i-1].sccRxBd = M360AllocateBufferDescriptors(chip, 1);
+ chip->port[i-1].sccTxBd = M360AllocateBufferDescriptors(chip, 1);
+ }
+
+ rsPMCQ1QuiccIntConnect(
+ chip->board_data->busNo,
+ chip->board_data->slotNo,
+ chip->board_data->funcNo,
+ &mc68360_sccInterruptHandler,
+ chip
+ );
+
+ return RTEMS_SUCCESSFUL;
+}
+
+console_fns mc68360_scc_fns = {
+ libchip_serial_default_probe, /* deviceProbe */
+ mc68360_scc_open, /* deviceFirstOpen */
+ NULL, /* deviceLastClose */
+ NULL, /* deviceRead */
+ mc68360_scc_write_support_int, /* deviceWrite */
+ mc68360_scc_initialize_interrupts, /* deviceInitialize */
+ mc68360_scc_write_polled, /* deviceWritePolled */
+ mc68360_scc_set_attributes, /* deviceSetAttributes */
+ TRUE /* deviceOutputUsesInterrupts */
+};
+
+console_fns mc68360_scc_polled = {
+ libchip_serial_default_probe, /* deviceProbe */
+ mc68360_scc_open, /* deviceFirstOpen */
+ mc68360_scc_close, /* deviceLastClose */
+ mc68360_scc_inbyte_nonblocking_polled, /* deviceRead */
+ mc68360_scc_write_support_polled, /* deviceWrite */
+ mc68360_scc_init, /* deviceInitialize */
+ mc68360_scc_write_polled, /* deviceWritePolled */
+ mc68360_scc_set_attributes, /* deviceSetAttributes */
+ FALSE /* deviceOutputUsesInterrupts */
+};
+
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c
new file mode 100644
index 0000000000..849b10af54
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c
@@ -0,0 +1,47 @@
+/*
+ * This include file contains all console driver definations for the nc16550
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include "console.h"
+
+typedef struct uart_reg
+{
+ unsigned char reg;
+ unsigned char pad[7];
+} uartReg;
+
+unsigned8 Read_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+)
+{
+ struct uart_reg *p = (struct uart_reg *)ulCtrlPort;
+ unsigned8 ucData;
+ ucData = p[ucRegNum].reg;
+ asm volatile("sync");
+ return ucData;
+}
+
+void Write_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+)
+{
+ struct uart_reg *p = (struct uart_reg *)ulCtrlPort;
+ volatile int i;
+ p[ucRegNum].reg = ucData;
+ asm volatile("sync");
+ for (i=0;i<0x08ff;i++);
+}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h
new file mode 100644
index 0000000000..c2aa368b28
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h
@@ -0,0 +1,57 @@
+/* nc16550cfg.h
+ *
+ * This include file contains all console driver definations for the nc16550
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __NS16550_CONFIG_H
+#define __NS16550_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Board specific register access routines
+ */
+
+unsigned8 Read_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+);
+
+void Write_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+);
+
+extern console_fns ns16550_fns_8245;
+extern console_fns ns16550_fns_polled_8245;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c
new file mode 100644
index 0000000000..088502e3b2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c
@@ -0,0 +1,558 @@
+/* rsPMCQ1.c - Radstone PMCQ1 Common Initialisation Code
+ *
+ * Copyright 2000 Radstone Technology
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 2005.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+/*
+DESCRIPTION
+These functions are responsible for scanning for PMCQ1's and setting up
+the Motorola MC68360's if present.
+
+USAGE
+call rsPMCQ1Init() to perform ba sic initialisation of the PMCQ1's.
+*/
+
+/* includes */
+#include <libcpu/io.h>
+#include <bsp/irq.h>
+#include <stdlib.h>
+#include <rtems/bspIo.h>
+#include <bsp/pci.h>
+#include <bsp.h>
+#include "rsPMCQ1.h"
+#include "m68360.h"
+
+/* defines */
+#if 0
+#define DEBUG_360
+#endif
+
+/* Local data */
+PPMCQ1BoardData pmcq1BoardData = NULL;
+
+static unsigned char rsPMCQ1Initialized = FALSE;
+
+/* forward declarations */
+
+/* local Qspan II serial eeprom table */
+static unsigned char rsPMCQ1eeprom[] =
+ {
+ 0x00, /* Byte 0 - PCI_SID */
+ 0x00, /* Byte 1 - PCI_SID */
+ 0x00, /* Byte 2 - PCI_SID */
+ 0x00, /* Byte 3 - PCI_SID */
+ 0x00, /* Byte 4 - PBROM_CTL */
+ 0x00, /* Byte 5 - PBROM_CTL */
+ 0x00, /* Byte 6 - PBROM_CTL */
+ 0x2C, /* Byte 7 - PBTI0_CTL */
+ 0xB0, /* Byte 8 - PBTI1_CTL */
+ 0x00, /* Byte 9 - QBSI0_AT */
+ 0x00, /* Byte 10 - QBSI0_AT */
+ 0x02, /* Byte 11 - QBSI0_AT */
+ 0x00, /* Byte 12 - PCI_ID */
+ 0x07, /* Byte 13 - PCI_ID */
+ 0x11, /* Byte 14 - PCI_ID */
+ 0xB5, /* Byte 15 - PCI_ID */
+ 0x06, /* Byte 16 - PCI_CLASS */
+ 0x80, /* Byte 17 - PCI_CLASS */
+ 0x00, /* Byte 18 - PCI_CLASS */
+ 0x00, /* Byte 19 - PCI_MISC1 */
+ 0x00, /* Byte 20 - PCI_MISC1 */
+ 0xC0, /* Byte 21 - PCI_PMC */
+ 0x00 /* Byte 22 - PCI_BST */
+};
+
+void MsDelay()
+{
+ printk(".");
+}
+
+void write8( int addr, int data ){
+ out_8((void *)addr, (unsigned char)data);
+}
+
+void write16( int addr, int data ) {
+ out_be16((void *)addr, (short)data );
+}
+
+void write32( int addr, int data ) {
+ out_be32((unsigned int *)addr, data );
+}
+
+int read32( int addr){
+ return in_be32((unsigned int *)addr);
+}
+
+
+void rsPMCQ1_scc_nullFunc() {}
+
+/*******************************************************************************
+* rsPMCQ1Int - handle a PMCQ1 interrupt
+*
+* This routine gets called when the QUICC or MA causes
+* an interrupt.
+*
+* RETURNS: NONE.
+*/
+
+void rsPMCQ1Int( void *ptr )
+{
+ unsigned long status;
+ unsigned long status1;
+ unsigned long mask;
+ PPMCQ1BoardData boardData = ptr;
+
+ status = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS );
+ mask = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_MASK );
+
+ if (((mask & PMCQ1_INT_MASK_QUICC) == 0) && (status & PMCQ1_INT_STATUS_QUICC))
+ {
+ /* If there is a handler call it otherwise mask the interrupt */
+ if (boardData->quiccInt) {
+ boardData->quiccInt(boardData->quiccArg);
+ } else {
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC;
+ }
+ }
+
+ if (((mask & PMCQ1_INT_MASK_MA) == 0) && (status & PMCQ1_INT_STATUS_MA))
+ {
+ /* If there is a handler call it otherwise mask the interrupt */
+ if (boardData->maInt) {
+ boardData->maInt(boardData->maArg);
+ } else {
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA;
+ }
+ }
+
+ /* Clear Interrupt on QSPAN */
+ *(unsigned long *)(boardData->bridgeaddr + 0x600) = 0x00001000;
+
+ /* read back the status register to ensure that the pci write has completed */
+ status1 = *(volatile unsigned long *)(boardData->bridgeaddr + 0x600);
+}
+
+
+/*******************************************************************************
+*
+* rsPMCQ1MaIntConnect - connect a MiniAce interrupt routine
+*
+* This routine is called to connect a MiniAce interrupt handler
+* upto a PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1MaIntConnect (
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo, /* Pci Function number of PMCQ1 */
+ rtems_irq_hdl routine,/* interrupt routine */
+ rtems_irq_hdl_param arg /* argument to pass to interrupt routine */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
+ {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->maInt = routine;
+ boardData->maArg = arg;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1MaIntDisconnect - disconnect a MiniAce interrupt routine
+*
+* This routine is called to disconnect a MiniAce interrupt handler
+* from a PMCQ1. It also masks the interrupt source on the PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1MaIntDisconnect(
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo /* Pci Function number of PMCQ1 */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext) {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->maInt = NULL;
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1QuiccIntConnect - connect a Quicc interrupt routine
+*
+* This routine is called to connect a Quicc interrupt handler
+* upto a PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1QuiccIntConnect(
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo, /* Pci Function number of PMCQ1 */
+ rtems_irq_hdl routine,/* interrupt routine */
+ rtems_irq_hdl_param arg /* argument to pass to interrupt routine */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
+ {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->quiccInt = routine;
+ boardData->quiccArg = arg;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+ return (status);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1QuiccIntDisconnect - disconnect a Quicc interrupt routine
+*
+* This routine is called to disconnect a Quicc interrupt handler
+* from a PMCQ1. It also masks the interrupt source on the PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1QuiccIntDisconnect(
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo /* Pci Function number of PMCQ1 */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
+ {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->quiccInt = NULL;
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+*
+* rsPMCQ1Init - initialize the PMCQ1's
+*
+* This routine is called to initialize the PCI card to a quiescent state.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1Init()
+{
+ int busNo;
+ int slotNo;
+ unsigned int baseaddr = 0;
+ unsigned int bridgeaddr = 0;
+ unsigned long pbti0_ctl;
+ int i;
+ unsigned char int_vector;
+ int fun;
+ int temp;
+ PPMCQ1BoardData boardData;
+ rtems_irq_connect_data IrqData = {0,
+ rsPMCQ1Int,
+ NULL,
+ (rtems_irq_enable)rsPMCQ1_scc_nullFunc,
+ (rtems_irq_disable)rsPMCQ1_scc_nullFunc,
+ (rtems_irq_is_enabled)rsPMCQ1_scc_nullFunc,
+ NULL};
+
+ if (rsPMCQ1Initialized)
+ {
+ return RTEMS_SUCCESSFUL;
+ }
+ for (i=0;;i++){
+ if ( pci_find_device(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1, i, &busNo, &slotNo, &fun) != 0 )
+ break;
+
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_2, &baseaddr);
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_0, &bridgeaddr);
+#ifdef DEBUG_360
+ printk("PMCQ1 baseaddr 0x%08x bridgeaddr 0x%08x\n", baseaddr, bridgeaddr );
+#endif
+
+ /* Set function code to normal mode and enable window */
+ pbti0_ctl = *(unsigned long *)(bridgeaddr + 0x100) & 0xff0fffff;
+ eieio();
+ *(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00500080;
+ eieio();
+
+ /* Assert QBUS reset */
+ *(unsigned long *)(bridgeaddr + 0x800) |= 0x00000080;
+ eieio();
+
+ /*
+ * Hold QBus in reset for 1ms
+ */
+ MsDelay();
+
+ /* Take QBUS out of reset */
+ *(unsigned long *)(bridgeaddr + 0x800) &= ~0x00000080;
+ eieio();
+
+ MsDelay();
+
+ /* If a QUICC is fitted initialise it */
+ if (PMCQ1_Read_EPLD(baseaddr, PMCQ1_BUILD_OPTION) & PMCQ1_QUICC_FITTED)
+ {
+#ifdef DEBUG_360
+ printk(" Found QUICC busNo %d slotNo %d\n", busNo, slotNo);
+#endif
+
+ /* Initialise MBAR (must use function code of 7) */
+ *(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00700080;
+ eieio();
+
+ /* place internal 8K SRAM and registers at address 0x0 */
+ *(unsigned long *)(baseaddr + Q1_360_MBAR) = 0x1;
+ eieio();
+
+ /* Set function code to normal mode */
+ *(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00500080;
+ eieio();
+
+ /* Disable the SWT and perform basic initialisation */
+ write8(baseaddr+Q1_360_SIM_SYPCR,0);
+ eieio();
+
+ write32(baseaddr+Q1_360_SIM_MCR,0xa0001029);
+ write16(baseaddr+Q1_360_SIM_PICR,0);
+ write16(baseaddr+Q1_360_SIM_PITR,0);
+
+ write16(baseaddr+Q1_360_CPM_ICCR,0x770);
+ write16(baseaddr+Q1_360_CPM_SDCR,0x770);
+ write32(baseaddr+Q1_360_CPM_CICR,0x00e49f00);
+ write16(baseaddr+Q1_360_SIM_PEPAR,0x2080);
+ eieio();
+
+ /* Enable SRAM */
+ write32(baseaddr+Q1_360_SIM_GMR,0x00001000); /* external master wait state */
+ eieio();
+ write32(baseaddr+Q1_360_SIM_OR0,0x1ff00000); /*| MEMC_OR_FC*/
+ eieio();
+ write32(baseaddr+Q1_360_SIM_BR0,0);
+ eieio();
+ write32(baseaddr+Q1_360_SIM_OR1,(0x5ff00000 | 0x00000780)); /*| MEMC_OR_FC*/
+ eieio();
+ write32(baseaddr+Q1_360_SIM_BR1,(0x00000040 | 0x00000001 | 0x00200280) );
+ eieio();
+ }
+
+ /*
+ * If a second PCI window is present then make it opposite
+ * endian to simplify 1553 integration.
+ */
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_3, &temp);
+ if (temp) {
+ *(unsigned long *)(bridgeaddr + 0x110) |= 0x00500880;
+ }
+
+ /*
+ * Create descriptor structure for this card
+ */
+ if ((boardData = malloc(sizeof(struct _PMCQ1BoardData))) == NULL)
+ {
+ printk("Error Unable to allocate memory for _PMCQ1BoardData\n");
+ return(RTEMS_IO_ERROR);
+ }
+
+ boardData->pNext = pmcq1BoardData;
+ boardData->busNo = busNo;
+ boardData->slotNo = slotNo;
+ boardData->funcNo = 0;
+ boardData->baseaddr = baseaddr;
+ boardData->bridgeaddr = bridgeaddr;
+ boardData->quiccInt = NULL;
+ boardData->maInt = NULL;
+ pmcq1BoardData = boardData;
+ mc68360_scc_create_chip( boardData, int_vector );
+
+ /*
+ * Connect PMCQ1 interrupt handler.
+ */
+ pci_read_config_byte(busNo, slotNo, 0, 0x3c, &int_vector);
+#ifdef DEBUG_360
+ printk("PMCQ1 int_vector %d\n", int_vector);
+#endif
+ IrqData.name = (rtems_irq_symbolic_name)((unsigned int)BSP_PCI_IRQ0 + int_vector);
+ IrqData.handle = boardData;
+ if (!BSP_install_rtems_shared_irq_handler (&IrqData)) {
+ printk("Error installing interrupt handler!\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ /*
+ * Enable PMCQ1 Interrupts from QSPAN-II
+ */
+
+ *(unsigned long *)(bridgeaddr + 0x600) = 0x00001000;
+ eieio();
+ *(unsigned long *)(bridgeaddr + 0x604) |= 0x00001000;
+
+ eieio();
+ }
+
+ if (i > 0)
+ {
+ rsPMCQ1Initialized = TRUE;
+ }
+ return((i > 0) ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1Commission - initialize the serial EEPROM on the QSPAN
+*
+* This routine is called to initialize the EEPROM attached to the QSPAN
+* on the PMCQ1 module. It will load standard settings into any QSPAN's
+* found with apparently uninitialised EEPROM's or PMCQ1's (to allow
+* EEPROM modifications to be performed).
+*/
+
+unsigned int rsPMCQ1Commission( unsigned long busNo, unsigned long slotNo )
+{
+ unsigned int status = RTEMS_IO_ERROR;
+ unsigned int bridgeaddr = 0;
+ unsigned long val;
+ int i;
+ int venId1;
+ int venId2;
+
+ pci_read_config_dword(busNo, slotNo, 0, PCI_VENDOR_ID, &venId1);
+ pci_read_config_dword(busNo, slotNo, 0, PCI_VENDOR_ID, &venId2);
+ if ((venId1 == 0x086210e3) ||
+ (venId2 == PCI_ID(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1)))
+ {
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_0, &bridgeaddr);
+ status = RTEMS_SUCCESSFUL;
+
+ /*
+ * The On board PMCQ1 on an EP1A has a subVendor ID of 0.
+ * A real PMCQ1 also has the sub vendor ID set up.
+ */
+ if ((busNo == 0) && (slotNo == 1)) {
+ *(unsigned long *)rsPMCQ1eeprom = 0;
+ } else {
+ *(unsigned long *)rsPMCQ1eeprom = PCI_ID(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1);
+ }
+
+ for (i = 0; i < 23; i++) {
+ /* Wait until interface not active */
+ while(read32(bridgeaddr + 0x804) & 0x80000000) {
+ rtems_bsp_delay(1);
+ }
+
+ /* Write value */
+ write32(bridgeaddr + 0x804, (rsPMCQ1eeprom[i] << 8) | i);
+
+ /* delay for > 31 usec to allow active bit to become set */
+ rtems_bsp_delay(100);
+
+ /* Wait until interface not active */
+ while(read32(bridgeaddr + 0x804) & 0x80000000) {
+ rtems_bsp_delay(1);
+ }
+
+ /* Re-read value */
+ write32(bridgeaddr + 0x804, 0x40000000 | i);
+
+ /* delay for > 31 usec to allow active bit to become set */
+ rtems_bsp_delay(100);
+
+ /* Wait until interface not active */
+ while((val = read32(bridgeaddr + 0x804)) & 0x80000000) {
+ rtems_bsp_delay(1);
+ }
+
+ if (((val >> 8) & 0xff) != rsPMCQ1eeprom[i]) {
+ printk("Error writing byte %d expected 0x%02x got 0x%02x\n",
+ i, rsPMCQ1eeprom[i], (unsigned char)(val >> 8));
+ status = RTEMS_IO_ERROR;
+ break;
+ }
+ }
+ }
+ return(status);
+}
+
+uint32_t PMCQ1_Read_EPLD( uint32_t base, uint32_t reg )
+{
+ uint32_t data;
+
+ data = ( *((unsigned long *) (base + reg)) );
+#ifdef DEBUG_360
+ printk("EPLD Read 0x%x: 0x%08x\n", reg + base, data );
+#endif
+ return data;
+}
+
+void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data )
+{
+ *((unsigned long *) (base + reg)) = data;
+#ifdef DEBUG_360
+ printk("EPLD Write 0x%x: 0x%08x\n", reg+base, data );
+#endif
+}
+
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h
new file mode 100644
index 0000000000..a38d24db35
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h
@@ -0,0 +1,148 @@
+/* rsPMCQ1.h - Radstone PMCQ1 private header
+ *
+ * Copyright 2000 Radstone Technology
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 2005.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+/*
+ modification history
+ --------------------
+ 01a,20Dec00,jpb created
+ */
+
+#ifndef __INCPMCQ1H
+#define __INCPMCQ1H
+
+#include <libcpu/io.h>
+#include <bsp/irq.h>
+
+/*
+ * PMCQ1 definitions
+ */
+
+/*
+ * 360 definitions
+ */
+
+#define Q1_360_MBAR 0x0003ff00 /* master base address register */
+
+#define REG_B_OFFSET 0x1000 /* offset to the internal registers */
+
+#define Q1_360_SIM_MCR (REG_B_OFFSET+0x00)
+#define Q1_360_SIM_PEPAR (REG_B_OFFSET+0x16)
+#define Q1_360_SIM_SYPCR (REG_B_OFFSET+0x22)
+#define Q1_360_SIM_PICR (REG_B_OFFSET+0x26)
+#define Q1_360_SIM_PITR (REG_B_OFFSET+0x2A)
+#define Q1_360_SIM_GMR (REG_B_OFFSET+0x40)
+#define Q1_360_SIM_BR0 (REG_B_OFFSET+0x50)
+#define Q1_360_SIM_OR0 (REG_B_OFFSET+0x54)
+#define Q1_360_SIM_BR1 (REG_B_OFFSET+0x60)
+#define Q1_360_SIM_OR1 (REG_B_OFFSET+0x64)
+
+#define Q1_360_CPM_ICCR (REG_B_OFFSET+0x500)
+#define Q1_360_CPM_SDCR (REG_B_OFFSET+0x51E)
+#define Q1_360_CPM_CICR (REG_B_OFFSET+0x540)
+
+/*
+ * EPLD offsets
+ *
+ * Only top 4 data bits are used
+ */
+#define PMCQ1_CODE_VERSION 0x00040000 /* Code Version */
+
+#define PMCQ1_BOARD_REVISION 0x00040004 /* Board Revision */
+
+#define PMCQ1_BUILD_OPTION 0x00040008 /* Build Option */
+#define PMCQ1_ACE_FITTED 0x80000000
+#define PMCQ1_QUICC_FITTED 0x40000000
+#define PMCQ1_SRAM_SIZE 0x30000000 /* 01 - 1MB */
+#define PMCQ1_SRAM_FITTED 0x20000000
+
+#define PMCQ1_INT_STATUS 0x0004000c /* Interrupt Status */
+#define PMCQ1_INT_STATUS_MA 0x20000000
+#define PMCQ1_INT_STATUS_QUICC 0x10000000
+
+#define PMCQ1_INT_MASK 0x00040010 /* Interrupt Mask */
+#define PMCQ1_INT_MASK_QUICC 0x20000000
+#define PMCQ1_INT_MASK_MA 0x10000000
+
+#define PMCQ1_RT_ADDRESS 0x00040014 /* RT Address Latch */
+
+#define PMCQ1_DRIVER_ENABLE 0x0004001c /* Channel Drive Enable */
+#define PMCQ1_DRIVER_ENABLE_3 0x80000000
+#define PMCQ1_DRIVER_ENABLE_2 0x40000000
+#define PMCQ1_DRIVER_ENABLE_1 0x20000000
+#define PMCQ1_DRIVER_ENABLE_0 0x10000000
+
+#define PMCQ1_MINIACE_REGS 0x000c0000
+#define PMCQ1_MINIACE_MEM 0x00100000
+#define PMCQ1_RAM 0x00200000
+
+/*
+#define PMCQ1_Read_EPLD( _base, _reg ) ( *((unsigned long *) ((unsigned32)_base + _reg)) )
+#define PMCQ1_Write_EPLD( _base, _reg, _data ) *((unsigned long *) ((unsigned32)_base + _reg)) = _data
+*/
+uint32_t PMCQ1_Read_EPLD( uint32_t base, uint32_t reg );
+void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data );
+
+/*
+ * QSPAN-II register offsets
+ */
+
+#define QSPAN2_INT_STATUS 0x00000600
+
+
+#define PCI_ID(v, d) ((d << 16) | v)
+
+
+#define PCI_VEN_ID_RADSTONE 0x11b5
+#define PCI_DEV_ID_PMC1553 0x0001
+#define PCI_DEV_ID_PMCF1 0x0002
+#define PCI_DEV_ID_PMCMMA 0x0003
+#define PCI_DEV_ID_PMCQ1 0x0007
+#define PCI_DEV_ID_PMCQ2 0x0008
+#define PCI_DEV_ID_PMCF1V2 0x0012
+
+
+
+typedef struct _PMCQ1BoardData
+{
+ struct _PMCQ1BoardData *pNext;
+ unsigned long busNo;
+ unsigned long slotNo;
+ unsigned long funcNo;
+ unsigned long baseaddr;
+ unsigned long bridgeaddr;
+ rtems_irq_hdl quiccInt;
+ rtems_irq_hdl_param quiccArg;
+ rtems_irq_hdl maInt;
+ rtems_irq_hdl_param maArg;
+} PMCQ1BoardData, *PPMCQ1BoardData;
+
+extern PPMCQ1BoardData pmcq1BoardData;
+
+/*
+ * Function declarations
+ */
+extern unsigned int rsPMCQ1QuiccIntConnect(
+ unsigned long busNo, unsigned long slotNo,unsigned long funcNo, rtems_irq_hdl routine,rtems_irq_hdl_param arg );
+unsigned int rsPMCQ1Init();
+
+#endif /* __INCPMCQ1H */