summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc6xx/mmu
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc6xx/mmu')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in79
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c64
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h40
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S224
4 files changed, 407 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in
new file mode 100644
index 0000000000..44278afbbc
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in
@@ -0,0 +1,79 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = ../../..
+subdir = powerpc/mpc6xx/mmu
+
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+VPATH = @srcdir@
+
+PGM = ${ARCH}/mmu.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES = bat
+C_FILES = $(C_PIECES:%=%.c)
+C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES = $(srcdir)/bat.h
+
+# Assembly source names, if any, go here -- minus the .S
+S_PIECES = mmuAsm
+S_FILES = $(S_PIECES:%=%.S)
+S_O_FILES = $(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS = $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS = $(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+INSTALL_CHANGE = @INSTALL_CHANGE@
+mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
+
+INSTALLDIRS = $(PROJECT_INCLUDE)/libcpu
+
+$(INSTALLDIRS):
+ @$(mkinstalldirs) $(INSTALLDIRS)
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${OBJS}
+ $(make-rel)
+
+preinstall: $(INSTALLDIRS) $(H_FILES)
+ @$(INSTALL_CHANGE) -m 644 $(H_FILES) $(PROJECT_INCLUDE)/libcpu
+
+all: ${ARCH} $(SRCS) preinstall $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c
new file mode 100644
index 0000000000..e39ab96ec5
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c
@@ -0,0 +1,64 @@
+/*
+ * bat.c
+ *
+ * This file contains the implementation of C function to
+ * Instanciate 60x/7xx ppc Block Address Translation (BAT) registers.
+ * More detailled information can be found on motorola
+ * site and more precisely in the following book :
+ *
+ * MPC750
+ * Risc Microporcessor User's Manual
+ * Mtorola REF : MPC750UM/AD 8/97
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <libcpu/bat.h>
+
+typedef union { /* BAT register values to be loaded */
+ BAT bat;
+ unsigned int word[2];
+}ubat;
+
+typedef struct batrange { /* stores address ranges mapped by BATs */
+ unsigned long start;
+ unsigned long limit;
+ unsigned long phys;
+}batrange;
+
+batrange bat_addrs[4];
+
+void setdbat(int bat_index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags)
+{
+ unsigned int bl;
+ int wimgxpp;
+ ubat bat;
+
+ bl = (size >> 17) - 1;
+ /* 603, 604, etc. */
+ wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
+ | _PAGE_COHERENT | _PAGE_GUARDED);
+ wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
+ bat.word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
+ bat.word[1] = phys | wimgxpp;
+ if (flags & _PAGE_USER)
+ bat.bat.batu.vp = 1;
+ bat_addrs[bat_index].start = virt;
+ bat_addrs[bat_index].limit = virt + ((bl + 1) << 17) - 1;
+ bat_addrs[bat_index].phys = phys;
+ switch (bat_index) {
+ case 1 : asm_setdbat1(bat.word[0], bat.word[1]); break;
+ case 2 : asm_setdbat2(bat.word[0], bat.word[1]); break;
+ case 3 : asm_setdbat3(bat.word[0], bat.word[1]); break;
+ default: printk("bat.c : invalid BAT bat_index\n");
+ }
+}
+
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h
new file mode 100644
index 0000000000..616f6182a4
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h
@@ -0,0 +1,40 @@
+/*
+ * bat.h
+ *
+ * This file contains declaration of C function to
+ * Instanciate 60x/7xx ppc Block Address Translation (BAT) registers.
+ * More detailled information can be found on motorola
+ * site and more precisely in the following book :
+ *
+ * MPC750
+ * Risc Microporcessor User's Manual
+ * Mtorola REF : MPC750UM/AD 8/97
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef LIBCPU_MCP750_MMU_BAT_H
+#define LIBCPU_MCP750_MMU_BAT_H
+
+#include <libcpu/mmu.h>
+#include <libcpu/pgtable.h>
+#include <bsp/consoleIo.h>
+
+#define IO_PAGE (_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW)
+
+extern void setdbat(int bat_index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags);
+
+extern void asm_setdbat1(unsigned int uperPart, unsigned int lowerPart);
+extern void asm_setdbat2(unsigned int uperPart, unsigned int lowerPart);
+extern void asm_setdbat3(unsigned int uperPart, unsigned int lowerPart);
+extern void asm_setdbat4(unsigned int uperPart, unsigned int lowerPart);
+
+#endif /* LIBCPU_MCP750_MMU_BAT_H */
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S
new file mode 100644
index 0000000000..a0f298e5c3
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S
@@ -0,0 +1,224 @@
+/*
+ * mmuAsm.S
+ *
+ * $Id$
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ *
+ * This file contains the low-level support for various MMU
+ * features.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ */
+
+#include <libcpu/cpu.h>
+#include <libcpu/io.h>
+#include <rtems/score/targopts.h>
+#include "asm.h"
+
+ .globl asm_setdbat1
+ .type asm_setdbat1,@function
+asm_setdbat1:
+ mtspr DBAT1U, r3
+ mtspr DBAT1L, r4
+ SYNC
+ blr
+
+ .globl asm_setdbat2
+ .type asm_setdbat2,@function
+asm_setdbat2:
+ mtspr DBAT2U, r3
+ mtspr DBAT2L, r4
+ SYNC
+ blr
+
+ .globl asm_setdbat3
+ .type asm_setdbat3,@function
+asm_setdbat3:
+ mtspr DBAT3U, r3
+ mtspr DBAT3L, r4
+ SYNC
+ blr
+
+ .globl L1_caches_enables
+ .type L1_caches_enables, @function
+
+L1_caches_enables:
+ /*
+ * Enable caches and 604-specific features if necessary.
+ */
+ mfspr r9,PVR
+ rlwinm r9,r9,16,16,31
+ cmpi 0,r9,1
+ beq 4f /* not needed for 601 */
+ mfspr r11,HID0
+ andi. r0,r11,HID0_DCE
+ ori r11,r11,HID0_ICE|HID0_DCE
+ ori r8,r11,HID0_ICFI
+ bne 3f /* don't invalidate the D-cache */
+ ori r8,r8,HID0_DCI /* unless it wasn't enabled */
+3:
+ sync
+ mtspr HID0,r8 /* enable and invalidate caches */
+ sync
+ mtspr HID0,r11 /* enable caches */
+ sync
+ isync
+ cmpi 0,r9,4 /* check for 604 */
+ cmpi 1,r9,9 /* or 604e */
+ cmpi 2,r9,10 /* or mach5 */
+ cror 2,2,6
+ cror 2,2,10
+ bne 4f
+ ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */
+ bne 2,5f
+ ori r11,r11,HID0_BTCD
+5: mtspr HID0,r11 /* superscalar exec & br history tbl */
+4:
+ blr
+
+ .globl get_L2CR
+ .type get_L2CR, @function
+get_L2CR:
+ /* Make sure this is a 750 chip */
+ mfspr r3,PVR
+ rlwinm r3,r3,16,16,31
+ cmplwi r3,0x0008
+ li r3,0
+ bnelr
+
+ /* Return the L2CR contents */
+ mfspr r3,L2CR
+ blr
+
+ .globl set_L2CR
+ .type set_L2CR, @function
+set_L2CR:
+ /* Usage:
+ * When setting the L2CR register, you must do a few special things.
+ * If you are enabling the cache, you must perform a global invalidate.
+ * If you are disabling the cache, you must flush the cache contents first.
+ * This routine takes care of doing these things. When first
+ * enabling the cache, make sure you pass in the L2CR you want, as well as
+ * passing in the global invalidate bit set. A global invalidate will
+ * only be performed if the L2I bit is set in applyThis. When enabling
+ * the cache, you should also set the L2E bit in applyThis. If you
+ * want to modify the L2CR contents after the cache has been enabled,
+ * the recommended procedure is to first call __setL2CR(0) to disable
+ * the cache and then call it again with the new values for L2CR. Examples:
+ *
+ * _setL2CR(0) - disables the cache
+ * _setL2CR(0xb9A14000) - enables my G3 MCP750 card:
+ * - L2E set to turn on the cache
+ * - L2SIZ set to 1MB
+ * - L2CLK set to %2
+ * - L2RAM set to pipelined syncronous late-write
+ * - L2I set to perform a global invalidation
+ * - L2OH set to 1 nS
+ *
+ * A similar call should work for your card. You need to know the correct
+ * setting for your card and then place them in the fields I have outlined
+ * above. Other fields support optional features, such as L2DO which caches
+ * only data, or L2TS which causes cache pushes from the L1 cache to go to
+ *the L2 cache instead of to main memory.
+ */
+
+ /* Make sure this is a 750 chip */
+ mfspr r4,PVR
+ rlwinm r4,r4,16,16,31
+ cmplwi r4,0x0008
+ beq thisIs750
+ li r3,-1
+ blr
+
+thisIs750:
+ /* Get the current enable bit of the L2CR into r4 */
+ mfspr r4,L2CR
+ rlwinm r4,r4,0,0,0
+
+ /* See if we want to perform a global inval this time. */
+ rlwinm r6,r3,0,10,10 /* r6 contains the new invalidate bit */
+ rlwinm. r5,r3,0,0,0 /* r5 contains the new enable bit */
+ rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */
+ rlwinm r3,r3,0,1,31 /* Turn off the enable bit */
+ or r3,r3,r4 /* Keep the enable bit the same as it was for now. */
+ bne dontDisableCache /* Only disable the cache if L2CRApply has the enable bit off */
+
+disableCache:
+ /* Disable the cache. First, we turn off data relocation. */
+ mfmsr r7
+ rlwinm r4,r7,0,28,26 /* Turn off DR bit */
+ rlwinm r4,r4,0,17,15 /* Turn off EE bit - an external exception while we are flushing
+ the cache is fatal (comment this line and see!) */
+ sync
+ mtmsr r4
+ sync
+
+ /*
+ Now, read the first 2MB of memory to put new data in the cache.
+ (Actually we only need the size of the L2 cache plus
+ the size of the L1 cache, but 2MB will cover everything just to be safe).
+ */
+ lis r4,0x0001
+ mtctr r4
+ li r4,0
+loadLoop:
+ lwzx r0,r0,r4
+ addi r4,r4,0x0020 /* Go to start of next cache line */
+ bdnz loadLoop
+
+ /* Now, flush the first 2MB of memory */
+ lis r4,0x0001
+ mtctr r4
+ li r4,0
+ sync
+flushLoop:
+ dcbf r0,r4
+ addi r4,r4,0x0020 /* Go to start of next cache line */
+ bdnz flushLoop
+
+ /* Turn off the L2CR enable bit. */
+ rlwinm r3,r3,0,1,31
+
+ /* Reenable data relocation. */
+ sync
+ mtmsr r7
+ sync
+
+dontDisableCache:
+ /* Set up the L2CR configuration bits */
+ sync
+ mtspr L2CR,r3
+ sync
+ cmplwi r6,0
+ beq noInval
+
+ /* Perform a global invalidation */
+ oris r3,r3,0x0020
+ sync
+ mtspr 1017,r3
+ sync
+invalCompleteLoop: /* Wait for the invalidation to complete */
+ mfspr r3,1017
+ rlwinm. r4,r3,0,31,31
+ bne invalCompleteLoop
+
+ rlwinm r3,r3,0,11,9; /* Turn off the L2I bit */
+ sync
+ mtspr L2CR,r3
+ sync
+
+noInval:
+ /* See if we need to enable the cache */
+ cmplwi r5,0
+ beqlr
+
+enableCache:
+ /* Enable the cache */
+ oris r3,r3,0x8000
+ mtspr L2CR,r3
+ sync
+ blr