summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc8xx/mmu
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc8xx/mmu')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am30
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c120
2 files changed, 150 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am
new file mode 100644
index 0000000000..322c3fca75
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am
@@ -0,0 +1,30 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = ${ARCH}/mmu.rel
+
+## C sources
+C_FILES = mmu.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/mmu/mmu.c b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c
new file mode 100644
index 0000000000..7e877b106f
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c
@@ -0,0 +1,120 @@
+/*
+ * mmu.c
+ *
+ * This file contains routines for initializing
+ * and manipulating the MMU on the MPC8xx.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#include <bsp.h>
+#include <mpc8xx/mmu.h>
+
+/*
+ * mmu_init
+ *
+ * This routine sets up the virtual memory maps on an MPC8xx.
+ * The MPC8xx does not support block address translation (BATs)
+ * and does not have segment registers. Thus, we must set up page
+ * translation. However, its MMU supports variable size pages
+ * (1-, 4-, 16-, 512-Kbyte or 8-Mbyte), which simplifies the task.
+ *
+ * The MPC8xx has separate data and instruction 32-entry translation
+ * lookaside buffers (TLB). By mapping all of DRAM as one huge page,
+ * we can preload the TLBs and not have to be concerned with taking
+ * TLB miss exceptions.
+ *
+ * We set up the virtual memory map so that virtual address of a
+ * location is equal to its real address.
+ */
+void mmu_init( void )
+{
+ register unsigned32 reg1, i;
+
+ /*
+ * Initialize the TLBs
+ *
+ * Instruction address translation and data address translation
+ * must be disabled during initialization (IR=0, DR=0 in MSR).
+ * We can assume the MSR has already been set this way.
+ */
+
+ /*
+ * Initialize IMMU & DMMU Control Registers (MI_CTR & MD_CTR)
+ * GPM [0] 0b0 = PowerPC mode
+ * PPM [1] 0b0 = Page resolution of protection
+ * CIDEF [2] 0b0/0b1 = Default cache-inhibit attribute =
+ * NO for IMMU, YES for DMMU!
+ * reserved/WTDEF [3] 0b0 = Default write-through attribute = not
+ * RSV4x [4] 0b0 = 4 entries not reserved
+ * reserved/TWAM [5] 0b0/0b1 = 4-Kbyte page hardware assist
+ * PPCS [6] 0b0 = Ignore user/supervisor state
+ * reserved [7-18] 0x00
+ * xTLB_INDX [19-23] 31 = 0x1F
+ * reserved [24-31] 0x00
+ *
+ * Note: It is important that cache-inhibit be set as the default for the
+ * data cache when the DMMU is disabled in order to prevent internal memory
+ * mapped registers from being cached accidentally when address translation
+ * is turned off at the start of exception processing.
+ */
+ reg1 = M8xx_MI_CTR_ITLB_INDX(31);
+ _mtspr( M8xx_MI_CTR, reg1 );
+ reg1 = M8xx_MD_CTR_CIDEF | M8xx_MD_CTR_TWAM | M8xx_MD_CTR_DTLB_INDX(31);
+ _mtspr( M8xx_MD_CTR, reg1 );
+ _isync;
+
+ /*
+ * Invalidate all TLB entries in both TLBs.
+ * Note: We rely on the RSV4 bit in MI_CTR and MD_CTR being 0b0, so
+ * all 32 entries are invalidated.
+ */
+ __asm__ volatile ("tlbia\n"::);
+ _isync;
+
+ /*
+ * Set Current Address Space ID Register (M_CASID).
+ * Supervisor: CASID = 0
+ */
+ reg1 = 0;
+ _mtspr( M8xx_M_CASID, reg1 );
+
+ /*
+ * Initialize the MMU Access Protection Registers (MI_AP, MD_AP)
+ * We ignore the Access Protection Group (APG) mechanism globally
+ * by setting all of the Mx_AP fields to 0b01 : client access
+ * permission is defined by page protection bits.
+ */
+ reg1 = 0x55555555;
+ _mtspr( M8xx_MI_AP, reg1 );
+ _mtspr( M8xx_MD_AP, reg1 );
+
+ /*
+ * Load both 32-entry TLBs with values from the MMU_TLB_table
+ * which is defined in the BSP.
+ * Note the _TLB_Table must have at most 32 entries. This code
+ * makes no effort to enforce this restriction.
+ */
+ for( i = 0; i < MMU_N_TLB_Table_Entries; ++i ) {
+ reg1 = MMU_TLB_table[i].mmu_epn;
+ _mtspr( M8xx_MI_EPN, reg1 );
+ _mtspr( M8xx_MD_EPN, reg1 );
+ reg1 = MMU_TLB_table[i].mmu_twc;
+ _mtspr( M8xx_MI_TWC, reg1 );
+ _mtspr( M8xx_MD_TWC, reg1 );
+ reg1 = MMU_TLB_table[i].mmu_rpn; /* RPN must be written last! */
+ _mtspr( M8xx_MI_RPN, reg1 );
+ _mtspr( M8xx_MD_RPN, reg1 );
+ }
+
+ /*
+ * Turn on address translation by setting MSR[IR] and MSR[DR].
+ */
+ _CPU_MSR_Value( reg1 );
+ reg1 |= PPC_MSR_IR | PPC_MSR_DR;
+ _CPU_MSR_SET( reg1 );
+}