[PATCH 06/15] Various updates and improvements

Ric Claus claus at slac.stanford.edu
Tue Nov 27 03:26:44 UTC 2012


---
 c/src/lib/libbsp/powerpc/virtex5/Makefile.am       |   12 +-
 c/src/lib/libbsp/powerpc/virtex5/configure.ac      |    2 +-
 .../libbsp/powerpc/virtex5/console/dummy_console.c |  102 ----
 c/src/lib/libbsp/powerpc/virtex5/include/irq.h     |    4 +-
 c/src/lib/libbsp/powerpc/virtex5/include/mmu.h     |  287 ++++++++++
 c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c    |   21 +-
 c/src/lib/libbsp/powerpc/virtex5/libc/fastcopy.S   |  143 +++++
 c/src/lib/libbsp/powerpc/virtex5/libc/memcpy.c     |  225 ++++++++
 c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c         |  582 ++++++++++++++++++++
 .../lib/libbsp/powerpc/virtex5/startup/bspstart.c  |  108 +++--
 c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds  |   11 +-
 c/src/lib/libbsp/powerpc/virtex5/startup/start.S   |  101 ++--
 12 files changed, 1395 insertions(+), 203 deletions(-)
 delete mode 100644 c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c
 create mode 100644 c/src/lib/libbsp/powerpc/virtex5/include/mmu.h
 create mode 100644 c/src/lib/libbsp/powerpc/virtex5/libc/fastcopy.S
 create mode 100644 c/src/lib/libbsp/powerpc/virtex5/libc/memcpy.c
 create mode 100644 c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c

diff --git a/c/src/lib/libbsp/powerpc/virtex5/Makefile.am b/c/src/lib/libbsp/powerpc/virtex5/Makefile.am
index 31d3987..9d8800c 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/virtex5/Makefile.am
@@ -41,8 +41,9 @@ libbsp_a_SOURCES = startup/bspclean.c \
 libbsp_a_SOURCES += startup/start.S
 
 # clock & timer
-libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/ppc403/clock/clock.c
-libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/ppc403/timer/timer.c
+libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/mpc6xx/clock/c_clock.c
+libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/mpc6xx/timer/timer.c
+libbsp_a_SOURCES += ../../powerpc/shared/clock/p_clock.c
 
 # console
 libbsp_a_SOURCES += startup/dummy_console.c \
@@ -52,10 +53,17 @@ libbsp_a_SOURCES += startup/dummy_console.c \
 include_bsp_HEADERS += include/irq.h
 libbsp_a_SOURCES += irq/irq_init.c
 
+# mmu
+include_bsp_HEADERS += include/mmu.h
+libbsp_a_SOURCES += mmu/mmu.c
+
 #vectors
 include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h
 include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_supp.h
 
+# libc
+libbsp_a_SOURCES += libc/memcpy.c libc/fastcopy.S
+
 libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
                   ../../../libcpu/@RTEMS_CPU@/@exceptions@/exc_bspsupport.rel \
                   ../../../libcpu/@RTEMS_CPU@/shared/cache.rel \
diff --git a/c/src/lib/libbsp/powerpc/virtex5/configure.ac b/c/src/lib/libbsp/powerpc/virtex5/configure.ac
index 9e420b1..644c659 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/configure.ac
+++ b/c/src/lib/libbsp/powerpc/virtex5/configure.ac
@@ -32,7 +32,7 @@ RTEMS_BSPOPTS_HELP([PPC_USE_SPRG],
  response time.  The use of these registers can conflict with
  other tools like debuggers.])
 
-RTEMS_BSPOPTS_SET([PPC_VECTOR_FILE_BASE],[*],[0x0100])
+RTEMS_BSPOPTS_SET([PPC_VECTOR_FILE_BASE],[*],[0x0])
 RTEMS_BSPOPTS_HELP([PPC_VECTOR_FILE_BASE],
 [This defines the base address of the exception table.])
 
diff --git a/c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c b/c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c
deleted file mode 100644
index 048133d..0000000
--- a/c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <rtems.h>
-#include <rtems/libio.h>
-
-#include <string.h>
-
-ssize_t app_memory_write(int minor, const char* buf, size_t len)
-__attribute__(( weak, alias("__bsp_memory_write") ));
-
-ssize_t __bsp_memory_write(int minor, const char* buf, size_t len);
-rtems_device_driver console_initialize(rtems_device_major_number major,
-                                       rtems_device_minor_number minor,
-                                       void*                     arg);
-rtems_device_driver console_open(rtems_device_major_number major,
-                                 rtems_device_minor_number minor,
-                                 void*                     arg);
-rtems_device_driver console_close(rtems_device_major_number major,
-                                  rtems_device_minor_number minor,
-                                  void*                     arg);
-rtems_device_driver console_read(rtems_device_major_number major,
-                                 rtems_device_minor_number minor,
-                                 void*                     arg);
-rtems_device_driver console_write(rtems_device_major_number major,
-                                  rtems_device_minor_number minor,
-                                  void*                     arg);
-rtems_device_driver console_control(rtems_device_major_number major,
-                                    rtems_device_minor_number minor,
-                                    void*                     arg);
-
-
-ssize_t __bsp_memory_write(int minor, const char* buf, size_t len)
-{
-  const char* const last = buf+len;
-  while (buf < last)
-  {
-    BSP_output_char(*buf++);
-  }
-  return len;
-}
-
-static rtems_termios_callbacks gMemCallbacks = {
-        0,                /* firstOpen */
-        0,                /* lastClose */
-        0,                /* PollRead */
-        app_memory_write, /* write */
-        0,                /* SetAttr */
-        0,                /* stopRemoteTx */
-        0,                /* startRemoteTx */
-        0                 /* outputUsesInterrupts */
-};
-
-rtems_device_driver console_initialize(rtems_device_major_number major,
-                                       rtems_device_minor_number minor,
-                                       void*                     arg)
-{
-  rtems_status_code status;
-
-  rtems_termios_initialize();
-
-  status = rtems_io_register_name("/dev/console", major, 0);
-
-  if (status != RTEMS_SUCCESSFUL)  rtems_fatal_error_occurred (status);
-  return RTEMS_SUCCESSFUL;
-}
-
-rtems_device_driver console_open(rtems_device_major_number major,
-                                 rtems_device_minor_number minor,
-                                 void*                     arg)
-{
-  rtems_status_code sc;
-
-  sc = rtems_termios_open (major, minor, arg, &gMemCallbacks);
-
-  return sc;
-}
-
-rtems_device_driver console_close(rtems_device_major_number major,
-                                  rtems_device_minor_number minor,
-                                  void*                     arg)
-{
-  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);
-}
diff --git a/c/src/lib/libbsp/powerpc/virtex5/include/irq.h b/c/src/lib/libbsp/powerpc/virtex5/include/irq.h
index 2edf6aa..62a86a5 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/include/irq.h
+++ b/c/src/lib/libbsp/powerpc/virtex5/include/irq.h
@@ -62,7 +62,7 @@ extern "C" {
  */
   typedef enum {
     BSP_EXT               = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 0,
-    BSP_PIT               = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 1,
+    BSP_DEC               = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 1,
     BSP_CRIT              = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 2
   } rtems_irq_symbolic_name;
 
@@ -72,6 +72,8 @@ extern "C" {
 #ifdef __cplusplus
 }
 #endif
+#define	BSP_DECREMENTER   BSP_DEC
+
 #endif /* ASM */
 
 #endif /* VIRTEX5_IRQ_IRQ_H */
diff --git a/c/src/lib/libbsp/powerpc/virtex5/include/mmu.h b/c/src/lib/libbsp/powerpc/virtex5/include/mmu.h
new file mode 100644
index 0000000..a3fb32b
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex5/include/mmu.h
@@ -0,0 +1,287 @@
+#ifndef RTEMS_VIRTEX5_MMU_H
+#define RTEMS_VIRTEX5_MMU_H
+/**
+ * @file
+ *
+ * @ingroup Virtex5MMU
+ *
+ * @brief Routines to manipulate the PPC 440 MMU.
+ */
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ *     Till Straumann <strauman at slac.stanford.edu>, 2005-2007,
+ *       Stanford Linear Accelerator Center, Stanford University.
+ * and was transcribed for the PPC 440 by
+ *     R. Claus <claus at slac.stanford.edu>, 2012,
+ *       Stanford Linear Accelerator Center, Stanford University,
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ *     the Stanford Linear Accelerator Center, Stanford University,
+ *     under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software.  Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+#include <rtems.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup Virtex5MMU Virtex 5 - MMU Support
+ *
+ * @ingroup Virtex5
+ *
+ * @brief MMU support.
+ *
+ * @{
+ */
+
+/* Some routines require or return an index 'key'.
+ */
+typedef int bsp_tlb_idx_t;
+
+/* Cache the relevant TLB entries so that we can make sure the user cannot
+ * create conflicting (overlapping) entries. Keep them public for informational
+ * purposes.
+ */
+typedef struct {
+  struct {
+    uint32_t pad:24;
+    uint32_t tid:8;             /** Translation ID */
+  }        id;
+  struct {
+    uint32_t epn:22;            /** Effective page number */
+    uint32_t v:1;               /** Valid */
+    uint32_t ts:1;              /** Translation Address Space */
+    uint32_t size:4;            /** Page size */
+    uint32_t tpar:4;            /** Tag parity */
+  }        w0;
+  struct {
+    uint32_t rpn:22;            /** The real (translated) page number. */
+    uint32_t par1:2;            /** For matching the TLB array parity */
+    uint32_t pad:4;
+    uint32_t erpn:4;            /** Extended Real Page Number */
+  }        w1;
+  struct {
+    uint32_t par2:2;            /** Parity for TLB word 2 */
+    uint32_t pad1:14;
+    uint32_t att:4;             /** User-defined attributes */
+    uint32_t wimge:5;           /** Write-Through/Caching Inhibited/Memory Coherent/Guarded/Endian */
+    uint32_t pad2:1;
+    uint32_t perm:6;            /** User-State Executable/Writeable/Readable Supervisor-State Executable/Writeable/Readable */
+  }        w2;
+} bsp_tlb_entry_t;
+
+#define NTLBS  64
+
+extern bsp_tlb_entry_t* bsp_mmu_cache;
+
+// These constants will have to be shifted right by 20 bits before
+// being inserted the high word of the TLB.
+
+#define MMU_M_SIZE_1K               (0x00000000U)
+#define MMU_M_SIZE_4K               (0x08000000U)
+#define MMU_M_SIZE_16K              (0x10000000U)
+#define MMU_M_SIZE_64K              (0x18000000U)
+#define MMU_M_SIZE_256K             (0x20000000U)
+#define MMU_M_SIZE_1M               (0x28000000U)
+#define MMU_M_SIZE_16M              (0x38000000U)
+#define MMU_M_SIZE_256M             (0x48000000U)
+#define MMU_M_SIZE_MIN              (MMU_M_SIZE_1K)
+#define MMU_M_SIZE_MAX              (MMU_M_SIZE_256M)
+#define MMU_M_SIZE                  (0x78000000U)
+#define MMU_V_SIZE                  (27)
+
+// These constants have the same bit positions they'll occupy
+// in low word of the TLB.
+
+#define MMU_M_ATTR_USER0            (0x00010000U)
+#define MMU_M_ATTR_USER1            (0x00008000U)
+#define MMU_M_ATTR_USER2            (0x00004000U)
+#define MMU_M_ATTR_USER3            (0x00002000U)
+#define MMU_M_ATTR                  (0x0001e000U)
+#define MMU_V_ATTR                  (13)
+
+#define MMU_M_PROP_WRITE_THROUGH    (0x00001000U)
+#define MMU_M_PROP_UNCACHED         (0x00000800U)
+#define MMU_M_PROP_MEM_COHERENT     (0x00000400U)
+#define MMU_M_PROP_GUARDED          (0x00000200U)
+#define MMU_M_PROP_LITTLE_ENDIAN    (0x00000100U)
+#define MMU_M_PROP                  (0x00000f00U)
+#define MMU_V_PROP                  (8)
+
+#define MMU_M_PERM_USER_EXEC        (0x00000020U)
+#define MMU_M_PERM_USER_WRITE       (0x00000010U)
+#define MMU_M_PERM_USER_READ        (0x00000008U)
+#define MMU_M_PERM_SUPER_EXEC       (0x00000004U)
+#define MMU_M_PERM_SUPER_WRITE      (0x00000002U)
+#define MMU_M_PERM_SUPER_READ       (0x00000001U)
+#define MMU_M_PERM                  (0x0000003fU)
+#define MMU_V_PERM                  (0)
+
+
+/*
+ * Dump (cleartext) content info from cached TLB entries
+ * to a file (stdout if f==NULL).
+ */
+void
+bsp_mmu_dump_cache(FILE *f);
+
+/* Read a TLB entry from the hardware and store the settings in the
+ * bsp_mmu_cache[] structure.
+ *
+ * The routine can perform this operation quietly or
+ * print information to a file.
+ *
+ *   'key': TLB entry index.
+ * 'quiet': perform operation silently (no info printed) if nonzero.
+ *     'f': open FILE where to print information. May be NULL, in
+ *          which case 'stdout' is used.
+ *
+ * RETURNS:
+ *       0: success; TLB entry is VALID
+ *      +1: success but TLB entry is INVALID
+ *     < 0: error (-1: invalid argument)
+ *                (-2: driver not initialized)
+ */
+int
+bsp_mmu_update(bsp_tlb_idx_t key, bool quiet, FILE *f);
+
+/* Initialize cache.  Should be done only once although this is not enforced.
+ *
+ * RETURNS: zero on success, nonzero on error; in this case the driver will
+ *          refuse to change TLB entries (other than disabling them).
+ */
+int
+bsp_mmu_initialize(void);
+
+/* Find first free TLB entry by examining all entries' valid bit.  The first
+ * entry without the valid bit set is returned.
+ *
+ * RETURNS: A free TLB entry number.  -1 if no entry can be found.
+ */
+bsp_tlb_idx_t
+bsp_mmu_find_first_free(void);
+
+/* Write a TLB entry (can also be used to disable an entry).
+ *
+ * The routine checks against the cached data in bsp_mmu_cache[]
+ * to prevent the user from generating overlapping entries.
+ *
+ *   'idx': TLB entry # to manipulate
+ *    'ea': Effective address (must be page aligned)
+ *    'pa': Physical  address (must be page aligned)
+ *    'sz': Page size selector; page size is 1024 * 2^(2*sz) bytes.
+ *          'sz' may also be one of the following:
+ *          - page size in bytes ( >= 1024 ); the selector
+ *            value is then computed by this routine.
+ *            However, 'sz' must be a valid page size
+ *            or -1 will be returned.
+ *          - a value < 0 to invalidate/disable the
+ *            TLB entry.
+ *  'flgs': Page's User-defined flags, permissions and WIMGE page attributes
+ *   'tid': Translation ID
+ *    'ts': Translation Space
+ *  'erpn': Extended Real Page Number
+ *
+ * RETURNS: 0 on success, nonzero on error:
+ *
+ *         >0: requested mapping would overlap with
+ *             existing mapping in another entry. Return
+ *             value gives conflicting entry + 1; i.e.,
+ *             if a value of 4 is returned then the request
+ *             conflicts with existing mapping in entry 3.
+ *         -1: invalid argument
+ *         -3: driver not initialized (or initialization failed).
+ *         <0: other error
+ */
+bsp_tlb_idx_t
+bsp_mmu_write(bsp_tlb_idx_t idx, uint32_t ea, uint32_t pa, int sz,
+              uint32_t flgs, uint32_t tid, uint32_t ts, uint32_t erpn);
+
+/* Check if a ea/tid/ts/sz mapping overlaps with an existing entry.
+ *
+ *    'ea': The Effective Address to match against
+ *    'sz': The 'logarithmic' size selector; the page size
+ *          is 1024*2^(2*sz).
+ *   'tid': Translation ID
+ *    'ts': Translation Space
+ *
+ * RETURNS:
+ *     >= 0: index of TLB entry that already provides a mapping
+ *           which overlaps within the ea range.
+ *       -1: SUCCESS (no conflicting entry found)
+ *     <=-2: ERROR (invalid input)
+ */
+bsp_tlb_idx_t
+bsp_mmu_match(uint32_t ea, int sz, uint32_t tid, uint32_t ts);
+
+/* Find TLB index that maps 'ea/tid/ts' combination
+ *
+ *    'ea': Effective address to match against
+ *   'tid': Translation ID
+ *    'ts': Translation Space
+ *
+ * RETURNS: index 'key'; i.e., the index number.
+ *
+ *          On error (no mapping) -1 is returned.
+ */
+bsp_tlb_idx_t
+bsp_mmu_find(uint32_t ea, uint32_t tid, uint32_t ts);
+
+/* Mark TLB entry as invalid ('disabled').
+ *
+ * 'key': TLB entry index.
+ *
+ * RETURNS: zero on success, nonzero on error (TLB unchanged).
+ *
+ * NOTE:  If a TLB entry is disabled the associated
+ *        entry in bsp_tlb_cache[] is also marked as disabled.
+ */
+int
+bsp_mmu_invalidate(bsp_tlb_idx_t key);
+
+/** @} */
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c b/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c
index ffcfe4c..2eeed10 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c
+++ b/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c
@@ -88,6 +88,20 @@ void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
   _CPU_MSR_SET(msr_value);
 }
 
+SPR_RW(BOOKE_TSR)
+
+int C_dispatch_dec_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+  /* Acknowledge the interrupt */
+  _write_BOOKE_TSR( BOOKE_TSR_DIS );
+
+  /* Handle the interrupt */
+  BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
+
+  return 0;
+}
+
+
 /***********************************************************
  * High level IRQ handler called from shared_raw_irq_code_entry
  */
@@ -100,9 +114,12 @@ int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
   case ASM_EXT_VECTOR:
     BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
     break;
+#if 0 /* Dealt with by C_dispatch_dec_handler(), above */
   case ASM_BOOKE_DEC_VECTOR:
-    BSP_rtems_irq_tbl[BSP_PIT].hdl(BSP_rtems_irq_tbl[BSP_PIT].handle);
+    _write_BOOKE_TSR( BOOKE_TSR_DIS );
+    BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
     break;
+#endif
 #if 0 /* Critical interrupts not yet supported */
   case ASM_BOOKE_CRIT_VECTOR:
     BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
@@ -305,7 +322,7 @@ void BSP_rtems_irq_mngt_init(unsigned cpuId)
    * connect all exception vectors needed
    */
   ppc_exc_set_handler(ASM_EXT_VECTOR,       C_dispatch_irq_handler);
-  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler);
+  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler);
 
   /*
    * setup interrupt handlers table
diff --git a/c/src/lib/libbsp/powerpc/virtex5/libc/fastcopy.S b/c/src/lib/libbsp/powerpc/virtex5/libc/fastcopy.S
new file mode 100644
index 0000000..2ecbdcc
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex5/libc/fastcopy.S
@@ -0,0 +1,143 @@
+/*----------------------------------------------------------------------------+
+| COPYRIGHT I B M CORPORATION 2007
+| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+| US Government Users Restricted Rights - Use, duplication or
+| disclosure restricted by GSA ADP Schedule Contract with
+| IBM Corp.
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| PPC440 Example Code
+| Author: Paul Gramann
+| Component: none
+| File: fastcopy.S
+| Purpose: Fast memory copy for PPC405 and PPC440 cores
+| Changes:
+| Date: Comment:
+| ----- --------
+| 29-Nov-07 Created pag
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| void fastcopy(dst, src, line_count);
+|
+| Inputs:
+| r3: destination address
+| r4: source address
+| r5: line count
+|
+| Notes:
+| dst and src address are assumed to be cache-line aligned.
+| line_count is assumed to be at least 3 cache-lines.
+| function needs to be in I-cache in order to not interfere with D-cache
+| access pattern.
+|
+| Algorithm:
+| touch (dcbt) 2 lines into the cache from source
+| zero (dcbz) 2 lines in cache for destination
+| repeat until 2 lines left to copy {
+| touch (dcbt) another line into the cache from source
+| load a source line from cache into 8 registers
+| zero (dcbz) another line in the cache for destination
+| store 8 registers to a destination cache line
+| }
+| copy last 2 cache lines of data from source to destination.
+|
+| During this algorithm the touches and loads are performed two lines ahead
+| of the data being copied.
+|
+| Register usage:
+| r0: scratch and copy
+| r1: stack frame pointer - not used
+| r2: small data area pointer - not used
+| r3: destination address
+| r4: source address
+| r5: line count and copy
+| r6: dcbz/dcbt offset and icbt address
+| r7-r12: copy and timing
++----------------------------------------------------------------------------*/
+
+#include <rtems/asm.h>
+
+        // Global Entry Point Definitions
+        .section .text,"ax"
+
+        .global fastcopy
+        
+fastcopy:
+// touch this code into the cache
+mflr r0          // save lr
+bl 4             // get our code address in lr
+mflr r6          // in r6
+mtlr r0          // restore lr
+addi r7,0,0      // initialize r7 to 0
+addi r0,0,0x10
+mtctr r0         // initialize ctr to 0x10 lines
+itouch_loop:
+icbt r6,r7       // touch line into i-cache
+addi r6,r6,0x20  // move to next line
+bdnz itouch_loop // repeat
+
+// initialize r6 for use in dcbt and dcbz's.
+// also adjust the data pointers to work with load/store update
+addi r6,0,4
+subf r4,r6,r4
+subf r3,r6,r3
+
+// pre-touch and pre-zero two lines of the source and destination
+// leaving r6 offset pointing to next untouched line
+// Note that the order must be dcbt, dcbt, dcbz, dcbz
+dcbt r4,r6
+addi r6,r6,0x20
+dcbt r4,r6
+addi r6,r6,-0x20
+dcbz r3,r6
+addi r6,r6,0x20
+dcbz r3,r6
+addi r6,r6,0x20
+
+addi r5,r5,-2 // subtract 2 from count
+mtctr r5      // and put in ctr
+
+cache_copy_loop:
+dcbt r4,r6    // touch 2 lines ahead
+lwzu r0,4(r4) // load 8 registers from cache
+lwzu r5,4(r4)
+lwzu r7,4(r4)
+lwzu r8,4(r4)
+lwzu r9,4(r4)
+lwzu r10,4(r4)
+lwzu r11,4(r4)
+lwzu r12,4(r4)
+dcbz r3,r6    // zero 2 lines ahead
+stwu r0,4(r3) // store 8 registers to cache
+stwu r5,4(r3)
+stwu r7,4(r3)
+stwu r8,4(r3)
+stwu r9,4(r3)
+stwu r10,4(r3)
+stwu r11,4(r3)
+stwu r12,4(r3)
+bdnz cache_copy_loop
+
+// Copy last two lines of data without cache ops.
+addi r0,0,2
+mtctr r0      // set ctr to 2
+final_copy_loop:
+lwzu r0,4(r4) // load 8 regs
+lwzu r5,4(r4)
+lwzu r7,4(r4)
+lwzu r8,4(r4)
+lwzu r9,4(r4)
+lwzu r10,4(r4)
+lwzu r11,4(r4)
+lwzu r12,4(r4)
+stwu r0,4(r3) // store 8 regs
+stwu r5,4(r3)
+stwu r7,4(r3)
+stwu r8,4(r3)
+stwu r9,4(r3)
+stwu r10,4(r3)
+stwu r11,4(r3)
+stwu r12,4(r3)
+bdnz final_copy_loop
+addi r3,r3,4    // adjust dst pointer
+blr             // all done - return
diff --git a/c/src/lib/libbsp/powerpc/virtex5/libc/memcpy.c b/c/src/lib/libbsp/powerpc/virtex5/libc/memcpy.c
new file mode 100644
index 0000000..ffbe31e
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex5/libc/memcpy.c
@@ -0,0 +1,225 @@
+/*!@file     memcpy.c
+*
+* @brief     PowerPC optimized memcpy routines
+*
+* @author    S. Maldonado -- REG - (smaldona at slac.stanford.edu)
+*
+* @date      Sept 24, 2012 -- Created
+*
+* $Revision: $
+*
+* @verbatim                    Copyright 2012
+*                                     by
+*                        The Board of Trustees of the
+*                      Leland Stanford Junior University.
+*                             All rights reserved.
+* @endverbatim
+*/
+
+#include <rtems.h>
+#include <rtems/powerpc/powerpc.h>  /* For PPC_CACHE_ALIGNMENT */
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
+#define UNALIGNED(X, Y) \
+  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the 4X unrolled loop.  */
+#define BIGBLOCKSIZE    (sizeof (long) << 2)
+
+/* How many bytes are copied each iteration of the word copy loop.  */
+#define LITTLEBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the byte copier.  */
+#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
+
+/* Nonzero if either X or Y is not aligned on a cache line boundary.  */
+#define CACHE_UNALIGNED(X, Y) \
+  (((long)X & (PPC_CACHE_ALIGNMENT - 1)) | ((long)Y & (PPC_CACHE_ALIGNMENT - 1)))
+
+/* Threshhold for fastcopy - 3 cache lines  */
+#define MIN_BLOCKS(LEN)  ((LEN) < (PPC_CACHE_ALIGNMENT*3))
+
+/* IBM fastcopy assembly routine */
+extern int *fastcopy(void *dst, const void *src, size_t count);
+
+void *memcpyppc32(void *dst, const void *src, size_t size);
+
+void *memcpynewlib(char *dst0, const char *src0, size_t len0);
+
+/*
+ * This is the RTEMS memcpy drop-in replacement which executes the IBM fastcopy algorithm
+ * or a secondary optimized block copy.
+ * The fastcopy routine is optimized for copying larger blocks with aligned 
+ * source and destination addresses.
+ * The memcpyppc32 routine is optimized for copying small and large blocks which may
+ * use unaligned destination addresses.
+ */
+void *memcpy(void *dst, const void *src, size_t len)  
+{
+  unsigned int len0;
+  
+  /* 
+   * If the size less than min cache lines, or either SRC or DST is not cache aligned,
+   * then proceed to optimized memcpy. Otherwise, execute fast block copy. 
+   */
+  if (!MIN_BLOCKS(len) && !CACHE_UNALIGNED(src, dst))
+  {   
+      /* fastcopy requires cache line count as argument */
+      len0 = len/PPC_CACHE_ALIGNMENT;
+      fastcopy(dst,src,len0);
+      
+      /* Adjust pointers and length */
+      len0 = len0*PPC_CACHE_ALIGNMENT;
+      src = (uint32_t *)(src + len0);
+      dst = (uint32_t *)(dst + len0);
+      len -= len0;
+
+      /* Pick up any residual words */   
+      while (len >= LITTLEBLOCKSIZE)
+      {
+        *((uint32_t*)dst) = *((uint32_t*)src);
+        src += LITTLEBLOCKSIZE;                                            
+        dst += LITTLEBLOCKSIZE;                                                    
+        len -= LITTLEBLOCKSIZE;
+      }
+
+      /* Pick up any residual bytes */
+      while (len--)
+        *((uint8_t*)dst++) = *((uint8_t*)src++);
+     
+      return dst;
+  }
+  else
+      return memcpyppc32(dst,src,len);
+}
+
+/*
+ * A memcpy routine optimized for ppc32 which handles small data blocks,
+ * destination address alignment, and cache line copying.
+ * Adopted from code examples provided in a 2004 posting at
+ * http://www.powerdeveloper.org/forums/viewtopic.php?t=1426
+ */
+void *memcpyppc32(void *dst, const void *src, size_t size)
+{
+  uint32_t i;
+  uint32_t *src32, *dst32;
+
+  if(size<4) goto memcpy_bytes;                        
+
+  /* align dest to 16 bits */
+  if( (uint32_t)dst & 1) 
+  {                             
+    *((uint8_t*)dst++) = *((uint8_t*)src++);           
+    size--;                                            
+  }   
+
+  /* align dest to 32 bits */                                                   
+  if ((uint32_t)dst & 2) 
+  {                             
+    *((uint16_t*)dst) = *((uint16_t*)src);             
+    src+=2;                                            
+    dst+=2;                                            
+    size -= 2;                                         
+  }                                                    
+
+  /* cache line copy, min 4 lines */
+  if(size >= 128) 
+  {    
+    /* align to cache line, 32 bytes */                                   
+    while( (uint32_t)dst & 31) 
+    {                      
+      *((uint32_t*)dst) = *((uint32_t*)src);           
+      src+=4;                                          
+      dst+=4;                                          
+      size -= 4;                                       
+    }                                                  
+
+    src32 = (uint32_t *)src; 
+    dst32 = (uint32_t *)dst;
+     
+    /* copy cache lines */
+    for (i=size/(8*sizeof(uint32_t));i;i--) 
+    {          
+      asm volatile ("dcbz 0,%0" : : "r" (&dst32[0]));
+      /* dcbt here doesn't improve performance */
+      /* asm volatile ("dcbt 0,%0" : : "r" (&src32[0])); */ 
+      dst32[0] = src32[0];
+      dst32[1] = src32[1];
+      dst32[2] = src32[2];
+      dst32[3] = src32[3];
+      dst32[4] = src32[4];
+      dst32[5] = src32[5];
+      dst32[6] = src32[6];
+      dst32[7] = src32[7];  
+
+      src32+=8;                                        
+      dst32+=8;                                        
+    }                                                  
+    size &= 8*sizeof(uint32_t)-1;                
+    src = (uint8_t *)src32;
+    dst = (uint8_t *)dst32;
+  }
+
+  /* copy residual words */
+  for (i=size/sizeof(uint32_t);i;i--) 
+  {                
+    *((uint32_t*)dst) = *((uint32_t*)src);             
+    src+=4;                                            
+    dst+=4;                                            
+  }                                                    
+  size &= sizeof(uint32_t)-1;      
+
+  /* copy residual bytes */
+memcpy_bytes:
+  while (size--)
+    *((uint8_t*)dst++) = *((uint8_t*)src++);           
+                                                   
+  return dst;
+}
+
+/*
+ * For reference, this is the default RTEMS version of memcpy provided with newlib-1.16.0.
+ */
+void *memcpynewlib(char *dst0, const char *src0, size_t len0)  {
+  char *dst = dst0;
+  _CONST char *src = src0;
+  long *aligned_dst;
+  _CONST long *aligned_src;
+  unsigned int   len =  len0;
+
+  /* 
+   * If the size is small, or either SRC or DST is unaligned,
+   * then punt into the byte copy loop.  This should be rare.  
+   */
+  if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
+    {
+      aligned_dst = (long*)dst;
+      aligned_src = (long*)src;
+
+      /* Copy 4X long words at a time if possible.  */
+      while (len >= BIGBLOCKSIZE)
+        {
+          *aligned_dst++ = *aligned_src++;
+          *aligned_dst++ = *aligned_src++;
+          *aligned_dst++ = *aligned_src++;
+          *aligned_dst++ = *aligned_src++;
+          len -= BIGBLOCKSIZE;
+        }
+
+      /* Copy one long word at a time if possible.  */
+      while (len >= LITTLEBLOCKSIZE)
+        {
+          *aligned_dst++ = *aligned_src++;
+          len -= LITTLEBLOCKSIZE;
+        }
+       
+      dst = (char*)aligned_dst;
+      src = (char*)aligned_src;
+    }
+
+  /* Pick up any residual bytes  */   
+  while (len--)
+    *dst++ = *src++;
+
+  return dst;
+}
diff --git a/c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c b/c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c
new file mode 100644
index 0000000..a598024
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c
@@ -0,0 +1,582 @@
+/**
+ * @file
+ *
+ * @ingroup Virtex5MMU
+ *
+ * @brief Implementation of routines to manipulate the PPC 440 MMU.
+ *
+ *        Since this is a real-time OS we want to stay away from
+ *        software TLB replacement.
+ */
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ *     Till Straumann <strauman at slac.stanford.edu>, 2005-2007,
+ * 	   Stanford Linear Accelerator Center, Stanford University.
+ * and was transcribed for the PPC 440 by
+ *     R. Claus <claus at slac.stanford.edu>, 2012,
+ *       Stanford Linear Accelerator Center, Stanford University,
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ *     the Stanford Linear Accelerator Center, Stanford University,
+ * 	   under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software.  Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+/* 440 MSR definitions; note that there are *substantial* differences
+ * compared to classic powerpc; in particular, IS/DS are *different*
+ * from IR/DR; the ppc440 MMU cannot be switched off!
+ *
+ * Also: To disable/enable all external interrupts, CE and EE must both be
+ *       controlled.
+ */
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/powerpc/powerpc.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+#include <bsp/mmu.h>
+
+
+#ifdef DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+
+bsp_tlb_entry_t* bsp_mmu_cache = 0;
+
+
+/* Since it is likely that these routines are used during
+ * early initialization when stdio is not available yet
+ * we provide a helper that resorts to 'printk()'
+ */
+static void
+myprintf(FILE *f, char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+
+  if (!f || !_impure_ptr->__sdidinit) {
+    /* Might be called at an early stage when stdio is not yet initialized. */
+    vprintk(fmt,ap);
+  } else {
+    vfprintf(f,fmt,ap);
+  }
+  va_end(ap);
+}
+
+
+void
+bsp_mmu_dump_cache(FILE *f)
+{
+  bsp_tlb_idx_t idx;
+  if ( !bsp_mmu_cache ) {
+    myprintf(stderr,"MMU TLB cache not initialized\n");
+    return;
+  }
+  for ( idx=0; idx<NTLBS; idx++ ) {
+    bsp_tlb_entry_t *tlb = bsp_mmu_cache + idx;
+    if ( !tlb->w0.v )
+      continue;
+    myprintf(f, "#%2i: EA 0x%08x .. 0x%08x, TID 0x%03x, TS %i\n",
+             idx,
+             tlb->w0.epn<<10,
+             (tlb->w0.epn<<10) + (1024<<(2*tlb->w0.size))-1,
+             tlb->id.tid,
+             tlb->w0.ts);
+    myprintf(f, "     PA 0x%08"PRIx32", U0-3 0x%01x, WIMGE 0x%02x, PERM 0x%03x\n",
+             tlb->w1.rpn<<10,
+             tlb->w2.att,
+             tlb->w2.wimge,
+             tlb->w2.perm);
+  }
+}
+
+static void
+fetch(bsp_tlb_idx_t key, bsp_tlb_entry_t* tlb)
+{
+  register uint32_t tmp;
+  __asm__ volatile ("mfpid   %[tmp]            \n\t"
+                    "stw     %[tmp],0(%[tlb])  \n\t"
+                    "tlbre   %[tmp],%[key],0   \n\t"
+                    "stw     %[tmp],4(%[tlb])  \n\t"
+                    "tlbre   %[tmp],%[key],1   \n\t"
+                    "stw     %[tmp],8(%[tlb])  \n\t"
+                    "tlbre   %[tmp],%[key],2   \n\t"
+                    "stw     %[tmp],12(%[tlb]) \n\t"
+                    "sync                      \n\t"
+                    : [tmp]"=&r"(tmp)
+                    : [key]"r"(key),
+                      [tlb]"b"(tlb)
+                    );
+}
+
+
+static void
+store(bsp_tlb_idx_t key, bsp_tlb_entry_t* tlb)
+{
+  register uint32_t tmp;
+  __asm__ volatile ("lwz     %[tmp],0(%[tlb])  \n\t"
+                    "mtpid   %[tmp]            \n\t"
+                    "lwz     %[tmp],4(%[tlb])  \n\t"
+                    "tlbwe   %[tmp],%[idx],0   \n\t"
+                    "lwz     %[tmp],8(%[tlb])  \n\t"
+                    "tlbwe   %[tmp],%[idx],1   \n\t"
+                    "lwz     %[tmp],12(%[tlb]) \n\t"
+                    "tlbwe   %[tmp],%[idx],2   \n\t"
+                    : [tmp]"=&r"(tmp)
+                    : [tlb]"b"(tlb),
+                      [idx]"r"(key)
+                    );
+}
+
+
+static void
+commit(void)
+{
+  __asm__ volatile("isync           \n\t");
+}
+
+
+/*
+ * Read a TLB entry from the hardware store the current settings in the
+ * bsp_mmu_cache[] structure.
+ *
+ * The routine can perform this operation quietly or
+ * print information to a file.
+ *
+ *   'idx': which TLB entry to access.
+ * 'quiet': perform operation silently (no info printed)
+ *          if nonzero.
+ *     'f': open FILE where to print information. May be
+ *          NULL in which case 'stdout' is used.
+ *
+ * RETURNS:
+ *       0: success; TLB entry is VALID
+ *      +1: success but TLB entry is INVALID
+ *     < 0: error (-1: invalid argument)
+ *                (-2: driver not initialized)
+ */
+int
+bsp_mmu_update(bsp_tlb_idx_t key, bool quiet, FILE *f)
+{
+  rtems_interrupt_level lvl;
+  bsp_tlb_entry_t*      tlb;
+  int                   idx;
+
+  idx = key;
+
+  if ( idx < 0 || idx > NTLBS-1 )
+    return -1;
+
+  if (!bsp_mmu_cache)
+    return -2;
+
+  tlb = bsp_mmu_cache + idx;
+
+  rtems_interrupt_disable(lvl);
+
+  fetch(idx, tlb);
+
+  rtems_interrupt_enable(lvl);
+
+  if ( tlb->w0.v ) {
+    if ( !quiet ) {
+/*
+               "TLB Entry #  0 spans EA range    0x00000000 - 0x00000000
+               "Mapping:     VA   [TS 0 / TID 0x00 / EPN 0x00000] -> RPN 0x00000"
+               "Size:        TSIZE 0x0 (4^sz KB = 000000 KB = 0x00000000 B)
+               "Attributes:  PERM  0x000 (ux/uw/ur/sx/sw/sr) WIMGE 0x00 U0-3 0x0"
+*/
+      myprintf(f,
+               "TLB Entry # %2d spans EA range    0x%08x - 0x%08x\n",
+               idx,
+               (tlb->w0.epn << 10),
+               (tlb->w0.epn << 10) + (1024<<(2*tlb->w0.size)) - 1
+               );
+
+      myprintf(f,
+               "Mapping:     VA   [TS %d / TID 0x%02x / EPN 0x%05x] -> RPN 0x%05"PRIx32"\n",
+               tlb->w0.ts, tlb->id.tid, tlb->w0.epn, tlb->w1.rpn
+               );
+      myprintf(f,
+               "Size:        TSIZE 0x%x (4^sz KB = %6d KB = 0x%08x B)\n",
+               tlb->w0.size, (1<<(2*tlb->w0.size)), (1024<<(2*tlb->w0.size))
+               );
+      myprintf(f,
+               "Properties:  PERM  0x%03x (ux/uw/ur/sx/sw/sr) WIMGE 0x%02x U0-3 0x%01x\n",
+               tlb->w2.perm, tlb->w2.wimge, tlb->w2.att
+               );
+    }
+  } else {
+    if ( !quiet ) {
+      myprintf(f, "TLB Entry # %2d <OFF> (size 0x%x = 0x%xb)\n",
+               idx, tlb->w0.size, (1024<<(2*tlb->w0.size)));
+    }
+    return 1;
+  }
+  return 0;
+}
+
+/* Initialize cache.  Should be done only once although this is not enforced.
+ *
+ * RETURNS: zero on success, nonzero on error; in this case the driver will
+ *          refuse to change TLB entries (other than disabling them).
+ */
+int
+bsp_mmu_initialize()
+{
+  static bsp_tlb_entry_t mmu_cache[NTLBS];
+  bsp_tlb_entry_t*       tlb = mmu_cache;  /* Should malloc if it's not too early */
+  rtems_interrupt_level  lvl;
+
+  bsp_tlb_idx_t idx;
+  rtems_interrupt_disable(lvl);
+  for (idx=0; idx<NTLBS; tlb++, idx++)
+  {
+    fetch(idx, tlb);
+  }
+  rtems_interrupt_enable(lvl);
+
+  bsp_mmu_cache = mmu_cache;
+  return 0;
+}
+
+/* Find first free TLB entry by examining all entries' valid bit.  The first
+ * entry without the valid bit set is returned.
+ *
+ * RETURNS: A free TLB entry number.  -1 if no entry can be found.
+ */
+bsp_tlb_idx_t
+bsp_mmu_find_first_free()
+{
+  bsp_tlb_idx_t   idx;
+  bsp_tlb_entry_t entry;
+
+  for (idx=0; idx<NTLBS; idx++) {
+    register uint32_t tmp;
+    __asm__ volatile ("tlbre   %[tmp],%[idx],0   \n\t"
+                      "stw     %[tmp],4(%[tlb])  \n\t" /* entry.w0 */
+                      "sync                      \n\t"
+                      : [tmp]"=&r"(tmp)
+                      : [idx]"r"(idx),
+                        [tlb]"b"(&entry)
+                      : "memory"
+                      );
+    if (!(entry.w0.v))
+      break;
+  }
+  return (idx < NTLBS) ? idx : -1;
+}
+
+/*
+ * Write TLB entry (can also be used to disable an entry).
+ *
+ * The routine checks against the cached data in
+ * bsp_mmu_cache[] to prevent the user from generating
+ * overlapping entries.
+ *
+ *   'idx': TLB entry # to manipulate
+ *    'ea': Effective address (must be page aligned)
+ *    'pa': Physical  address (must be page aligned)
+ *    'sz': Page size selector; page size is
+ *          1024 * 2^(2*sz) bytes.
+ *          'sz' may also be one of the following:
+ *          - page size in bytes ( >= 1024 ); the selector
+ *            value is then computed by this routine.
+ *            However, 'sz' must be a valid page size
+ *            or -1 will be returned.
+ *          - a value < 0 to invalidate/disable the
+ *            TLB entry.
+ *  'flgs': Page's User-defined flags, permissions and WIMGE page attributes
+ *   'tid': Translation ID
+ *    'ts': Translation Space
+ *  'erpn': Extended Real Page Number
+ *
+ * RETURNS: 0 on success, nonzero on error:
+ *
+ *         >0: requested mapping would overlap with
+ *             existing mapping in other entry. Return
+ *             value gives conflicting entry + 1; i.e.,
+ *             if a value of 4 is returned then the request
+ *             conflicts with existing mapping in entry 3.
+ *         -1: invalid argument
+ *         -3: driver not initialized (or initialization failed).
+ *         <0: other error
+ */
+bsp_tlb_idx_t
+bsp_mmu_write(bsp_tlb_idx_t idx, uint32_t ea, uint32_t pa, int sz,
+              uint32_t flgs, uint32_t tid, uint32_t ts, uint32_t erpn)
+{
+  bsp_tlb_entry_t       tlb;
+  uint32_t              msk;
+  bsp_tlb_idx_t         lkup;
+  rtems_interrupt_level lvl;
+
+  if ( sz >= 1024 ) {
+    /* Assume they literally specify a size */
+    msk = sz;
+    sz  = 0;
+    while ( msk != (1024<<(sz+sz)) ) {
+      if ( ++sz > 15 ) {
+        return -1;
+      }
+    }
+    /* OK, acceptable */
+  }
+
+  msk = sz > 0 ? (1024<<(sz+sz)) - 1 : 0;
+
+  if ( !bsp_mmu_cache && sz > 0 ) {
+    myprintf(stderr,"MMU driver not initialized; refusing to enable any entry\n");
+    return -3;
+  }
+
+  if ( (ea & msk) || (pa & msk) ) {
+    myprintf(stderr,"Misaligned EA (%08x) or PA (%08x) (mask is %08x)\n", ea, pa, msk);
+    return -1;
+  }
+
+  if ( idx < 0 || idx > NTLBS-1 )
+    return -1;
+
+  /* Not all 16 possible sizes are supported */
+  if ( sz == 6 || sz == 8 || sz > 9 ) {
+    myprintf(stderr,"Invalid size %u = %08x = %u KB\n", sz, 1024<<(sz+sz), (1024<<(sz+sz))/1024);
+    return -1;
+  }
+
+  if ( sz >=0 ) {
+    lkup = bsp_mmu_match(ea, sz, tid, ts);
+
+    if ( lkup < -1 ) {
+      /* some error */
+      return lkup;
+    }
+
+    if ( lkup >= 0 && lkup != idx && (bsp_mmu_cache[lkup].w0.v != 0) ) {
+      myprintf(stderr,"TLB #%i overlaps with requested mapping\n", lkup);
+      bsp_mmu_update( lkup, false, stderr);
+      return lkup+1;
+    }
+  }
+
+  /* OK to proceed */
+  tlb.id.tid  = tid;
+  tlb.w0.v    = sz >= 0;
+  tlb.w0.ts   = ts;
+  tlb.w0.size = sz;
+  tlb.w0.epn = (ea & (0xfffffc00 << (sz+sz))) >> 10;
+  if (sz < 11) {
+    tlb.w1.rpn  = (pa & (0xfffffc00 << (sz+sz))) >> 10;
+    tlb.w1.erpn = erpn;
+  }
+  else {
+    sz -= 11;
+    tlb.w1.rpn  = 0;
+    tlb.w1.erpn = (erpn & (0xf << (sz+sz))) & 0xf;
+  }
+  tlb.w2.att   = (flgs & MMU_M_ATTR) >> MMU_V_ATTR;
+  tlb.w2.wimge = (flgs & MMU_M_PROP) >> MMU_V_PROP;
+  tlb.w2.perm  = (flgs & MMU_M_PERM) >> MMU_V_PERM;
+
+  rtems_interrupt_disable(lvl);
+
+  store(idx, &tlb);
+
+  commit();
+
+  rtems_interrupt_enable(lvl);
+
+  /* update cache */
+  bsp_mmu_update(idx, true, 0);
+
+  return 0;
+}
+
+/*
+ * Check if a ea/tid/ts/sz mapping overlaps with an existing entry.
+ *
+ *    'ea': The Effective Address to match against
+ *    'sz': The 'logarithmic' size selector; the page size
+ *          is 1024*2^(2*sz).
+ *   'tid': Translation ID
+ *    'ts': Translation Space
+ *
+ * RETURNS:
+ *     >= 0: index of the TLB entry that already provides a mapping
+ *           which overlaps within the ea range.
+ *       -1: SUCCESS (no conflicting entry found)
+ *     <=-2: ERROR (invalid input)
+ */
+bsp_tlb_idx_t
+bsp_mmu_match(uint32_t ea, int sz, uint32_t tid, uint32_t ts)
+{
+  bsp_tlb_idx_t    idx;
+  uint32_t         m,a;
+  bsp_tlb_entry_t* tlb;
+
+  if ( sz < 0 || sz == 6 || sz == 8 || sz > 9 )
+    return -4;
+
+  sz = (1024<<(2*sz));
+
+  if ( !bsp_mmu_cache ) {
+    /* cache not initialized */
+    return -3;
+  }
+
+  if ( ea & (sz-1) ) {
+    /* misaligned ea */
+    return -2;
+  }
+
+  for ( idx=0, tlb=bsp_mmu_cache; idx<NTLBS; idx++, tlb++ ) {
+    if ( ! tlb->w0.v )
+      continue;
+    if ( tlb->id.tid && tlb->id.tid != tid )
+      continue;
+    if ( tlb->w0.ts != ts )
+      continue;
+    /* TID and TS match a valid entry */
+    m  = (1024<<(2*tlb->w0.size)) - 1;
+    /* calculate starting address of this entry */
+    a  = tlb->w0.epn<<10;
+    if ( ea <= a + m && ea + sz -1 >= a ) {
+      /* overlap */
+      return idx;
+    }
+  }
+  return -1;
+}
+
+/* Find TLB index that maps 'ea/tid/ts' combination
+ *
+ *    'ea': Effective address to match against
+ *   'tid': Translation ID
+ *    'ts': Translation Space
+ *
+ * RETURNS: index 'key' which indicates whether
+ *          the mapping was found.
+ *
+ *          On error (no mapping) -1 is returned.
+ */
+bsp_tlb_idx_t
+bsp_mmu_find(uint32_t ea, uint32_t tid, uint32_t ts)
+{
+  rtems_interrupt_level  lvl;
+  register uint32_t      mmucr;
+  register bsp_tlb_idx_t idx;
+  register int           failure;
+
+  rtems_interrupt_disable(lvl);
+
+  __asm__ volatile ("mfspr  %[mmucr],0x3b2  \n\t" /* Save MMUCR */
+                    : [mmucr]"=r"(mmucr)
+                    );
+  __asm__ volatile ("mtspr  0x3b2,%[tid]    \n\t"
+                    "tlbsx. %[idx],0,%[ea]  \n\t" /* Failure changes the index reg randomly. */
+                    "mfcr   %[failure]      \n\t"
+                    "mtspr  0x3b2,%[mmucr]  \n\t" /* Restore MMUCR */
+                    : [idx]"=&r"(idx),
+                      [failure]"=&r"(failure)
+                    : [tid]"r"((mmucr & 0xfffeff00) | (ts << 16) | tid),
+                      [ea]"r"(ea),
+                      [mmucr]"r"(mmucr)
+                    : "cc"
+                    );
+
+  rtems_interrupt_enable(lvl);
+
+  return (failure & 0x20000000) ? idx : -1;
+}
+
+/* Mark TLB entry as invalid ('disabled').
+ *
+ * 'key': TLB entry (index).
+ *
+ * RETURNS: zero on success, nonzero on error (TLB unchanged).
+ *
+ * NOTE:  If a TLB entry is disabled the associated
+ *        entry in bsp_mmu_cache[] is also
+ *        marked as disabled.
+ */
+int
+bsp_mmu_invalidate(bsp_tlb_idx_t key)
+{
+  bsp_tlb_idx_t         k0;
+  rtems_interrupt_level lvl;
+  bsp_tlb_entry_t       tlb;
+  uint32_t              msr;
+
+  /* minimal guard against bad key */
+  if ( key < 0 || key > NTLBS-1 )
+    return -1;
+
+  /* Must not invalidate page 0 which holds vectors, text etc...  */
+  k0 = bsp_mmu_find(0, 0, 0);
+  if ( -1 == k0 ) {
+    myprintf(stderr,"No mapping for address 0 found\n");
+    return -2;
+  }
+
+  /* NOTE: we assume PID is ignored */
+  if ( k0 == key ) {
+    myprintf(stderr,"Cannot invalidate page holding address 0 (always needed)\n");
+    return -3;
+  }
+
+  rtems_interrupt_disable(lvl);
+
+  fetch(key, &tlb);
+
+  /* Invalidate old entries */
+  tlb.w0.v = 0;
+
+  store(key, &tlb);
+
+  commit();
+
+  /* Update cache */
+  bsp_mmu_cache[ key ].w0.v = tlb.w0.v;
+
+  rtems_interrupt_enable(lvl);
+
+  return 0;
+}
diff --git a/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c b/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c
index 8847dc8..53e8a37 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c
@@ -54,20 +54,23 @@
  *  Modifications for PPC405GP by Dennis Ehlin
  *  Modifications for Virtex5 by Richard Claus <claus at slac.stanford.edu>
  */
-
-#include <string.h>
-#include <fcntl.h>
-
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <bsp/vectors.h>
+#include <rtems.h>
+#include <rtems/config.h>
 #include <rtems/bspIo.h>
 #include <rtems/libio.h>
 #include <rtems/libcsupport.h>
-#include <rtems/sptables.h>             /* for RTEMS_VERSION */
+
 #include <libcpu/cpuIdent.h>
 #include <libcpu/spr.h>
 
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq.h>
+
+#include <string.h>
+#include <fcntl.h>
+
 #define DO_DOWN_ALIGN(x,a) ((x) & ~((a)-1))
 
 #define DO_UP_ALIGN(x,a)   DO_DOWN_ALIGN(((x) + (a) - 1 ),a)
@@ -75,14 +78,6 @@
 #define CPU_DOWN_ALIGN(x)  DO_DOWN_ALIGN(x, CPU_ALIGNMENT)
 #define CPU_UP_ALIGN(x)    DO_UP_ALIGN(x, CPU_ALIGNMENT)
 
-
-/* Expected by clock.c */
-uint32_t    bsp_clicks_per_usec;
-bool        bsp_timer_internal_clock;   /* true, when timer runs with CPU clk */
-uint32_t    bsp_timer_least_valid;
-uint32_t    bsp_timer_average_overhead;
-
-
 /* Defined in linkcmds linker script */
 LINKER_SYMBOL(RamBase);
 LINKER_SYMBOL(RamSize);
@@ -96,35 +91,37 @@ LINKER_SYMBOL(WorkAreaBase);
 LINKER_SYMBOL(MsgAreaBase);
 LINKER_SYMBOL(MsgAreaSize);
 LINKER_SYMBOL(__phy_ram_end);
+LINKER_SYMBOL(bsp_exc_vector_base);
 
 
+/* Expected by clock.c */
+uint32_t    bsp_clicks_per_usec;
+bool        bsp_timer_internal_clock;   /* true, when timer runs with CPU clk */
+uint32_t    bsp_timer_least_valid;
+uint32_t    bsp_timer_average_overhead;
+
 /*
- * Provide weak aliases so that RTEMS distribution builds
+ * Bus Frequency
  */
-static void _noopfun(void) {}
-static void _bsp_start(void)
-{
-  uintptr_t         intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start);
-  uintptr_t         intrStackSize  = rtems_configuration_get_interrupt_stack_size();
+unsigned int BSP_bus_frequency;
+/*
+ * processor clock frequency
+ */
+unsigned int BSP_processor_frequency;
 
-  /*
-   * Initialize default raw exception handlers.
-   *
-   * This BSP does not assume anything about firmware possibly loaded in the
-   * FPGA, so the external interrupt should not be enabled in order to avoid
-   * spurious interrupts.
-   */
-  ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT & ~MSR_EE,
-                     intrStackStart,
-                     intrStackSize);
+/*
+ * Time base divisior (bus freq / TB clock)
+ */
+unsigned int BSP_time_base_divisor;
 
-  /* Install our own set of exception vectors */
-  BSP_rtems_irq_mngt_init(0);
-}
+/*
+ * Provide weak aliases so that RTEMS distribution builds
+ */
+static void _noopfun(void) {}
 
 
 void app_bsp_start(void)
-__attribute__(( weak, alias("_bsp_start") ));
+__attribute__(( weak, alias("_noopfun") ));
 
 void app_bsp_pretasking_hook(void)
 __attribute__(( weak, alias("_noopfun") ));
@@ -147,20 +144,31 @@ static void __bsp_outchar_to_memory(char c)
 void BSP_ask_for_reset(void)
 {
   printk("\nSystem stopped, issue RESET");
+
   for(;;);
 }
 
 
 void BSP_panic(char *s)
 {
-  printk("\n%s PANIC %s\n", _RTEMS_version, s);
+  rtems_interrupt_level level;
+
+  rtems_interrupt_disable(level);
+
+  printk("\n%s PANIC %s\n", rtems_get_version_string(), s);
+
   BSP_ask_for_reset();
 }
 
 
 void _BSP_Fatal_error(unsigned int v)
 {
-  printk("\n%s FATAL ERROR %x\n", _RTEMS_version, v);
+  rtems_interrupt_level level;
+
+  rtems_interrupt_disable(level);
+
+  printk("\n%s FATAL ERROR %x\n", rtems_get_version_string(), v);
+
   BSP_ask_for_reset();
 }
 
@@ -176,13 +184,14 @@ void bsp_start(void)
 {
   uintptr_t          intrStackStart;
   uintptr_t          intrStackSize;
+
   ppc_cpu_id_t       myCpu;
   ppc_cpu_revision_t myCpuRevision;
 
   /* Set the character output function;  The application may override this */
   BSP_output_char = __bsp_outchar_to_memory;
 
-  printk("\nWelcome to RTEMS %s\n", _RTEMS_version );
+  printk("RTEMS %s\n", rtems_get_version_string());
 
   /*
    * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
@@ -197,8 +206,13 @@ void bsp_start(void)
    *  Initialize the device driver parameters
    */
 
+  /* For mpc6xx clock driver: */
+  BSP_bus_frequency       = 465000000;
+  BSP_processor_frequency = 465000000;  /* Measured with a DPM 440 2012/8/13 */
+  BSP_time_base_divisor   = 1000;
+
   /* Timebase register ticks/microsecond;  The application may override these */
-  bsp_clicks_per_usec        = 450;
+  bsp_clicks_per_usec        = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
   bsp_timer_internal_clock   = true;
   bsp_timer_average_overhead = 2;
   bsp_timer_least_valid      = 3;
@@ -208,6 +222,15 @@ void bsp_start(void)
    */
   intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start);
   intrStackSize  = rtems_configuration_get_interrupt_stack_size();
+
+  sc = ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
+                          intrStackStart,
+                          intrStackSize);
+  if (sc != RTEMS_SUCCESSFUL) {
+    BSP_panic("Cannot initialize exceptions");
+  }
+
+  /* Let the user know what parameters we were compiled with */
   printk("                  Base/Start     End         Size\n"
          "RAM:              0x%08x              0x%x\n"
          "RTEMS:                        0x%08x\n"
@@ -224,6 +247,11 @@ void bsp_start(void)
          (uint32_t)MsgAreaBase,                           (uint32_t)MsgAreaSize,
          (uint32_t)__phy_ram_end);
 
+  /*
+   * Initialize RTEMS IRQ system
+   */
+  BSP_rtems_irq_mngt_init(0);
+
   /* Continue with application-specific initialization */
   app_bsp_start();
 }
diff --git a/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds b/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds
index 20d4095..a92d9a1 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds
+++ b/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds
@@ -20,16 +20,17 @@ HeapSize          = DEFINED(HeapSize)      ? HeapSize      : 0; /* 0=Use def */
 
 MEMORY
 {
-  VECTORS         : ORIGIN = 0x00000000, LENGTH = 8K
-  RAM             : ORIGIN = 0x00002000, LENGTH = 2048M - 8K
+  VECTORS         : ORIGIN = 0x00000000, LENGTH = 512
+  RAM             : ORIGIN = 0x00000200, LENGTH = 2048M - 512
 }
 
 
 SECTIONS
 {
-  __exeentry      = download_entry;
-  __exestart      = 0x100;
-  .vectors __exestart : { *(.vectors)                           } > VECTORS
+  bsp_exc_vector_base = 0;
+  __exeentry          = download_entry;
+  __exestart          = bsp_exc_vector_base;
+  .vectors bsp_exc_vector_base : { *(.vectors)                  } > VECTORS
 
   /* Read-only sections, merged into text segment: */
   .interp         : { *(.interp)                                } > RAM
diff --git a/c/src/lib/libbsp/powerpc/virtex5/startup/start.S b/c/src/lib/libbsp/powerpc/virtex5/startup/start.S
index 1afa587..40938e5 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/startup/start.S
+++ b/c/src/lib/libbsp/powerpc/virtex5/startup/start.S
@@ -61,6 +61,7 @@
 
 #include <rtems/asm.h>
 #include <rtems/powerpc/powerpc.h>
+#include <rtems/powerpc/registers.h>
 
 #define   V_TS_SZ_I    0x0290      // V,TS=0(Inst),SIZE=9,TID=0
 #define   V_TS_SZ_D    0x0390      // V,TS=1(Data),SIZE=9,TID=0
@@ -154,43 +155,44 @@ first:  li      r0,0              // Clear r0
 
        /*------------------------------------------------------------------
         * Set Core Configuration Register 0 as follows:
-        * sum: 0x00200000
+        * sum: 0x00206000
         * bit  1    off  Parity Recovery Enable
         * bit  4    off  Cache Read Parity Enable
         * bit 10    on   Disable Store Gathering
         * bit 11    off  Disable APU Instruction Broadcast
         * bit 16    off  Disable Trace Broadcast
-        * bit 17:18 off  Specifies behaviour of icbt,dcbt/dcbtst insts
+        * bit 17:18 on   Specifies behaviour of icbt,dcbt/dcbtst insts
         * bit 23    off  Force Load/Store Alignment
         * bit 28:29 off  Instruction Cache Speculative Line Count
         * bit 30:31 off  Instruction Cache Speculative Line Threshold
         *            NB: UG200/pg 21: Spec. prefetching must be disabled
         *------------------------------------------------------------------*/
 
-        lis     r2,0x0020         // 7. Set CCR0: DSTG
-        mtccr0  r2                // Configure CCR0
+        lis     r2,   0x00206000 at h // 7. Set CCR0: DSTG
+        ori     r2,r2,0x00206000 at l //    Set CCR0: GDCBT, GICBT
+        mtccr0  r2                 // Configure CCR0
 
-        mtspr   ccr1,r0           // 8. Clear CCR1
+        mtspr   PPC440_CCR1,r0     // 8. Clear CCR1
 
        /*------------------------------------------------------------------
 	* 9. Configure cache regions
         *------------------------------------------------------------------*/
-	mtspr   inv0,r0
-	mtspr   inv1,r0
-	mtspr   inv2,r0
-	mtspr   inv3,r0
-	mtspr   dnv0,r0
-	mtspr   dnv1,r0
-	mtspr   dnv2,r0
-	mtspr   dnv3,r0
-	mtspr   itv0,r0
-	mtspr   itv1,r0
-	mtspr   itv2,r0
-	mtspr   itv3,r0
-	mtspr   dtv0,r0
-	mtspr   dtv1,r0
-	mtspr   dtv2,r0
-	mtspr   dtv3,r0
+	mtspr   PPC440_INV0,r0
+	mtspr   PPC440_INV1,r0
+	mtspr   PPC440_INV2,r0
+	mtspr   PPC440_INV3,r0
+	mtspr   PPC440_DNV0,r0
+	mtspr   PPC440_DNV1,r0
+	mtspr   PPC440_DNV2,r0
+	mtspr   PPC440_DNV3,r0
+	mtspr   PPC440_ITV0,r0
+	mtspr   PPC440_ITV1,r0
+	mtspr   PPC440_ITV2,r0
+	mtspr   PPC440_ITV3,r0
+	mtspr   PPC440_DTV0,r0
+	mtspr   PPC440_DTV1,r0
+	mtspr   PPC440_DTV2,r0
+	mtspr   PPC440_DTV3,r0
 
        /*------------------------------------------------------------------
 	* Cache victim limits
@@ -198,8 +200,8 @@ first:  li      r0,0              // Clear r0
         *------------------------------------------------------------------*/
 	lis	r2,   0x0001f800 at h
 	ori	r2,r2,0x0001f800 at l
-	mtspr   ivlim,r2
-	mtspr   dvlim,r2
+	mtspr   PPC440_IVLIM,r2
+	mtspr   PPC440_DVLIM,r2
 
        /*------------------------------------------------------------------
         * Configure instruction and data cache regions:
@@ -241,7 +243,7 @@ first:  li      r0,0              // Clear r0
         *    31  SR    1     1     Supervisor State Read Enable
         *------------------------------------------------------------------*/
 
-        mtspr   mmucr,r0          // 10a. Clear MMUCR
+        mtspr   PPC440_MMUCR,r0   // 10a. Clear MMUCR
         li      r7,WIMG_U_S_1     // Word 2: Pages are NOT cache inhibited
         lis     r6,   PAGE_SZ at h   // Page size constant
         ori     r6,r6,PAGE_SZ at l
@@ -255,9 +257,9 @@ first:  li      r0,0              // Clear r0
         * Select whether Wait Enable, interrupts/exceptions and which address
         * spaces should be enabled when application starts
         *------------------------------------------------------------------*/
-        lis     r0,   0x00000000 at h // 10d. MSR[IS]=0 MSR[DS]=0
-        ori     r0,r0,0x00000000 at l
-        mtsrr1  r0
+        lis     r3,   0x00000000 at h // 10d. MSR[IS]=0 MSR[DS]=0
+        ori     r3,r3,0x00000000 at l
+        mtsrr1  r3
         mtsrr0  r28               // Return address
         rfi                       // Context synchronize to invalidate shadow TLB contents
 
@@ -275,43 +277,43 @@ startupDL:
         * 11. Tell the processor where the exception vector table will be
         *------------------------------------------------------------------*/
         .extern SYM(__vectors)
-        lis     r2, __vectors at h     /* set EVPR exc. vector prefix */
-        mtspr   ivpr,r2
+        lis     r1, __vectors at h     /* set EVPR exc. vector prefix */
+        mtspr   BOOKE_IVPR,r1
 
        /*------------------------------------------------------------------
         * Set up default exception and interrupt vectors
         *------------------------------------------------------------------*/
-        li       r1,0x100
+        li       r1,0
         mtivor0  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor1  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor2  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor3  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor4  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor5  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor6  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor7  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor8  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor9  r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor10 r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor11 r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor12 r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor13 r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor14 r1
-        addi     r1,r1,0x100
+        addi     r1,r1,0x10
         mtivor15 r1
 
        /*------------------------------------------------------------------
@@ -336,16 +338,15 @@ startupDL:
         * 13. Configure timer facilities
         *------------------------------------------------------------------*/
         mtdec   r0                // Clear Decrementer to prevent exception
-        mttbu   r0                // Clear Timebase to prevent Fixed Interval..
-        mttbl   r0                // ..timer and Watchdog Timer exceptions
+        mttbl   r0                // Clear Timebase to prevent Fixed Interval..
+        mttbu   r0                // ..timer and Watchdog Timer exceptions
         mtpit   r0                // Programmable interval timer
-        li      r1,-1             // -1 to clear TSR
-        mttsr   r1                // Timer status register
+        li      r2,-1             // -1 to clear TSR
+        mttsr   r2                // Timer status register
 
        /*-------------------------------------------------------------------
         * Clear out stale values in certain registers to avoid confusion
         *------------------------------------------------------------------*/
-        li      r0,0
         mtcrf   0xff,r0           // Need for simulation
         mtctr   r0                // Counter register
         mtxer   r0                // Fixed-point exception register
-- 
1.7.1




More information about the devel mailing list