summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc8xx/cpm
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc8xx/cpm')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am38
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c34
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c89
3 files changed, 161 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am
new file mode 100644
index 0000000000..1c9af7e4a3
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am
@@ -0,0 +1,38 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = ${ARCH}/cp.rel
+
+## C sources
+C_FILES = cp.c dpram.c
+
+clock_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CFLAGS = $(CFLAGS_OS_V)
+
+$(PGM): $(clock_rel_OBJECTS)
+ $(make-rel)
+
+all-local: ${ARCH} $(PGM)
+
+EXTRA_DIST = $(C_FILES)
+
+include $(top_srcdir)/../../../../../automake/local.am
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c
new file mode 100644
index 0000000000..235e4bafc3
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c
@@ -0,0 +1,34 @@
+/*
+ * cp.c
+ *
+ * MPC8xx CPM RISC Communication Processor routines.
+ *
+ * Based on code (alloc860.c in eth_comm port) by
+ * Jay Monkman (jmonkman@frasca.com),
+ * which, in turn, is based on code by
+ * W. Eric Norum (eric@skatter.usask.ca).
+ *
+ * Modifications by Darlene Stewart (Darlene.Stewart@iit.nrc.ca):
+ * Copyright (c) 1999, National Research Council of Canada
+ */
+
+#include <bsp.h>
+#include <rtems/rtems/intr.h>
+#include <rtems/error.h>
+
+/*
+ * Send a command to the CPM RISC processer
+ */
+void m8xx_cp_execute_cmd( unsigned16 command )
+{
+ rtems_unsigned16 lvl;
+
+ rtems_interrupt_disable(lvl);
+ while (m8xx.cpcr & M8xx_CR_FLG) {
+ continue;
+ }
+
+ m8xx.cpcr = command | M8xx_CR_FLG;
+ rtems_interrupt_enable (lvl);
+}
+
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c
new file mode 100644
index 0000000000..985b5b5bd1
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c
@@ -0,0 +1,89 @@
+/*
+ * dpram.c
+ *
+ * MPC8xx dual-port RAM allocation routines
+ *
+ * Based on code (alloc860.c in eth_comm port) by
+ * Jay Monkman (jmonkman@frasca.com),
+ * which, in turn, is based on code by
+ * W. Eric Norum (eric@skatter.usask.ca).
+ *
+ *
+ * Modifications :
+ * Copyright (c) 1999, National Research Council of Canada
+ */
+
+#include <bsp.h>
+#include <rtems/rtems/intr.h>
+#include <rtems/error.h>
+
+/*
+ * Allocation order:
+ * - Dual-Port RAM section 0
+ * - Dual-Port RAM section 1
+ * - Dual-Port RAM section 2
+ * - Dual-Port RAM section 3
+ * - Dual-Port RAM section 4
+ */
+static struct {
+ unsigned8 *base;
+ unsigned int size;
+ unsigned int used;
+} dpram_regions[] = {
+ { (char *)&m8xx.dpram0[0], sizeof m8xx.dpram0, 0 },
+ { (char *)&m8xx.dpram1[0], sizeof m8xx.dpram1, 0 },
+ { (char *)&m8xx.dpram2[0], sizeof m8xx.dpram2, 0 },
+ { (char *)&m8xx.dpram3[0], sizeof m8xx.dpram3, 0 },
+ { (char *)&m8xx.dpram4[0], sizeof m8xx.dpram4, 0 },
+};
+
+#define NUM_DPRAM_REGIONS (sizeof(dpram_regions) / sizeof(dpram_regions[0]))
+
+void *
+m8xx_dpram_allocate( unsigned int byte_count )
+{
+ unsigned int i;
+ ISR_Level level;
+ void *blockp = NULL;
+
+ byte_count = (byte_count + 3) & ~0x3;
+
+ /*
+ * 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 < NUM_DPRAM_REGIONS; i++ ) {
+ /*
+ * Verify that the region is available for use.
+ * This test is necessary because if extra microcode modules
+ * are installed, some regions are locked and unavailable.
+ * See MPC860 User's Manual Pages 19-9 to 19-11.
+ */
+ if (dpram_regions[i].used == 0) {
+ volatile unsigned char *cp = dpram_regions[i].base;
+ *cp = 0xAA;
+ if (*cp != 0xAA)
+ dpram_regions[i].used = dpram_regions[i].size;
+ else {
+ *cp = 0x55;
+ if (*cp != 0x55)
+ dpram_regions[i].used = dpram_regions[i].size;
+ }
+ *cp = 0x0;
+ }
+ if (dpram_regions[i].size - dpram_regions[i].used >= byte_count) {
+ blockp = dpram_regions[i].base + dpram_regions[i].used;
+ dpram_regions[i].used += byte_count;
+ break;
+ }
+ }
+
+ _ISR_Enable(level);
+
+ if (blockp == NULL)
+ rtems_panic("Can't allocate %d bytes of dual-port RAM.\n", byte_count);
+ return blockp;
+}