Index: bsps/powerpc/include/libcpu/bat.h
===================================================================
--- bsps/powerpc/include/libcpu/bat.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/bat.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,85 @@
+/*
+ * bat.h
+ *
+ *	    This file contains declaration of C function to
+ *          Instantiate 60x/7xx ppc Block Address Translation (BAT) registers.
+ *	    More detailed information can be found on motorola
+ *	    site and more precisely in the following book :
+ *
+ *		MPC750
+ *		Risc Microporcessor User's Manual
+ *		Motorola 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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_BAT_H
+#define _LIBCPU_BAT_H
+
+#include <libcpu/mmu.h>
+#include <libcpu/pgtable.h>
+
+#define IO_PAGE	(_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW)
+
+#ifndef ASM
+/* Take no risks -- the essential parts of this routine run with
+ * interrupts disabled!
+ *
+ * The routine does basic parameter checks:
+ *   - Index must be 0..3 (0..7 on 7455, 7457).
+ *     If an index > 3 is requested the 745x is
+ *     programmed to enable the higher BATs.
+ *   - Size must be a power of two and <= 1<<28
+ *     (<=1<<31 on 7455, 7457. Also, on these processors
+ *     the special value 0xffffffff is allowed which stands
+ *     for 1<<32).
+ *     If a size > 1<<28 is requested, the 745x is
+ *     programmed to enable the larger block sizes.
+ *   - Bat ranges must not overlap.
+ *   - Physical & virtual addresses must be aligned
+ *     to the size.
+ *
+ * RETURNS: zero on success, nonzero on failure.
+ */
+extern int setdbat(int bat_index, unsigned long virt, unsigned long phys,
+		    unsigned int size, int flags);
+
+/* Same as setdbat but sets IBAT */
+extern int setibat(int bat_index, unsigned long virt, unsigned long phys,
+		    unsigned int size, int flags);
+
+/* read DBAT # 'idx' into *pu / *pl. NULL pointers may be passed.
+ * If pu and pl are NULL, the bat contents are dumped to the console (printk).
+ *
+ * RETURNS: upper BAT contents or (-1) if index is invalid
+ */
+extern int getdbat(int bat_index, unsigned long *pu, unsigned long *pl);
+
+/* Same as getdbat but reads IBAT */
+extern int getibat(int bat_index, unsigned long *pu, unsigned long *pl);
+
+/* Do not use the asm-routines; they are obsolete; use setdbat() instead */
+extern void asm_setdbat0(unsigned int uperPart, unsigned int lowerPart);
+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);
+#else
+
+/* Initialize all bats (upper and lower) to zero. This routine should *only*
+ * be called during early BSP initialization when no C-ABI is available
+ * yet.
+ * This routine clobbers r3 and r4.
+ * NOTE: on 7450 CPUs all 8 dbat/ibat units are cleared. On 601 CPUs only
+ *       4 ibats.
+ */
+	.globl CPU_clear_bats_early
+	.type  CPU_clear_bats_early,@function
+
+#endif
+
+#endif /* _LIBCPU_BAT_H */
Index: bsps/powerpc/include/libcpu/byteorder.h
===================================================================
--- bsps/powerpc/include/libcpu/byteorder.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/byteorder.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,54 @@
+/*
+ * byteorder.h
+ *
+ *        This file contains inline implementation of function to
+ *          deal with endian conversion.
+ *
+ * It is a stripped down version of linux ppc file...
+ *
+ * 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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_BYTEORDER_H
+#define _LIBCPU_BYTEORDER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline unsigned ld_le16(volatile uint16_t *addr)
+{
+	unsigned val;
+
+	__asm__ volatile ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+	return val;
+}
+
+static inline void st_le16(volatile uint16_t *addr, unsigned val)
+{
+	__asm__ volatile ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+}
+
+static inline unsigned ld_le32(volatile uint32_t *addr)
+{
+	unsigned val;
+
+	__asm__ volatile ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+	return val;
+}
+
+static inline void st_le32(volatile uint32_t *addr, unsigned val)
+{
+	__asm__ volatile ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBCPU_BYTEORDER_H */
Index: bsps/powerpc/include/libcpu/c_clock.h
===================================================================
--- bsps/powerpc/include/libcpu/c_clock.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/c_clock.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,56 @@
+/*
+ *  Clock Tick Device Driver
+ *
+ *  This routine utilizes the Decrementer Register common to the PPC family.
+ *
+ *  The tick frequency is directly programmed to the configured number of
+ *  microseconds per tick.
+ *
+ *  COPYRIGHT (c) 1989-1997.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Modified to support the MPC750.
+ *  Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
+ */
+
+#ifndef _LIBCPU_C_CLOCK_H
+#define _LIBCPU_C_CLOCK_H
+
+#include <rtems.h>
+
+/*
+ * These functions and variables represent the API exported by the
+ * CPU to the BSP.
+ */
+
+extern void clockOff	(void* unused);
+extern void clockOn	(void* unused);
+extern void clockIsr	(void* unused);
+/* bookE decrementer is slightly different */
+extern void clockIsrBookE (void *unused);
+extern int  clockIsOn	(void* unused);
+
+/*
+ *  These functions and variables represent the assumptions of this
+ *  driver on the BSP.
+ */
+
+extern int BSP_disconnect_clock_handler (void);
+/*
+ * PCI Bus Frequency
+ */
+extern unsigned int BSP_bus_frequency;
+/*
+ * processor clock frequency
+ */
+extern unsigned int BSP_processor_frequency;
+/*
+ * Time base divisior (how many tick for 1 second).
+ */
+extern unsigned int BSP_time_base_divisor;
+
+#endif
Index: bsps/powerpc/include/libcpu/cpuIdent.h
===================================================================
--- bsps/powerpc/include/libcpu/cpuIdent.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/cpuIdent.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 1999  Eric Valette (valette@crf.canon.fr)
+ *                     Canon Centre Recherche France.
+ *
+ *  Added MPC8260 Andy Dachs <a.dachs@sstl.co.uk>
+ *  Surrey Satellite Technology Limited
+ *
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_CPUIDENT_H
+#define _LIBCPU_CPUIDENT_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASM
+typedef enum
+{
+  PPC_601 = 0x1,
+  PPC_5XX = 0x2,
+  PPC_603 = 0x3,
+  PPC_604 = 0x4,
+  PPC_603e = 0x6,
+  PPC_603ev = 0x7,
+  PPC_750 = 0x8,
+  PPC_750_IBM = 0x7000,
+  PPC_604e = 0x9,
+  PPC_604r = 0xA,
+  PPC_7400 = 0xC,
+  PPC_405  = 0x2001,  /* Xilinx Virtex-II Pro or -4 */
+  PPC_405EX = 0x1291,	/* + 405EXr */
+  PPC_405GP = 0x4011,	/* + 405CR */
+  PPC_405GPr = 0x5091,
+  PPC_405EZ = 0x4151,
+  PPC_405EP = 0x5121,
+  PPC_440 = 0x7ff2,  /* Xilinx Virtex-5*/
+  PPC_7455 = 0x8001, /* Kate Feng */
+  PPC_7457 = 0x8002,
+  PPC_620 = 0x16,
+  PPC_860 = 0x50,
+  PPC_821 = PPC_860,
+  PPC_823 = PPC_860,
+  PPC_8260 = 0x81,
+  PPC_8240 = PPC_8260,
+  PPC_8245 = 0x8081,
+  PPC_8540 = 0x8020,
+  PPC_e500v2 = 0x8021,
+  PPC_e6500 = 0x8040,
+  PPC_603le = 0x8082, /* 603le core, in MGT5100 and MPC5200 */
+  PPC_e300c1  = 0x8083, /* e300c1  core, in MPC83xx*/
+  PPC_e300c2  = 0x8084, /* e300c2  core */
+  PPC_e300c3  = 0x8085, /* e300c3  core */
+  PPC_e200z0  = 0x8170,
+  PPC_e200z1  = 0x8140,
+  PPC_e200z4  = 0x8150,
+  PPC_e200z6  = 0x8110,
+  PPC_e200z7  = 0x8160,
+  PPC_PSIM    = 0xfffe,  /* GDB PowerPC simulator -- fake version */
+  PPC_UNKNOWN = 0xffff
+} ppc_cpu_id_t;
+
+/* Bitfield of for identifying features or groups of cpu flavors.
+ * DO NOT USE DIRECTLY (as implementation may change)
+ * only use the 'ppc_is_xxx() / ppc_has_xxx()' macros/inlines
+ * below.
+ */
+
+typedef struct {
+	unsigned has_altivec		: 1;
+	unsigned has_fpu			: 1;
+	unsigned has_hw_ptbl_lkup	: 1;
+#define PPC_BOOKE_405   1	/* almost like booke but with some significant differences */
+#define PPC_BOOKE_STD	2
+#define PPC_BOOKE_E500	3	/* bookE with extensions */
+	unsigned is_bookE			: 2;
+	unsigned has_16byte_clne	: 1;
+	unsigned is_60x             : 1;
+	unsigned has_8_bats			: 1;
+	unsigned has_epic           : 1;
+	unsigned has_shadowed_gprs  : 1;
+} ppc_feature_t;
+
+extern ppc_feature_t   current_ppc_features;
+extern ppc_cpu_id_t current_ppc_cpu;
+
+typedef unsigned short ppc_cpu_revision_t;
+
+extern ppc_cpu_id_t get_ppc_cpu_type (void);
+extern const char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu);
+extern ppc_cpu_revision_t get_ppc_cpu_revision (void);
+extern ppc_cpu_revision_t current_ppc_revision;
+
+/* PUBLIC ACCESS ROUTINES */
+#define _PPC_FEAT_DECL(x) \
+static inline unsigned ppc_cpu_##x(void) { \
+  if ( PPC_UNKNOWN == current_ppc_cpu ) \
+    get_ppc_cpu_type(); \
+  return current_ppc_features.x; \
+}
+
+_PPC_FEAT_DECL(has_altivec)
+/* has_fpu not implemented yet */
+_PPC_FEAT_DECL(has_hw_ptbl_lkup)
+_PPC_FEAT_DECL(is_bookE)
+_PPC_FEAT_DECL(is_60x)
+_PPC_FEAT_DECL(has_8_bats)
+_PPC_FEAT_DECL(has_epic)
+_PPC_FEAT_DECL(has_shadowed_gprs)
+
+#undef _PPC_FEAT_DECL
+
+static inline ppc_cpu_id_t ppc_cpu_current(void)
+{
+	return current_ppc_cpu;
+}
+
+static inline bool ppc_cpu_is_e200(void)
+{
+	return (ppc_cpu_current() & 0xff80) == 0x8100;
+}
+
+static inline bool ppc_cpu_is_specific_e200(ppc_cpu_id_t id)
+{
+	return (ppc_cpu_current() & 0xfff0) == id;
+}
+
+static inline bool ppc_cpu_is_e300(void)
+{
+	return ppc_cpu_current() == PPC_e300c1
+		|| ppc_cpu_current() == PPC_e300c2
+		|| ppc_cpu_current() == PPC_e300c3;
+}
+
+static inline bool ppc_cpu_is_e500(void)
+{
+	return ppc_cpu_current() == PPC_8540
+		|| ppc_cpu_current() == PPC_e500v2;
+}
+
+static inline bool ppc_cpu_is(ppc_cpu_id_t cpu)
+{
+	return ppc_cpu_current() == cpu;
+}
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: bsps/powerpc/include/libcpu/e500_mmu.h
===================================================================
--- bsps/powerpc/include/libcpu/e500_mmu.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/e500_mmu.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,230 @@
+#ifndef RTEMS_E500_MMU_DRIVER_H
+#define RTEMS_E500_MMU_DRIVER_H
+
+/*
+ * Routines to manipulate e500 TLBs; TLB0 (fixed 4k page size)
+ * is not very useful so we mostly focus on TLB1 (variable page size)
+ */
+
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ *     Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
+ * 	   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
+
+/* Some routines require or return a index 'key'. This
+ * is simply the TLB entry # ORed with E500_SELTLB_0
+ * or E500_SELTLB_1 specifying an entry in TLB0 or TLB1,
+ * respectively.
+ */
+typedef int rtems_e500_tlb_idx;
+#define E500_SELTLB_0	0x0000
+#define E500_SELTLB_1	0x1000
+
+/* Cache the relevant TLB1 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 va_epn: 20;
+		uint32_t va_tid: 12;
+	}         va;
+	uint32_t rpn;
+	struct {
+		uint32_t     sz:  4;
+		uint32_t     ts:  1;
+		uint32_t      v:  1;
+		uint32_t   perm: 10;
+		uint32_t  wimge:  7;
+	}        att;
+} E500_tlb_va_cache_t;
+
+extern E500_tlb_va_cache_t rtems_e500_tlb_va_cache[16];
+
+/*
+ * Dump (cleartext) content info from cached TLB entries
+ * to a file (stdout if f==NULL).
+ */
+void
+rtems_e500_dmptlbc(FILE *f);
+
+/*
+ * Read a TLB entry from the hardware; if it is a TLB1 entry
+ * then the current settings are stored in the
+ * rtems_e500_tlb_va_cache[] structure.
+ *
+ * The routine can perform this operation quietly or
+ * print information to a file.
+ *
+ *   'key': TLB entry index ORed with selector bit
+ *          (E500_SELTLB_0 for TLB0, E500_SELTLB_1 for TLB1).
+ * '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)
+ */
+int
+rtems_e500_prtlb(rtems_e500_tlb_idx key, int quiet, FILE *f);
+
+/* Initialize cache; verify that TLB0 is unused;
+ *
+ * RETURNS: zero on success, nonzero on error (TLB0
+ *          seems to be in use); in this case the
+ *          driver will refuse to change TLB1 entries
+ *          (other than disabling them).
+ */
+int
+rtems_e500_initlb(void);
+
+/*
+ * Write TLB1 entry (can also be used to disable an entry).
+ *
+ * The routine checks against the cached data in
+ * rtems_e500_tlb_va[] to prevent the user from generating
+ * overlapping entries.
+ *
+ *   'idx': TLB 1 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.
+ *  'attr': Page attributes; ORed combination of WIMGE,
+ *          PERMissions, TID and TS. Use ATTR_xxx macros
+ *
+ * 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 because TLB0 is in use).
+ *         <0: other error
+ *
+ */
+#define E500_TLB_ATTR_WIMGE(x)      ((x)&0x7f)				/* includes user bits */
+#define E500_TLB_ATTR_WIMGE_GET(x)  ((x)&0x7f)
+#define E500_TLB_ATTR_TS            (1<<7)
+#define E500_TLB_ATTR_PERM(x)   	(((x)&0x3ff)<<8)
+#define E500_TLB_ATTR_PERM_GET(x)   (((x)>>8)&0x3ff)
+#define E500_TLB_ATTR_TID(x)        (((x)&0xfff)<<20)
+#define E500_TLB_ATTR_TID_GET(x)    (((x)>>20)&0xfff)
+
+int
+rtems_e500_wrtlb(int idx, uint32_t ea, uint32_t pa, int sz, uint32_t attr);
+
+/*
+ * Check if a ts/tid/ea/sz mapping overlaps
+ * with an existing entry.
+ *
+ * ASSUMPTION: all TLB0 (fixed 4k pages) are invalid and always unused.
+ *
+ * NOTE: 'sz' is the 'logarithmic' size selector; the page size
+ *       is 1024*2^(2*sz).
+ *
+ * RETURNS:
+ *     >= 0: index of TLB1 entry that already provides a mapping
+ *           which overlaps within the ea range.
+ *       -1: SUCCESS (no conflicting entry found)
+ *     <=-2: ERROR (invalid input)
+ */
+int
+rtems_e500_matchtlb(uint32_t ea, uint32_t tid, int ts, int sz);
+
+/* Find TLB index that maps 'ea/as' combination
+ *
+ * RETURNS: index 'key'; i.e., the index number plus
+ *          a bit (E500_SELTLB_1) which indicates whether
+ *          the mapping was found in TLB0 (4k fixed page
+ *          size) or in TLB1 (variable page size).
+ *
+ *          On error (no mapping) -1 is returned.
+ */
+rtems_e500_tlb_idx
+rtems_e500_ftlb(uint32_t ea, int as);
+
+/* Mark TLB entry as invalid ('disabled'). Unlike
+ * rtems_e500_wrtlb() with a negative size argument
+ * this routine also can disable TLB0 entries.
+ *
+ * 'key': TLB entry index ORed with selector bit
+ *        (E500_SELTLB_0 for TLB0, E500_SELTLB_1 for TLB1).
+ *
+ * RETURNS: zero on success, nonzero on error (TLB
+ *          unchanged).
+ *
+ * NOTE:  If a TLB1 entry is disabled the associated
+ *        entry in rtems_e500_va_cache[] is also
+ *        marked as disabled.
+ */
+int
+rtems_e500_clrtlb(rtems_e500_tlb_idx key);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
Index: bsps/powerpc/include/libcpu/io.h
===================================================================
--- bsps/powerpc/include/libcpu/io.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/io.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,139 @@
+/*
+ * io.h
+ *
+ *	    This file contains inline implementation of function to
+ *          deal with IO.
+ *
+ * It is a stripped down version of linux ppc file...
+ *
+ * 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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+#ifndef _LIBCPU_IO_H
+#define _LIBCPU_IO_H
+
+
+#define PREP_ISA_IO_BASE 	0x80000000
+#define PREP_ISA_MEM_BASE 	0xc0000000
+#define PREP_PCI_DRAM_OFFSET 	0x80000000
+
+#define CHRP_ISA_IO_BASE	0xfe000000
+#define CHRP_ISA_MEM_BASE	0xfd000000
+#define CHRP_PCI_DRAM_OFFSET	0x00000000
+
+/* _IO_BASE, _ISA_MEM_BASE, PCI_DRAM_OFFSET are now defined by bsp.h */
+
+#ifndef ASM
+
+#include <bsp.h>		/* for _IO_BASE & friends */
+#include <stdint.h>
+
+/* NOTE: The use of these macros is DISCOURAGED.
+ *       you should consider e.g. using in_xxx / out_xxx
+ *       with a device specific base address that is
+ *       defined by the BSP. This makes drivers easier
+ *       to port.
+ */
+#define inb(port)		in_8((uint8_t *)((port)+_IO_BASE))
+#define outb(val, port)		out_8((uint8_t *)((port)+_IO_BASE), (val))
+#define inw(port)		in_le16((uint16_t *)((port)+_IO_BASE))
+#define outw(val, port)		out_le16((uint16_t *)((port)+_IO_BASE), (val))
+#define inl(port)		in_le32((uint32_t *)((port)+_IO_BASE))
+#define outl(val, port)		out_le32((uint32_t *)((port)+_IO_BASE), (val))
+
+/*
+ * Enforce In-order Execution of I/O:
+ * Acts as a barrier to ensure all previous I/O accesses have
+ * completed before any further ones are issued.
+ */
+static inline void eieio(void)
+{
+	__asm__ __volatile__ ("eieio");
+}
+
+
+/* Enforce in-order execution of data I/O.
+ * No distinction between read/write on PPC; use eieio for all three.
+ */
+#define iobarrier_rw() eieio()
+#define iobarrier_r()  eieio()
+#define iobarrier_w()  eieio()
+
+/*
+ * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
+ */
+static inline uint8_t in_8(const volatile uint8_t *addr)
+{
+	uint8_t ret;
+
+	__asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
+	return ret;
+}
+
+static inline void out_8(volatile uint8_t *addr, uint8_t val)
+{
+	__asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+}
+
+static inline uint16_t in_le16(const volatile uint16_t *addr)
+{
+	uint16_t ret;
+
+	__asm__ __volatile__("lhbrx %0,0,%1; eieio" : "=r" (ret) :
+			      "r" (addr), "m" (*addr));
+	return ret;
+}
+
+static inline uint16_t in_be16(const volatile uint16_t *addr)
+{
+	uint16_t ret;
+
+	__asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
+	return ret;
+}
+
+static inline void out_le16(volatile uint16_t *addr, uint16_t val)
+{
+	__asm__ __volatile__("sthbrx %1,0,%2; eieio" : "=m" (*addr) :
+			      "r" (val), "r" (addr));
+}
+
+static inline void out_be16(volatile uint16_t *addr, uint16_t val)
+{
+	__asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+}
+
+static inline uint32_t in_le32(const volatile uint32_t *addr)
+{
+	uint32_t ret;
+
+	__asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
+			     "r" (addr), "m" (*addr));
+	return ret;
+}
+
+static inline uint32_t in_be32(const volatile uint32_t *addr)
+{
+	uint32_t ret;
+
+	__asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
+	return ret;
+}
+
+static inline void out_le32(volatile uint32_t *addr, uint32_t val)
+{
+	__asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
+			     "r" (val), "r" (addr));
+}
+
+static inline void out_be32(volatile uint32_t *addr, uint32_t val)
+{
+	__asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+}
+
+#endif /* ASM */
+#endif /* _LIBCPU_IO_H */
Index: bsps/powerpc/include/libcpu/irq.h
===================================================================
--- bsps/powerpc/include/libcpu/irq.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/irq.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,199 @@
+/*
+ * irq.h
+ *
+ *  This include file describe the data structure and the functions implemented
+ *  by rtems to write interrupt handlers.
+ *
+ *
+ *  MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ *  Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ *  Derived from libbsp/powerpc/mbx8xx/irq/irq.h:
+ *
+ *  CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ *  This code is heavilly inspired by the public specification of STREAM V2
+ *  that can be found at :
+ *
+ *      <http://www.chorus.com/Documentation/index.html> by following
+ *  the STREAM API Specification Document link.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_IRQ_H
+#define _LIBCPU_IRQ_H
+
+#include <rtems/irq.h>
+
+#define CPU_ASM_IRQ_VECTOR_BASE 0x0
+
+#ifndef ASM
+
+extern volatile unsigned int ppc_cached_irq_mask;
+
+/*
+ * Symblolic IRQ names and related definitions.
+ */
+
+  /*
+   * Base vector for our USIU IRQ handlers.
+   */
+#define CPU_USIU_VECTOR_BASE	(CPU_ASM_IRQ_VECTOR_BASE)
+  /*
+   * USIU IRQ handler related definitions
+   */
+#define CPU_USIU_IRQ_COUNT    	(16) /* 16 reserved but in the future... */
+#define CPU_USIU_IRQ_MIN_OFFSET	(0)
+#define CPU_USIU_IRQ_MAX_OFFSET	(CPU_USIU_IRQ_MIN_OFFSET + CPU_USIU_IRQ_COUNT - 1)
+  /*
+   * UIMB IRQ handlers related definitions
+   */
+#define CPU_UIMB_IRQ_COUNT	(32 - 8) /* first 8 overlap USIU */
+#define CPU_UIMB_IRQ_MIN_OFFSET	(CPU_USIU_IRQ_COUNT + CPU_USIU_VECTOR_BASE)
+#define CPU_UIMB_IRQ_MAX_OFFSET	(CPU_UIMB_IRQ_MIN_OFFSET + CPU_UIMB_IRQ_COUNT - 1)
+  /*
+   * PowerPc exceptions handled as interrupt where a rtems managed interrupt
+   * handler might be connected
+   */
+#define CPU_PROC_IRQ_COUNT	(1)
+#define CPU_PROC_IRQ_MIN_OFFSET	(CPU_UIMB_IRQ_MAX_OFFSET + 1)
+#define CPU_PROC_IRQ_MAX_OFFSET	(CPU_PROC_IRQ_MIN_OFFSET + CPU_PROC_IRQ_COUNT - 1)
+  /*
+   * Summary
+   */
+#define CPU_IRQ_COUNT		(CPU_PROC_IRQ_MAX_OFFSET + 1)
+#define CPU_MIN_OFFSET		(CPU_USIU_IRQ_MIN_OFFSET)
+#define CPU_MAX_OFFSET		(CPU_PROC_IRQ_MAX_OFFSET)
+  /*
+   * USIU IRQ symbolic name definitions.
+   */
+#define CPU_USIU_EXT_IRQ_0      (CPU_USIU_IRQ_MIN_OFFSET + 0)
+#define CPU_USIU_INT_IRQ_0      (CPU_USIU_IRQ_MIN_OFFSET + 1)
+
+#define CPU_USIU_EXT_IRQ_1      (CPU_USIU_IRQ_MIN_OFFSET + 2)
+#define CPU_USIU_INT_IRQ_1      (CPU_USIU_IRQ_MIN_OFFSET + 3)
+
+#define CPU_USIU_EXT_IRQ_2      (CPU_USIU_IRQ_MIN_OFFSET + 4)
+#define CPU_USIU_INT_IRQ_2      (CPU_USIU_IRQ_MIN_OFFSET + 5)
+
+#define CPU_USIU_EXT_IRQ_3      (CPU_USIU_IRQ_MIN_OFFSET + 6)
+#define CPU_USIU_INT_IRQ_3      (CPU_USIU_IRQ_MIN_OFFSET + 7)
+
+#define CPU_USIU_EXT_IRQ_4      (CPU_USIU_IRQ_MIN_OFFSET + 8)
+#define CPU_USIU_INT_IRQ_4      (CPU_USIU_IRQ_MIN_OFFSET + 9)
+
+#define CPU_USIU_EXT_IRQ_5      (CPU_USIU_IRQ_MIN_OFFSET + 10)
+#define CPU_USIU_INT_IRQ_5      (CPU_USIU_IRQ_MIN_OFFSET + 11)
+
+#define CPU_USIU_EXT_IRQ_6      (CPU_USIU_IRQ_MIN_OFFSET + 12)
+#define CPU_USIU_INT_IRQ_6      (CPU_USIU_IRQ_MIN_OFFSET + 13)
+
+#define CPU_USIU_EXT_IRQ_7      (CPU_USIU_IRQ_MIN_OFFSET + 14)
+#define CPU_USIU_INT_IRQ_7      (CPU_USIU_IRQ_MIN_OFFSET + 15)
+
+  /*
+   * Symbolic names for UISU interrupt sources.
+   */
+#define CPU_PERIODIC_TIMER	(CPU_USIU_INT_IRQ_6)
+#define CPU_UIMB_INTERRUPT	(CPU_USIU_INT_IRQ_7)
+
+  /*
+   * UIMB IRQ symbolic name definitions.  The first 8 sources are aliases to
+   * the USIU interrupts of the same number, because they are detected in
+   * the USIU pending register rather than the UIMB pending register.
+   */
+#define CPU_UIMB_IRQ_0 		(CPU_USIU_INT_IRQ_0)
+#define CPU_UIMB_IRQ_1 		(CPU_USIU_INT_IRQ_1)
+#define CPU_UIMB_IRQ_2 		(CPU_USIU_INT_IRQ_2)
+#define CPU_UIMB_IRQ_3 		(CPU_USIU_INT_IRQ_3)
+#define CPU_UIMB_IRQ_4 		(CPU_USIU_INT_IRQ_4)
+#define CPU_UIMB_IRQ_5 		(CPU_USIU_INT_IRQ_5)
+#define CPU_UIMB_IRQ_6 		(CPU_USIU_INT_IRQ_6)
+#define CPU_UIMB_IRQ_7 		(CPU_USIU_INT_IRQ_7)
+
+#define CPU_UIMB_IRQ_8         	(CPU_UIMB_IRQ_MIN_OFFSET+ 0)
+#define CPU_UIMB_IRQ_9          (CPU_UIMB_IRQ_MIN_OFFSET+ 1)
+#define CPU_UIMB_IRQ_10         (CPU_UIMB_IRQ_MIN_OFFSET+ 2)
+#define CPU_UIMB_IRQ_11         (CPU_UIMB_IRQ_MIN_OFFSET+ 3)
+#define CPU_UIMB_IRQ_12         (CPU_UIMB_IRQ_MIN_OFFSET+ 4)
+#define CPU_UIMB_IRQ_13         (CPU_UIMB_IRQ_MIN_OFFSET+ 5)
+#define CPU_UIMB_IRQ_14         (CPU_UIMB_IRQ_MIN_OFFSET+ 6)
+#define CPU_UIMB_IRQ_15         (CPU_UIMB_IRQ_MIN_OFFSET+ 7)
+#define CPU_UIMB_IRQ_16         (CPU_UIMB_IRQ_MIN_OFFSET+ 8)
+#define CPU_UIMB_IRQ_17         (CPU_UIMB_IRQ_MIN_OFFSET+ 9)
+#define CPU_UIMB_IRQ_18         (CPU_UIMB_IRQ_MIN_OFFSET+ 0)
+#define CPU_UIMB_IRQ_19         (CPU_UIMB_IRQ_MIN_OFFSET+11)
+#define CPU_UIMB_IRQ_20         (CPU_UIMB_IRQ_MIN_OFFSET+12)
+#define CPU_UIMB_IRQ_21         (CPU_UIMB_IRQ_MIN_OFFSET+13)
+#define CPU_UIMB_IRQ_22         (CPU_UIMB_IRQ_MIN_OFFSET+14)
+#define CPU_UIMB_IRQ_23         (CPU_UIMB_IRQ_MIN_OFFSET+15)
+#define CPU_UIMB_IRQ_24         (CPU_UIMB_IRQ_MIN_OFFSET+16)
+#define CPU_UIMB_IRQ_25         (CPU_UIMB_IRQ_MIN_OFFSET+17)
+#define CPU_UIMB_IRQ_26         (CPU_UIMB_IRQ_MIN_OFFSET+18)
+#define CPU_UIMB_IRQ_27         (CPU_UIMB_IRQ_MIN_OFFSET+19)
+#define CPU_UIMB_IRQ_28         (CPU_UIMB_IRQ_MIN_OFFSET+20)
+#define CPU_UIMB_IRQ_29         (CPU_UIMB_IRQ_MIN_OFFSET+21)
+#define CPU_UIMB_IRQ_30         (CPU_UIMB_IRQ_MIN_OFFSET+22)
+#define CPU_UIMB_IRQ_31         (CPU_UIMB_IRQ_MIN_OFFSET+23)
+
+  /*
+   * Symbolic names for UIMB interrupt sources.
+   */
+#define CPU_IRQ_SCI		(CPU_UIMB_IRQ_5)
+
+  /*
+   * Processor exceptions handled as rtems IRQ symbolic name definitions.
+   */
+#define CPU_DECREMENTER		(CPU_PROC_IRQ_MIN_OFFSET)
+
+/*
+ * Convert an rtems_irq_number constant to an interrupt level
+ * suitable for programming into an I/O device's interrupt level field.
+ */
+int CPU_irq_level_from_symbolic_name(const rtems_irq_number name);
+
+/*-------------------------------------------------------------------------+
+| Function Prototypes.
++--------------------------------------------------------------------------*/
+
+extern void CPU_rtems_irq_mng_init(unsigned cpuId);
+
+typedef struct MPC5XX_Interrupt_frame {
+    uint32_t   stacklink;	/* Ensure this is a real frame (also reg1 save) */
+    uint32_t   calleeLr;	/* link register used by callees: SVR4/EABI */
+
+    /* This is what is left out of the primary contexts */
+    uint32_t   gpr0;
+    uint32_t   gpr2;		/* play safe */
+    uint32_t   gpr3;
+    uint32_t   gpr4;
+    uint32_t   gpr5;
+    uint32_t   gpr6;
+    uint32_t   gpr7;
+    uint32_t   gpr8;
+    uint32_t   gpr9;
+    uint32_t   gpr10;
+    uint32_t   gpr11;
+    uint32_t   gpr12;
+    uint32_t   gpr13;   /* Play safe */
+    uint32_t   gpr28;   /* For internal use by the IRQ handler */
+    uint32_t   gpr29;   /* For internal use by the IRQ handler */
+    uint32_t   gpr30;   /* For internal use by the IRQ handler */
+    uint32_t   gpr31;   /* For internal use by the IRQ handler */
+    uint32_t   cr;	/* Bits of this are volatile, so no-one may save */
+    uint32_t   ctr;
+    uint32_t   xer;
+    uint32_t   lr;
+    uint32_t   pc;
+    uint32_t   msr;
+    uint32_t   pad[3];
+} MPC5XX_Interrupt_frame;
+
+void C_dispatch_irq_handler(MPC5XX_Interrupt_frame *frame, unsigned int excNum);
+
+#endif
+
+#endif
Index: bsps/powerpc/include/libcpu/mmu.h
===================================================================
--- bsps/powerpc/include/libcpu/mmu.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/mmu.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,304 @@
+/*
+ * mmu.h
+ *
+ *	PowerPC memory management structures
+ *
+ * It is a stripped down version of linux ppc file...
+ *
+ * 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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_MMU_H
+#define _LIBCPU_MMU_H
+
+#ifndef ASM
+/* Hardware Page Table Entry */
+typedef struct _PTE {
+	unsigned long v:1;	/* Entry is valid */
+	unsigned long vsid:24;	/* Virtual segment identifier */
+	unsigned long h:1;	/* Hash algorithm indicator */
+	unsigned long api:6;	/* Abbreviated page index */
+	unsigned long rpn:20;	/* Real (physical) page number */
+	unsigned long    :3;	/* Unused */
+	unsigned long r:1;	/* Referenced */
+	unsigned long c:1;	/* Changed */
+	unsigned long w:1;	/* Write-thru cache mode */
+	unsigned long i:1;	/* Cache inhibited */
+	unsigned long m:1;	/* Memory coherence */
+	unsigned long g:1;	/* Guarded */
+	unsigned long  :1;	/* Unused */
+	unsigned long pp:2;	/* Page protection */
+} PTE;
+
+/* Values for PP (assumes Ks=0, Kp=1) */
+#define PP_RWXX	0	/* Supervisor read/write, User none */
+#define PP_RWRX 1	/* Supervisor read/write, User read */
+#define PP_RWRW 2	/* Supervisor read/write, User read/write */
+#define PP_RXRX 3	/* Supervisor read,       User read */
+
+/* Segment Register */
+typedef struct _SEGREG {
+	unsigned long t:1;	/* Normal or I/O  type */
+	unsigned long ks:1;	/* Supervisor 'key' (normally 0) */
+	unsigned long kp:1;	/* User 'key' (normally 1) */
+	unsigned long n:1;	/* No-execute */
+	unsigned long :4;	/* Unused */
+	unsigned long vsid:24;	/* Virtual Segment Identifier */
+} SEGREG;
+
+/* Block Address Translation (BAT) Registers */
+typedef struct _P601_BATU {	/* Upper part of BAT for 601 processor */
+	unsigned long bepi:15;	/* Effective page index (virtual address) */
+	unsigned long :8;	/* unused */
+	unsigned long w:1;
+	unsigned long i:1;	/* Cache inhibit */
+	unsigned long m:1;	/* Memory coherence */
+	unsigned long ks:1;	/* Supervisor key (normally 0) */
+	unsigned long kp:1;	/* User key (normally 1) */
+	unsigned long pp:2;	/* Page access protections */
+} P601_BATU;
+
+typedef struct _BATU {		/* Upper part of BAT (all except 601) */
+	unsigned long bepi:15;	/* Effective page index (virtual address) */
+	unsigned long :4;	/* Unused */
+	unsigned long bl:11;	/* Block size mask */
+	unsigned long vs:1;	/* Supervisor valid */
+	unsigned long vp:1;	/* User valid */
+} BATU;
+
+typedef struct _P601_BATL {	/* Lower part of BAT for 601 processor */
+	unsigned long brpn:15;	/* Real page index (physical address) */
+	unsigned long :10;	/* Unused */
+	unsigned long v:1;	/* Valid bit */
+	unsigned long bl:6;	/* Block size mask */
+} P601_BATL;
+
+typedef struct _BATL {		/* Lower part of BAT (all except 601) */
+	unsigned long brpn:15;	/* Real page index (physical address) */
+	unsigned long :10;	/* Unused */
+	unsigned long w:1;	/* Write-thru cache */
+	unsigned long i:1;	/* Cache inhibit */
+	unsigned long m:1;	/* Memory coherence */
+	unsigned long g:1;	/* Guarded (MBZ in IBAT) */
+	unsigned long :1;	/* Unused */
+	unsigned long pp:2;	/* Page access protections */
+} BATL;
+
+typedef struct _BAT {
+	BATU batu;		/* Upper register */
+	BATL batl;		/* Lower register */
+} BAT;
+
+typedef struct _P601_BAT {
+	P601_BATU batu;		/* Upper register */
+	P601_BATL batl;		/* Lower register */
+} P601_BAT;
+
+/* Block size masks */
+#define BL_128K	0x000
+#define BL_256K 0x001
+#define BL_512K 0x003
+#define BL_1M   0x007
+#define BL_2M   0x00F
+#define BL_4M   0x01F
+#define BL_8M   0x03F
+#define BL_16M  0x07F
+#define BL_32M  0x0FF
+#define BL_64M  0x1FF
+#define BL_128M 0x3FF
+#define BL_256M 0x7FF
+
+/* BAT Access Protection */
+#define BPP_XX	0x00		/* No access */
+#define BPP_RX	0x01		/* Read only */
+#define BPP_RW	0x02		/* Read/write */
+
+/*
+ * Simulated two-level MMU.  This structure is used by the kernel
+ * to keep track of MMU mappings and is used to update/maintain
+ * the hardware HASH table which is really a cache of mappings.
+ *
+ * The simulated structures mimic the hardware available on other
+ * platforms, notably the 80x86 and 680x0.
+ */
+
+typedef struct _pte {
+   	unsigned long page_num:20;
+   	unsigned long flags:12;		/* Page flags (some unused bits) */
+} pte;
+
+#define PD_SHIFT (10+12)		/* Page directory */
+#define PD_MASK  0x03FF
+#define PT_SHIFT (12)			/* Page Table */
+#define PT_MASK  0x03FF
+#define PG_SHIFT (12)			/* Page Entry */
+
+
+/* MMU context */
+
+typedef struct _MMU_context {
+	SEGREG	segs[16];	/* Segment registers */
+	pte	**pmap;		/* Two-level page-map structure */
+} MMU_context;
+
+/* Used to set up SDR1 register */
+#define HASH_TABLE_SIZE_64K	0x00010000
+#define HASH_TABLE_SIZE_128K	0x00020000
+#define HASH_TABLE_SIZE_256K	0x00040000
+#define HASH_TABLE_SIZE_512K	0x00080000
+#define HASH_TABLE_SIZE_1M	0x00100000
+#define HASH_TABLE_SIZE_2M	0x00200000
+#define HASH_TABLE_SIZE_4M	0x00400000
+#define HASH_TABLE_MASK_64K	0x000
+#define HASH_TABLE_MASK_128K	0x001
+#define HASH_TABLE_MASK_256K	0x003
+#define HASH_TABLE_MASK_512K	0x007
+#define HASH_TABLE_MASK_1M	0x00F
+#define HASH_TABLE_MASK_2M	0x01F
+#define HASH_TABLE_MASK_4M	0x03F
+
+/* invalidate a TLB entry */
+static inline void _tlbie(unsigned long va)
+{
+	asm volatile ("tlbie %0" : : "r"(va));
+}
+
+extern void _tlbia(void);		/* invalidate all TLB entries */
+#endif /* ASM */
+
+/* Control/status registers for the MPC8xx.
+ * A write operation to these registers causes serialized access.
+ * During software tablewalk, the registers used perform mask/shift-add
+ * operations when written/read.  A TLB entry is created when the Mx_RPN
+ * is written, and the contents of several registers are used to
+ * create the entry.
+ */
+#define MI_CTR		784	/* Instruction TLB control register */
+#define MI_GPM		0x80000000	/* Set domain manager mode */
+#define MI_PPM		0x40000000	/* Set subpage protection */
+#define MI_CIDEF	0x20000000	/* Set cache inhibit when MMU dis */
+#define MI_RSV4I	0x08000000	/* Reserve 4 TLB entries */
+#define MI_PPCS		0x02000000	/* Use MI_RPN prob/priv state */
+#define MI_IDXMASK	0x00001f00	/* TLB index to be loaded */
+#define MI_RESETVAL	0x00000000	/* Value of register at reset */
+
+/* These are the Ks and Kp from the PowerPC books.  For proper operation,
+ * Ks = 0, Kp = 1.
+ */
+#define MI_AP		786
+#define MI_Ks		0x80000000	/* Should not be set */
+#define MI_Kp		0x40000000	/* Should always be set */
+
+/* The effective page number register.  When read, contains the information
+ * about the last instruction TLB miss.  When MI_RPN is written, bits in
+ * this register are used to create the TLB entry.
+ */
+#define MI_EPN		787
+#define MI_EPNMASK	0xfffff000	/* Effective page number for entry */
+#define MI_EVALID	0x00000200	/* Entry is valid */
+#define MI_ASIDMASK	0x0000000f	/* ASID match value */
+					/* Reset value is undefined */
+
+/* A "level 1" or "segment" or whatever you want to call it register.
+ * For the instruction TLB, it contains bits that get loaded into the
+ * TLB entry when the MI_RPN is written.
+ */
+#define MI_TWC		789
+#define MI_APG		0x000001e0	/* Access protection group (0) */
+#define MI_GUARDED	0x00000010	/* Guarded storage */
+#define MI_PSMASK	0x0000000c	/* Mask of page size bits */
+#define MI_PS8MEG	0x0000000c	/* 8M page size */
+#define MI_PS512K	0x00000004	/* 512K page size */
+#define MI_PS4K_16K	0x00000000	/* 4K or 16K page size */
+#define MI_SVALID	0x00000001	/* Segment entry is valid */
+					/* Reset value is undefined */
+
+/* Real page number.  Defined by the pte.  Writing this register
+ * causes a TLB entry to be created for the instruction TLB, using
+ * additional information from the MI_EPN, and MI_TWC registers.
+ */
+#define MI_RPN		790
+
+/* Define an RPN value for mapping kernel memory to large virtual
+ * pages for boot initialization.  This has real page number of 0,
+ * large page size, shared page, cache enabled, and valid.
+ * Also mark all subpages valid and write access.
+ */
+#define MI_BOOTINIT	0x000001fd
+
+#define MD_CTR		792	/* Data TLB control register */
+#define MD_GPM		0x80000000	/* Set domain manager mode */
+#define MD_PPM		0x40000000	/* Set subpage protection */
+#define MD_CIDEF	0x20000000	/* Set cache inhibit when MMU dis */
+#define MD_WTDEF	0x10000000	/* Set writethrough when MMU dis */
+#define MD_RSV4I	0x08000000	/* Reserve 4 TLB entries */
+#define MD_TWAM		0x04000000	/* Use 4K page hardware assist */
+#define MD_PPCS		0x02000000	/* Use MI_RPN prob/priv state */
+#define MD_IDXMASK	0x00001f00	/* TLB index to be loaded */
+#define MD_RESETVAL	0x04000000	/* Value of register at reset */
+
+#define M_CASID		793	/* Address space ID (context) to match */
+#define MC_ASIDMASK	0x0000000f	/* Bits used for ASID value */
+
+
+/* These are the Ks and Kp from the PowerPC books.  For proper operation,
+ * Ks = 0, Kp = 1.
+ */
+#define MD_AP		794
+#define MD_Ks		0x80000000	/* Should not be set */
+#define MD_Kp		0x40000000	/* Should always be set */
+
+/* The effective page number register.  When read, contains the information
+ * about the last instruction TLB miss.  When MD_RPN is written, bits in
+ * this register are used to create the TLB entry.
+ */
+#define MD_EPN		795
+#define MD_EPNMASK	0xfffff000	/* Effective page number for entry */
+#define MD_EVALID	0x00000200	/* Entry is valid */
+#define MD_ASIDMASK	0x0000000f	/* ASID match value */
+					/* Reset value is undefined */
+
+/* The pointer to the base address of the first level page table.
+ * During a software tablewalk, reading this register provides the address
+ * of the entry associated with MD_EPN.
+ */
+#define M_TWB		796
+#define	M_L1TB		0xfffff000	/* Level 1 table base address */
+#define M_L1INDX	0x00000ffc	/* Level 1 index, when read */
+					/* Reset value is undefined */
+
+/* A "level 1" or "segment" or whatever you want to call it register.
+ * For the data TLB, it contains bits that get loaded into the TLB entry
+ * when the MD_RPN is written.  It is also provides the hardware assist
+ * for finding the PTE address during software tablewalk.
+ */
+#define MD_TWC		797
+#define MD_L2TB		0xfffff000	/* Level 2 table base address */
+#define MD_L2INDX	0xfffffe00	/* Level 2 index (*pte), when read */
+#define MD_APG		0x000001e0	/* Access protection group (0) */
+#define MD_GUARDED	0x00000010	/* Guarded storage */
+#define MD_PSMASK	0x0000000c	/* Mask of page size bits */
+#define MD_PS8MEG	0x0000000c	/* 8M page size */
+#define MD_PS512K	0x00000004	/* 512K page size */
+#define MD_PS4K_16K	0x00000000	/* 4K or 16K page size */
+#define MD_WT		0x00000002	/* Use writethrough page attribute */
+#define MD_SVALID	0x00000001	/* Segment entry is valid */
+					/* Reset value is undefined */
+
+
+/* Real page number.  Defined by the pte.  Writing this register
+ * causes a TLB entry to be created for the data TLB, using
+ * additional information from the MD_EPN, and MD_TWC registers.
+ */
+#define MD_RPN		798
+
+/* This is a temporary storage register that could be used to save
+ * a processor working register during a tablewalk.
+ */
+#define M_TW		799
+#endif /* _LIBCPU_MMU_H */
Index: bsps/powerpc/include/libcpu/page.h
===================================================================
--- bsps/powerpc/include/libcpu/page.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/page.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,66 @@
+/*
+ * page.h
+ *
+ *	PowerPC memory management structures
+ *
+ * It is a stripped down version of linux ppc file...
+ *
+ * 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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_PAGE_H
+#define _LIBCPU_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#define PAGE_OFFSET	0xc0000000
+
+
+#ifndef ASM
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)	(x)
+#define pmd_val(x)	(x)
+#define pgd_val(x)	(x)
+#define pgprot_val(x)	(x)
+
+#define __pte(x)	(x)
+#define __pmd(x)	(x)
+#define __pgd(x)	(x)
+#define __pgprot(x)	(x)
+
+
+/* align addr on a size boundry - adjust address up if needed -- Cort */
+#define _ALIGN(addr,size)	(((addr)+size-1)&(~(size-1)))
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+
+#define clear_page(page)        memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+/* map phys->virtual and virtual->phys for RAM pages */
+
+#define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
+#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+
+#define MAP_NR(addr)		(((unsigned long)addr-PAGE_OFFSET) >> PAGE_SHIFT)
+#define MAP_PAGE_RESERVED	(1<<15)
+
+extern unsigned long get_zero_page_fast(void);
+#endif /* ASM */
+#endif /* _LIBCPU_PAGE_H */
Index: bsps/powerpc/include/libcpu/pgtable.h
===================================================================
--- bsps/powerpc/include/libcpu/pgtable.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/pgtable.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,144 @@
+/*
+ * pgtable.h
+ *
+ *	PowerPC memory management structures
+ *
+ * It is a stripped down version of linux ppc file...
+ *
+ * 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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_PGTABLE_H
+#define _LIBCPU_PGTABLE_H
+
+/*
+ * The PowerPC MMU uses a hash table containing PTEs, together with
+ * a set of 16 segment registers (on 32-bit implementations), to define
+ * the virtual to physical address mapping.
+ *
+ * We use the hash table as an extended TLB, i.e. a cache of currently
+ * active mappings.  We maintain a two-level page table tree, much like
+ * that used by the i386, for the sake of the Linux memory management code.
+ * Low-level assembler code in head.S (procedure hash_page) is responsible
+ * for extracting ptes from the tree and putting them into the hash table
+ * when necessary, and updating the accessed and modified bits in the
+ * page table tree.
+ *
+ * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
+ * We also use the two level tables, but we can put the real bits in them
+ * needed for the TLB and tablewalk.  These definitions require Mx_CTR.PPM = 0,
+ * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1.  The level 2 descriptor has
+ * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
+ * based upon user/super access.  The TLB does not have accessed nor write
+ * protect.  We assume that if the TLB get loaded with an entry it is
+ * accessed, and overload the changed bit for write protect.  We use
+ * two bits in the software pte that are supposed to be set to zero in
+ * the TLB entry (24 and 25) for these indicators.  Although the level 1
+ * descriptor contains the guarded and writethrough/copyback bits, we can
+ * set these at the page level since they get copied from the Mx_TWC
+ * register when the TLB entry is loaded.  We will use bit 27 for guard, since
+ * that is where it exists in the MD_TWC, and bit 26 for writethrough.
+ * These will get masked from the level 2 descriptor at TLB load time, and
+ * copied to the MD_TWC before it gets loaded.
+ */
+
+/* PMD_SHIFT determines the size of the area mapped by the second-level page tables */
+#define PMD_SHIFT	22
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT	22
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: our page-table tree is two-level, so
+ * we don't really have any PMD directory.
+ */
+#define PTRS_PER_PTE	1024
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PGD	1024
+#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
+
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 64MB value just means that there will be a 64MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ *
+ * We no longer map larger than phys RAM with the BATs so we don't have
+ * to worry about the VMALLOC_OFFSET causing problems.  We do have to worry
+ * about clashes between our early calls to ioremap() that start growing down
+ * from ioremap_base being run into the VM area allocations (growing upwards
+ * from VMALLOC_START).  For this reason we have ioremap_bot to check when
+ * we actually run into our mappings setup in the early boot with the VM
+ * system.  This really does become a problem for machines with good amounts
+ * of RAM.  -- Cort
+ */
+#define VMALLOC_OFFSET (0x4000000) /* 64M */
+#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END	ioremap_bot
+
+/*
+ * Bits in a linux-style PTE.  These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible.
+ */
+#define _PAGE_PRESENT	0x001	/* software: pte contains a translation */
+#define _PAGE_USER	0x002	/* matches one of the PP bits */
+#define _PAGE_RW	0x004	/* software: user write access allowed */
+#define _PAGE_GUARDED	0x008
+#define _PAGE_COHERENT	0x010	/* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE	0x020	/* I: cache inhibit */
+#define _PAGE_WRITETHRU	0x040	/* W: cache write-through */
+#define _PAGE_DIRTY	0x080	/* C: page changed */
+#define _PAGE_ACCESSED	0x100	/* R: page referenced */
+#define _PAGE_HWWRITE	0x200	/* software: _PAGE_RW & _PAGE_DIRTY */
+#define _PAGE_SHARED	0
+
+#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define _PAGE_BASE	_PAGE_PRESENT | _PAGE_ACCESSED
+#define _PAGE_WRENABLE	_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE
+
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+
+#define PAGE_SHARED	__pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | \
+				 _PAGE_SHARED)
+#define PAGE_COPY	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_KERNEL	__pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_SHARED)
+#define PAGE_KERNEL_CI	__pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_SHARED | \
+				 _PAGE_NO_CACHE )
+
+/*
+ * The PowerPC can only do execute protection on a segment (256MB) basis,
+ * not on a page basis.  So we consider execute permission the same as read.
+ * Also, write permissions imply read permissions.
+ * This is the closest we can get..
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+#endif /* _LIBCPU_PGTABLE_H */
Index: bsps/powerpc/include/libcpu/powerpc-utility.h
===================================================================
--- bsps/powerpc/include/libcpu/powerpc-utility.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/powerpc-utility.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,985 @@
+/**
+ * @file
+ *
+ * @ingroup powerpc_shared
+ *
+ * @brief General purpose assembler macros, linker command file support and
+ * some inline functions for direct register access.
+ */
+
+/*
+ * Copyright (c) 2008-2015 embedded brains GmbH.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * access function for Device Control Registers inspired by "ppc405common.h"
+ * from Michael Hamel ADInstruments May 2008
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+/**
+ * @defgroup powerpc_shared Shared PowerPC Code
+ */
+
+#ifndef __LIBCPU_POWERPC_UTILITY_H
+#define __LIBCPU_POWERPC_UTILITY_H
+
+#if !defined(ASM)
+  #include <rtems.h>
+#endif
+
+#include <rtems/score/cpu.h>
+#include <rtems/powerpc/registers.h>
+#include <rtems/powerpc/powerpc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(ASM)
+
+#include <rtems/bspIo.h>
+#include <rtems/system.h>
+
+#include <libcpu/cpuIdent.h>
+
+#define LINKER_SYMBOL(sym) extern char sym [];
+
+/**
+ * @brief Read one byte from @a src.
+ */
+static inline uint8_t ppc_read_byte(const volatile void *src)
+{
+  uint8_t value;
+
+  __asm__ volatile (
+    "lbz %0, 0(%1)"
+    : "=r" (value)
+    : "b" (src)
+  );
+
+  return value;
+}
+
+/**
+ * @brief Read one half word from @a src.
+ */
+static inline uint16_t ppc_read_half_word(const volatile void *src)
+{
+  uint16_t value;
+
+  __asm__ volatile (
+    "lhz %0, 0(%1)"
+    : "=r" (value)
+    : "b" (src)
+  );
+
+  return value;
+}
+
+/**
+ * @brief Read one word from @a src.
+ */
+static inline uint32_t ppc_read_word(const volatile void *src)
+{
+  uint32_t value;
+
+  __asm__ volatile (
+    "lwz %0, 0(%1)"
+    : "=r" (value)
+    : "b" (src)
+  );
+
+  return value;
+}
+
+/**
+ * @brief Write one byte @a value to @a dest.
+ */
+static inline void ppc_write_byte(uint8_t value, volatile void *dest)
+{
+  __asm__ volatile (
+    "stb %0, 0(%1)"
+    :
+    : "r" (value), "b" (dest)
+  );
+}
+
+/**
+ * @brief Write one half word @a value to @a dest.
+ */
+static inline void ppc_write_half_word(uint16_t value, volatile void *dest)
+{
+  __asm__ volatile (
+    "sth %0, 0(%1)"
+    :
+    : "r" (value), "b" (dest)
+  );
+}
+
+/**
+ * @brief Write one word @a value to @a dest.
+ */
+static inline void ppc_write_word(uint32_t value, volatile void *dest)
+{
+  __asm__ volatile (
+    "stw %0, 0(%1)" :
+    : "r" (value), "b" (dest)
+  );
+}
+
+
+static inline void *ppc_stack_pointer(void)
+{
+  void *sp;
+
+  __asm__ volatile (
+    "mr %0, 1"
+    : "=r" (sp)
+  );
+
+  return sp;
+}
+
+static inline void ppc_set_stack_pointer(void *sp)
+{
+  __asm__ volatile (
+    "mr 1, %0"
+    :
+    : "r" (sp)
+  );
+}
+
+static inline void *ppc_link_register(void)
+{
+  void *lr;
+
+  __asm__ volatile (
+    "mflr %0"
+    : "=r" (lr)
+  );
+
+  return lr;
+}
+
+static inline void ppc_set_link_register(void *lr)
+{
+  __asm__ volatile (
+    "mtlr %0"
+    :
+    : "r" (lr)
+  );
+}
+
+static inline uint32_t ppc_machine_state_register(void)
+{
+  uint32_t msr;
+
+  __asm__ volatile (
+    "mfmsr %0"
+    : "=r" (msr)
+  );
+
+  return msr;
+}
+
+static inline void ppc_set_machine_state_register(uint32_t msr)
+{
+  __asm__ volatile (
+    "mtmsr %0"
+    :
+    : "r" (msr)
+  );
+}
+
+static inline void ppc_synchronize_data(void)
+{
+  RTEMS_COMPILER_MEMORY_BARRIER();
+
+  __asm__ volatile ("sync");
+}
+
+static inline void ppc_light_weight_synchronize(void)
+{
+  RTEMS_COMPILER_MEMORY_BARRIER();
+
+  __asm__ volatile ("lwsync");
+}
+
+static inline void ppc_synchronize_instructions(void)
+{
+  RTEMS_COMPILER_MEMORY_BARRIER();
+
+  __asm__ volatile ("isync");
+}
+
+static inline void ppc_enforce_in_order_execution_of_io(void)
+{
+  RTEMS_COMPILER_MEMORY_BARRIER();
+
+  __asm__ volatile ("eieio");
+}
+
+static inline void ppc_data_cache_block_flush(void *addr)
+{
+  __asm__ volatile (
+    "dcbf 0, %0"
+    :
+    : "r" (addr)
+    : "memory"
+  );
+}
+
+static inline void ppc_data_cache_block_flush_2(
+  void *base,
+  uintptr_t offset
+)
+{
+  __asm__ volatile (
+    "dcbf %0, %1"
+    :
+    : "b" (base), "r" (offset)
+    : "memory"
+  );
+}
+
+static inline void ppc_data_cache_block_invalidate(void *addr)
+{
+  __asm__ volatile (
+    "dcbi 0, %0"
+    :
+    : "r" (addr)
+    : "memory"
+  );
+}
+
+static inline void ppc_data_cache_block_invalidate_2(
+  void *base,
+  uintptr_t offset
+)
+{
+  __asm__ volatile (
+    "dcbi %0, %1"
+    :
+    : "b" (base), "r" (offset)
+    : "memory"
+  );
+}
+
+static inline void ppc_data_cache_block_store(const void *addr)
+{
+  __asm__ volatile (
+    "dcbst 0, %0"
+    :
+    : "r" (addr)
+  );
+}
+
+static inline void ppc_data_cache_block_store_2(
+  const void *base,
+  uintptr_t offset
+)
+{
+  __asm__ volatile (
+    "dcbst %0, %1"
+    :
+    : "b" (base), "r" (offset)
+  );
+}
+
+static inline void ppc_data_cache_block_touch(const void *addr)
+{
+  __asm__ volatile (
+    "dcbt 0, %0"
+    :
+    : "r" (addr)
+  );
+}
+
+static inline void ppc_data_cache_block_touch_2(
+  const void *base,
+  uintptr_t offset
+)
+{
+  __asm__ volatile (
+    "dcbt %0, %1"
+    :
+    : "b" (base), "r" (offset)
+  );
+}
+
+static inline void ppc_data_cache_block_touch_for_store(const void *addr)
+{
+  __asm__ volatile (
+    "dcbtst 0, %0"
+    :
+    : "r" (addr)
+  );
+}
+
+static inline void ppc_data_cache_block_touch_for_store_2(
+  const void *base,
+  uintptr_t offset
+)
+{
+  __asm__ volatile (
+    "dcbtst %0, %1"
+    :
+    : "b" (base), "r" (offset)
+  );
+}
+
+static inline void ppc_data_cache_block_clear_to_zero(void *addr)
+{
+  __asm__ volatile (
+    "dcbz 0, %0"
+    :
+    : "r" (addr)
+    : "memory"
+  );
+}
+
+static inline void ppc_data_cache_block_clear_to_zero_2(
+  void *base,
+  uintptr_t offset
+)
+{
+  __asm__ volatile (
+    "dcbz %0, %1"
+    :
+    : "b" (base), "r" (offset)
+    : "memory"
+  );
+}
+
+static inline void ppc_instruction_cache_block_invalidate(void *addr)
+{
+  __asm__ volatile (
+    "icbi 0, %0"
+    :
+    : "r" (addr)
+  );
+}
+
+static inline void ppc_instruction_cache_block_invalidate_2(
+  void *base,
+  uintptr_t offset
+)
+{
+  __asm__ volatile (
+    "icbi %0, %1"
+    :
+    : "b" (base), "r" (offset)
+  );
+}
+
+/**
+ * @brief Enables external exceptions.
+ *
+ * You can use this function to enable the external exceptions and restore the
+ * machine state with ppc_external_exceptions_disable() later.
+ */
+static inline uint32_t ppc_external_exceptions_enable(void)
+{
+  uint32_t current_msr;
+  uint32_t new_msr;
+
+  RTEMS_COMPILER_MEMORY_BARRIER();
+
+  __asm__ volatile (
+    "mfmsr %0;"
+    "ori %1, %0, 0x8000;"
+    "mtmsr %1"
+    : "=r" (current_msr), "=r" (new_msr)
+  );
+
+  return current_msr;
+}
+
+/**
+ * @brief Restores machine state.
+ *
+ * @see ppc_external_exceptions_enable()
+ */
+static inline void ppc_external_exceptions_disable(uint32_t msr)
+{
+  ppc_set_machine_state_register(msr);
+
+  RTEMS_COMPILER_MEMORY_BARRIER();
+}
+
+static inline uint32_t ppc_count_leading_zeros(uint32_t value)
+{
+  uint32_t count;
+
+  __asm__ (
+    "cntlzw %0, %1;"
+    : "=r" (count)
+    : "r" (value)
+  );
+
+  return count;
+}
+
+/*
+ *  Simple spin delay in microsecond units for device drivers.
+ *  This is very dependent on the clock speed of the target.
+ */
+
+#if defined(mpx8xx) || defined(mpc860) || defined(mpc821)
+/* Wonderful bookE doesn't have mftb/mftbu; they only
+ * define the TBRU/TBRL SPRs so we use these. Luckily,
+ * we run in supervisory mode so that should work on
+ * all CPUs. In user mode we'd have a problem...
+ * 2007/11/30, T.S.
+ *
+ * OTOH, PSIM currently lacks support for reading
+ * SPRs 268/269. You need GDB patch sim/2376 to avoid
+ * a crash...
+ * OTOH, the MPC8xx do not allow to read the timebase registers via mfspr.
+ * we NEED a mftb to access the time base.
+ * 2009/10/30 Th. D.
+ */
+#define CPU_Get_timebase_low( _value ) \
+    __asm__ volatile( "mftb  %0" : "=r" (_value) )
+#else
+#define CPU_Get_timebase_low( _value ) \
+    __asm__ volatile( "mfspr %0,268" : "=r" (_value) )
+#endif
+
+/* Must be provided for rtems_bsp_delay to work */
+extern     uint32_t bsp_clicks_per_usec;
+
+#define rtems_bsp_delay( _microseconds ) \
+  do { \
+    uint32_t   start, ticks, now; \
+    CPU_Get_timebase_low( start ) ; \
+    ticks = (_microseconds) * bsp_clicks_per_usec; \
+    do \
+      CPU_Get_timebase_low( now ) ; \
+    while (now - start < ticks); \
+  } while (0)
+
+#define rtems_bsp_delay_in_bus_cycles( _cycles ) \
+  do { \
+    uint32_t   start, now; \
+    CPU_Get_timebase_low( start ); \
+    do \
+      CPU_Get_timebase_low( now ); \
+    while (now - start < (_cycles)); \
+  } while (0)
+
+/*
+ *  Routines to access the decrementer register
+ */
+
+#define PPC_Set_decrementer( _clicks ) \
+  do { \
+    __asm__ volatile( "mtdec %0" : : "r" ((_clicks)) ); \
+  } while (0)
+
+#define PPC_Get_decrementer( _clicks ) \
+    __asm__ volatile( "mfdec  %0" : "=r" (_clicks) )
+
+/*
+ *  Routines to access the time base register
+ */
+
+static inline uint64_t PPC_Get_timebase_register( void )
+{
+  uint32_t tbr_low;
+  uint32_t tbr_high;
+  uint32_t tbr_high_old;
+  uint64_t tbr;
+
+  do {
+#if defined(mpx8xx) || defined(mpc860) || defined(mpc821)
+/* See comment above (CPU_Get_timebase_low) */
+    __asm__ volatile( "mftbu %0" : "=r" (tbr_high_old));
+    __asm__ volatile( "mftb  %0" : "=r" (tbr_low));
+    __asm__ volatile( "mftbu %0" : "=r" (tbr_high));
+#else
+    __asm__ volatile( "mfspr %0, 269" : "=r" (tbr_high_old));
+    __asm__ volatile( "mfspr %0, 268" : "=r" (tbr_low));
+    __asm__ volatile( "mfspr %0, 269" : "=r" (tbr_high));
+#endif
+  } while ( tbr_high_old != tbr_high );
+
+  tbr = tbr_high;
+  tbr <<= 32;
+  tbr |= tbr_low;
+  return tbr;
+}
+
+static inline  void PPC_Set_timebase_register (uint64_t tbr)
+{
+  uint32_t tbr_low;
+  uint32_t tbr_high;
+
+  tbr_low = (uint32_t) tbr;
+  tbr_high = (uint32_t) (tbr >> 32);
+  __asm__ volatile( "mtspr 284, %0" : : "r" (tbr_low));
+  __asm__ volatile( "mtspr 285, %0" : : "r" (tbr_high));
+
+}
+
+static inline uint32_t ppc_decrementer_register(void)
+{
+  uint32_t dec;
+
+  PPC_Get_decrementer(dec);
+
+  return dec;
+}
+
+static inline void ppc_set_decrementer_register(uint32_t dec)
+{
+  PPC_Set_decrementer(dec);
+}
+
+/**
+ * @brief Preprocessor magic for stringification of @a x.
+ */
+#define PPC_STRINGOF(x) #x
+
+/**
+ * @brief Returns the value of the Special Purpose Register with number @a spr.
+ *
+ * @note This macro uses a GNU C extension.
+ */
+#define PPC_SPECIAL_PURPOSE_REGISTER(spr) \
+  ({ \
+    uint32_t val; \
+    __asm__ volatile (\
+      "mfspr %0, " PPC_STRINGOF(spr) \
+      : "=r" (val) \
+    ); \
+    val;\
+  } )
+
+/**
+ * @brief Sets the Special Purpose Register with number @a spr to the value in
+ * @a val.
+ */
+#define PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val) \
+  do { \
+    __asm__ volatile (\
+      "mtspr " PPC_STRINGOF(spr) ", %0" \
+      : \
+      : "r" (val) \
+    ); \
+  } while (0)
+
+/**
+ * @brief Sets in the Special Purpose Register with number @a spr all bits
+ * which are set in @a bits.
+ *
+ * Interrupts are disabled throughout this operation.
+ */
+#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
+  do { \
+    ISR_Level level; \
+    uint32_t val; \
+    uint32_t mybits = bits; \
+    _ISR_Local_disable(level); \
+    val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
+    val |= mybits; \
+    PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
+    _ISR_Local_enable(level); \
+  } while (0)
+
+/**
+ * @brief Sets in the Special Purpose Register with number @a spr all bits
+ * which are set in @a bits.  The previous register value will be masked with
+ * @a mask.
+ *
+ * Interrupts are disabled throughout this operation.
+ */
+#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED(spr, bits, mask) \
+  do { \
+    ISR_Level level; \
+    uint32_t val; \
+    uint32_t mybits = bits; \
+    uint32_t mymask = mask; \
+    _ISR_Local_disable(level); \
+    val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
+    val &= ~mymask; \
+    val |= mybits; \
+    PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
+    _ISR_Local_enable(level); \
+  } while (0)
+
+/**
+ * @brief Clears in the Special Purpose Register with number @a spr all bits
+ * which are set in @a bits.
+ *
+ * Interrupts are disabled throughout this operation.
+ */
+#define PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
+  do { \
+    ISR_Level level; \
+    uint32_t val; \
+    uint32_t mybits = bits; \
+    _ISR_Local_disable(level); \
+    val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
+    val &= ~mybits; \
+    PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
+    _ISR_Local_enable(level); \
+  } while (0)
+
+/**
+ * @brief Returns the value of the Thread Management Register with number @a tmr.
+ *
+ * @note This macro uses a GNU C extension.
+ */
+#define PPC_THREAD_MGMT_REGISTER(tmr) \
+  ({ \
+    uint32_t val; \
+    __asm__ volatile (\
+      "mftmr %0, " PPC_STRINGOF(tmr) \
+      : "=r" (val) \
+    ); \
+    val;\
+  } )
+
+/**
+ * @brief Sets the Thread Management Register with number @a tmr to the value in
+ * @a val.
+ */
+#define PPC_SET_THREAD_MGMT_REGISTER(tmr, val) \
+  do { \
+    __asm__ volatile (\
+      "mttmr " PPC_STRINGOF(tmr) ", %0" \
+      : \
+      : "r" (val) \
+    ); \
+  } while (0)
+
+/**
+ * @brief Returns the value of the Device Control Register with number @a dcr.
+ *
+ * The PowerPC 4XX family has Device Control Registers.
+ *
+ * @note This macro uses a GNU C extension.
+ */
+#define PPC_DEVICE_CONTROL_REGISTER(dcr) \
+  ({ \
+    uint32_t val; \
+    __asm__ volatile (\
+      "mfdcr %0, " PPC_STRINGOF(dcr) \
+      : "=r" (val) \
+    ); \
+    val;\
+  } )
+
+/**
+ * @brief Sets the Device Control Register with number @a dcr to the value in
+ * @a val.
+ *
+ * The PowerPC 4XX family has Device Control Registers.
+ */
+#define PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val) \
+  do { \
+    __asm__ volatile (\
+      "mtdcr " PPC_STRINGOF(dcr) ", %0" \
+      : \
+      : "r" (val) \
+    ); \
+  } while (0)
+
+/**
+ * @brief Sets in the Device Control Register with number @a dcr all bits
+ * which are set in @a bits.
+ *
+ * Interrupts are disabled throughout this operation.
+ */
+#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
+  do { \
+    ISR_Level level; \
+    uint32_t val; \
+    uint32_t mybits = bits; \
+    _ISR_Local_disable(level); \
+    val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
+    val |= mybits; \
+    PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
+    _ISR_Local_enable(level); \
+  } while (0)
+
+/**
+ * @brief Sets in the Device Control Register with number @a dcr all bits
+ * which are set in @a bits.  The previous register value will be masked with
+ * @a mask.
+ *
+ * Interrupts are disabled throughout this operation.
+ */
+#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS_MASKED(dcr, bits, mask) \
+  do { \
+    ISR_Level level; \
+    uint32_t val; \
+    uint32_t mybits = bits; \
+    uint32_t mymask = mask; \
+    _ISR_Local_disable(level); \
+    val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
+    val &= ~mymask; \
+    val |= mybits; \
+    PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
+    _ISR_Local_enable(level); \
+  } while (0)
+
+/**
+ * @brief Clears in the Device Control Register with number @a dcr all bits
+ * which are set in @a bits.
+ *
+ * Interrupts are disabled throughout this operation.
+ */
+#define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
+  do { \
+    ISR_Level level; \
+    uint32_t val; \
+    uint32_t mybits = bits; \
+    _ISR_Local_disable(level); \
+    val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
+    val &= ~mybits; \
+    PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
+    _ISR_Local_enable(level); \
+  } while (0)
+
+static inline uint32_t ppc_time_base(void)
+{
+  uint32_t val;
+
+  CPU_Get_timebase_low(val);
+
+  return val;
+}
+
+static inline void ppc_set_time_base(uint32_t val)
+{
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(TBWL, val);
+}
+
+static inline uint32_t ppc_time_base_upper(void)
+{
+  return PPC_SPECIAL_PURPOSE_REGISTER(TBRU);
+}
+
+static inline void ppc_set_time_base_upper(uint32_t val)
+{
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(TBWU, val);
+}
+
+static inline uint64_t ppc_time_base_64(void)
+{
+  return PPC_Get_timebase_register();
+}
+
+static inline void ppc_set_time_base_64(uint64_t val)
+{
+  PPC_Set_timebase_register(val);
+}
+
+static inline uint32_t ppc_alternate_time_base(void)
+{
+  return PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_ATBL);
+}
+
+static inline uint32_t ppc_alternate_time_base_upper(void)
+{
+  return PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_ATBU);
+}
+
+static inline uint64_t ppc_alternate_time_base_64(void)
+{
+  uint32_t atbl;
+  uint32_t atbu_0;
+  uint32_t atbu_1;
+
+  do {
+    atbu_0 = ppc_alternate_time_base_upper();
+    atbl = ppc_alternate_time_base();
+    atbu_1 = ppc_alternate_time_base_upper();
+  } while (atbu_0 != atbu_1);
+
+  return (((uint64_t) atbu_1) << 32) | ((uint64_t) atbl);
+}
+
+static inline uint32_t ppc_processor_id(void)
+{
+  return PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR);
+}
+
+static inline void ppc_set_processor_id(uint32_t val)
+{
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR, val);
+}
+
+static inline uint32_t ppc_fsl_system_version(void)
+{
+  return PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_SVR);
+}
+
+static inline uint32_t ppc_fsl_system_version_cid(uint32_t svr)
+{
+  return (svr >> 28) & 0xf;
+}
+
+static inline uint32_t ppc_fsl_system_version_sid(uint32_t svr)
+{
+  return (svr >> 16) & 0xfff;
+}
+
+static inline uint32_t ppc_fsl_system_version_proc(uint32_t svr)
+{
+  return (svr >> 12) & 0xf;
+}
+
+static inline uint32_t ppc_fsl_system_version_mfg(uint32_t svr)
+{
+  return (svr >> 8) & 0xf;
+}
+
+static inline uint32_t ppc_fsl_system_version_mjrev(uint32_t svr)
+{
+  return (svr >> 4) & 0xf;
+}
+
+static inline uint32_t ppc_fsl_system_version_mnrev(uint32_t svr)
+{
+  return (svr >> 0) & 0xf;
+}
+
+void ppc_code_copy(void *dest, const void *src, size_t n);
+
+/* FIXME: Do not use this function */
+void printBAT(int bat, uint32_t upper, uint32_t lower);
+
+/* FIXME: Do not use this function */
+void ShowBATS(void);
+
+#endif /* ifndef ASM */
+
+#if defined(ASM)
+#include <rtems/asm.h>
+
+.macro LA reg, addr
+#if defined(__powerpc64__)
+	lis	\reg, (\addr)@highest
+	ori	\reg, \reg, (\addr)@higher
+	rldicr	\reg, \reg, 32, 31
+	oris	\reg, \reg, (\addr)@h
+	ori	\reg, \reg, (\addr)@l
+#else
+	lis	\reg, (\addr)@h
+	ori	\reg, \reg, (\addr)@l
+#endif
+.endm
+
+.macro LA32 reg, addr
+	lis	\reg, (\addr)@h
+	ori	\reg, \reg, (\addr)@l
+.endm
+
+.macro LWI reg, value
+	lis \reg, (\value)@h
+	ori	\reg, \reg, (\value)@l
+.endm
+
+.macro LW reg, addr
+	lis	\reg, \addr@ha
+	lwz	\reg, \addr@l(\reg)
+.endm
+
+/*
+ * Tests the bits in reg1 against the bits set in mask.  A match is indicated
+ * by EQ = 0 in CR0.  A mismatch is indicated by EQ = 1 in CR0.  The register
+ * reg2 is used to load the mask.
+ */
+.macro	TSTBITS	reg1, reg2, mask
+	LWI 	\reg2, \mask
+	and	\reg1, \reg1, \reg2
+	cmplw	\reg1, \reg2
+.endm
+
+.macro 	SETBITS reg1, reg2, mask
+	LWI 	\reg2, \mask
+	or	\reg1, \reg1, \reg2
+.endm
+
+.macro 	CLRBITS reg1, reg2, mask
+	LWI 	\reg2, \mask
+	andc	\reg1, \reg1, \reg2
+.endm
+
+.macro GLOBAL_FUNCTION name
+	.global \name
+	.type \name, @function
+\name:
+.endm
+
+/*
+ * Obtain interrupt mask
+ */
+.macro GET_INTERRUPT_MASK mask
+	lis	\mask, _PPC_INTERRUPT_DISABLE_MASK@h
+	ori	\mask, \mask, _PPC_INTERRUPT_DISABLE_MASK@l
+.endm
+
+/*
+ * Disables all asynchronous exeptions (interrupts) which may cause a context
+ * switch.
+ */
+.macro INTERRUPT_DISABLE level, mask
+	mfmsr	\level
+	GET_INTERRUPT_MASK mask=\mask
+	andc	\mask, \level, \mask
+	mtmsr	\mask
+.endm
+
+/*
+ * Restore previous machine state.
+ */
+.macro INTERRUPT_ENABLE level
+	mtmsr	\level
+.endm
+
+.macro SET_SELF_CPU_CONTROL reg_0, reg_1
+#if defined(RTEMS_SMP)
+	/* Use Book E Processor ID Register (PIR) */
+	mfspr	\reg_0, 286
+	slwi	\reg_0, \reg_0, PER_CPU_CONTROL_SIZE_LOG2
+#if defined(__powerpc64__)
+	LA	\reg_1, _Per_CPU_Information
+	add	\reg_0, \reg_0, \reg_1
+#else
+	addis	\reg_0, \reg_0, _Per_CPU_Information@ha
+	addi	\reg_0, \reg_0, _Per_CPU_Information@l
+#endif
+	mtspr	PPC_PER_CPU_CONTROL_REGISTER, \reg_0
+#endif
+.endm
+
+.macro GET_SELF_CPU_CONTROL reg
+#if defined(RTEMS_SMP)
+	mfspr	\reg, PPC_PER_CPU_CONTROL_REGISTER
+#else
+	lis	\reg, _Per_CPU_Information@h
+	ori	\reg, \reg, _Per_CPU_Information@l
+#endif
+.endm
+
+#define LINKER_SYMBOL(sym) .extern sym
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LIBCPU_POWERPC_UTILITY_H */
Index: bsps/powerpc/include/libcpu/pte121.h
===================================================================
--- bsps/powerpc/include/libcpu/pte121.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/pte121.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,265 @@
+#ifndef _LIBCPU_PTE121_H
+#define _LIBCPU_PTE121_H
+
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ *     Till Straumann <strauman@slac.stanford.edu>, 4/2002, 2003, 2004,
+ * 	   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
+ */
+
+/* Rudimentary page/hash table support for Powerpc
+ *
+ * A simple, static (i.e. no 'per-process' virtual
+ * address space etc.) page table providing
+ * one-to-one effective <-> virtual <-> physical
+ * address mapping.
+ *
+ * PURPOSE:
+ *    1) allow write-protection of text/read-only data areas
+ *    2) provide more effective-address space in case
+ *       the BATs are not enough
+ *    3) allow 'alias' mappings. Such aliases can only use
+ *       the upper bits of the VSID since VSID & 0xf and the
+ *       PI are always mapped 1:1 to the RPN.
+ * LIMITATIONS:
+ *    -  no PTE replacement (makes no sense in a real-time
+ *       environment, anyway) -> the page table just MUST
+ *       be big enough!.
+ *    -  only one page table supported.
+ *    -  no locking implemented. If multiple threads modify
+ *       the page table, it is the user's responsibility to
+ *       implement exclusive access.
+ */
+
+
+/* I don't include mmu.h here because it says it's derived from linux
+ * and I want to avoid licensing problems
+ */
+
+/* Abstract handle for a page table */
+typedef struct Triv121PgTblRec_ *Triv121PgTbl;
+
+/* A PTE entry */
+typedef struct PTERec_ {
+  volatile unsigned long v:1,    vsid:24, h:1, api: 6;
+  volatile unsigned long rpn:20, pad: 3, r:1, c:1, wimg:4, marked:1, pp:2;
+} PTERec, *APte;
+
+/* Initialize a trivial page table
+ * using 2^ldSize bytes of memory starting at
+ * 'base'.
+ *
+ * RETURNS: a handle to the internal data structure
+ *          used to manage the page table. NULL on
+ *          error.
+ *
+ * NOTES:   - 'base' must be aligned to the size
+ *          - minimal ldSize is 16 (== 64k)
+ *          - this routine maps the page table itself
+ *            with read-only access. While this prevents
+ *            the CPU from overwriting the page table,
+ *            it can still be corrupted by PCI bus masters
+ *            (like DMA engines, [VME] bridges etc.) and
+ *            even by this CPU if either the MMU is off
+ *            or if there is a DBAT mapping granting write
+ *            access...
+ */
+Triv121PgTbl
+triv121PgTblInit(unsigned long base, unsigned ldSize);
+
+/* get the log2 of the minimal page table size needed
+ * for mapping 'size' bytes.
+ *
+ * EXAMPLE: create a page table which maps the entire
+ *          physical memory. The page table itself shall
+ *          be allocated at the top of the available
+ *          memory (assuming 'memsize' is a power of two):
+ *
+ *  ldSize = triv121PgTblLdMinSize(memsize);
+ *  memsize -= (1<<ldSize);  / * reduce memory available to RTEMS * /
+ *  pgTbl  = triv121PgTblInit(memsize,ldSize);
+ *
+ */
+unsigned long
+triv121PgTblLdMinSize(unsigned long size);
+
+/* Map an address range 1:1 in pgTbl with the given protection;
+ *
+ * RETURNS: -1 (TRIV121_MAP_SUCCESS) on success; the page index
+ *          for which no PTE could be allocated, on failure.
+ *
+ * NOTES:   - This routine returns MINUS ONE ON SUCCESS
+ *          - (parts) of a mapping which overlap with
+ *            already existing PTEs are silently ignored.
+ *
+ *            Therefore, you can e.g. first create
+ *            a couple of write protected maps and
+ *            finally map the entire memory r/w. This
+ *            will leave the write protected maps
+ *            intact.
+ */
+long
+triv121PgTblMap(
+  Triv121PgTbl  pgTbl,     /* handle, returned by Init or Get */
+
+  long          vsid,      /* vsid for this mapping (contains topmost 4 bits of EA);
+                            *
+                            * NOTE: it is allowed to pass a VSID < 0 to tell this
+                            *       routine it should use a VSID corresponding to a
+                            *       1:1:1  effective - virtual - physical  mapping
+                            */
+
+  unsigned long start,     /* segment offset (lowermost 28 bits of EA) of address range
+                            *
+                            * NOTE: if VSID < 0 (TRIV121_121_VSID), 'start' is inter-
+                            *       preted as an effective address (EA), i.e. all 32
+                            *       bits are used - the most significant four going into
+                            *       to the VSID...
+                            */
+
+  unsigned long numPages,  /* number of pages to map */
+
+  unsigned wimgAttr,       /* 'wimg' attributes
+                            * (Write thru, cache Inhibit, coherent Memory,
+                            *  Guarded memory)
+                            */
+
+  unsigned protection      /* 'pp' access protection: Super      User
+                            *
+                            *   0                      r/w       none
+                            *   1                      r/w       ro
+                            *   2                      r/w       r/w
+                            *   3                      ro        ro
+                            */
+);
+
+#define TRIV121_ATTR_W  8
+#define TRIV121_ATTR_I  4
+#define TRIV121_ATTR_M  2
+#define TRIV121_ATTR_G  1
+
+/* for I/O pages (e.g. PCI, VME addresses) use cache inhibited
+ * and guarded pages. RTM about the 'eieio' instruction!
+ */
+#define TRIV121_ATTR_IO_PAGE    (TRIV121_ATTR_I|TRIV121_ATTR_G)
+
+#define TRIV121_PP_RO_PAGE      (1)  /* read-only for key = 1, unlocked by key=0 */
+#define TRIV121_PP_RW_PAGE      (2)  /* read-write for key = 1/0                 */
+
+#define TRIV121_121_VSID        (-1) /* use 1:1 effective<->virtual address mapping */
+#define TRIV121_SEG_VSID        (-2) /* lookup VSID in the segment register         */
+
+#define TRIV121_MAP_SUCCESS     (-1) /* triv121PgTblMap() returns this on SUCCESS */
+
+/* get a handle to the one and only page table
+ * (must have been initialized/allocated)
+ *
+ * RETURNS: NULL if the page table has not been initialized/allocated.
+ */
+Triv121PgTbl
+triv121PgTblGet(void);
+
+/*
+ * compute the SDR1 register value for the page table
+ */
+
+unsigned long
+triv121PgTblSDR1(Triv121PgTbl pgTbl);
+
+/*
+ * Activate the page table:
+ *  - set up the segment registers for a 1:1 effective <-> virtual address mapping,
+ *    give user and supervisor keys.
+ *  - set up the SDR1 register
+ *  - flush all tlbs
+ *  - 'lock' pgTbl, i.e. prevent all further modifications.
+ *
+ * NOTE: This routine does not change any BATs. Since these
+ *       have priority over the page table, the user
+ *       may have to switch overlapping BATs OFF in order
+ *       for the page table mappings to take effect.
+ */
+void triv121PgTblActivate(Triv121PgTbl pgTbl);
+
+/* Find the PTE for a EA and print its contents to stdout
+ * RETURNS: pte for EA or NULL if no entry was found.
+ */
+APte triv121DumpEa(unsigned long ea);
+
+/* Find and return a PTE for a vsid/pi combination
+ * RETURNS: pte or NULL if no entry was found
+ */
+APte triv121FindPte(unsigned long vsid, unsigned long pi);
+
+/*
+ * Unmap an effective address
+ *
+ * RETURNS: pte that mapped the ea or NULL if no
+ *          mapping existed.
+ */
+APte triv121UnmapEa(unsigned long ea);
+
+/*
+ * Change the WIMG and PP attributes of the page containing 'ea'
+ *
+ * NOTES:   The 'wimg' and 'pp' may be <0 to indicate that no
+ *          change is desired.
+ *
+ * RETURNS: Pointer to modified PTE or NULL if 'ea' is not mapped.
+ */
+APte triv121ChangeEaAttributes(unsigned long ea, int wimg, int pp);
+
+/* Make the whole page table writable
+ * NOTES:   If the page table has not been initialized yet,
+ *          this routine has no effect (i.e., after
+ *          initialization the page table will still be read-only).
+ */
+void triv121MakePgTblRW(void);
+
+/* Make the whole page table read-only
+ */
+void triv121MakePgTblRO(void);
+
+/* Dump a pte to stdout */
+long triv121DumpPte(APte pte);
+
+#endif
Index: bsps/powerpc/include/libcpu/raw_exception.h
===================================================================
--- bsps/powerpc/include/libcpu/raw_exception.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/raw_exception.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,161 @@
+/*
+ * raw_execption.h
+ *
+ *	    This file contains implementation of C function to
+ *          Instantiate mpc5xx primary exception entries.
+ *	    More detailled information can be found on the Motorola
+ *	    site and more precisely in the following book:
+ *
+ *		MPC555/MPC556 User's Manual
+ *		Motorola REF : MPC555UM/D Rev. 3, 2000 October 15
+ *
+ *
+ *  MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ *  Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ *  Derived from libcpu/powerpc/mpc8xx/exceptions/raw_exception.h:
+ *
+ *  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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_RAW_EXCEPTION_H
+#define _LIBCPU_RAW_EXCEPTION_H
+
+#include <libcpu/vectors.h>
+
+/*
+ * Exception Vectors as defined in the MPC555 User's Manual
+ */
+
+#define	ASM_RESET_VECTOR 	0x01
+#define	ASM_MACH_VECTOR		0x02
+
+#define	ASM_EXT_VECTOR 		0x05
+#define	ASM_ALIGN_VECTOR 	0x06
+#define	ASM_PROG_VECTOR		0x07
+#define	ASM_FLOAT_VECTOR	0x08
+#define	ASM_DEC_VECTOR		0x09
+
+#define	ASM_SYS_VECTOR		0x0C
+#define	ASM_TRACE_VECTOR	0x0D
+#define	ASM_FLOATASSIST_VECTOR	0x0E
+
+#define	ASM_SOFTEMUL_VECTOR	0x10
+
+#define	ASM_IPROT_VECTOR	0x13
+#define	ASM_DPROT_VECTOR	0x14
+
+#define ASM_DBREAK_VECTOR	0x1C
+#define ASM_IBREAK_VECTOR	0x1D
+#define ASM_MEBREAK_VECTOR	0x1E
+#define ASM_NMEBREAK_VECTOR	0x1F
+
+#define LAST_VALID_EXC		ASM_NMEBREAK_VECTOR
+
+#ifndef ASM
+
+/*
+ * Type definition for raw exceptions.
+ */
+
+typedef unsigned char  rtems_vector;
+struct 	__rtems_raw_except_connect_data__;
+typedef unsigned char 	rtems_raw_except_hdl_size;
+
+typedef struct {
+  rtems_vector			vector;
+  rtems_exception_handler_t*	raw_hdl;
+}rtems_raw_except_hdl;
+
+typedef void (*rtems_raw_except_enable)		(const struct __rtems_raw_except_connect_data__*);
+typedef void (*rtems_raw_except_disable)	(const struct __rtems_raw_except_connect_data__*);
+typedef int  (*rtems_raw_except_is_enabled)	(const struct __rtems_raw_except_connect_data__*);
+
+typedef struct __rtems_raw_except_connect_data__{
+ /*
+  * Exception vector (As defined in the manual)
+  */
+  rtems_vector			exceptIndex;
+  /*
+   * Exception raw handler. See comment on handler properties below in function prototype.
+   */
+  rtems_raw_except_hdl	   	hdl;
+  /*
+   * function for enabling raw exceptions. In order to be consistent
+   * with the fact that the raw connexion can defined in the
+   * libcpu library, this library should have no knowledge of
+   * board specific hardware to manage exceptions and thus the
+   * "on" routine must enable the except at processor level only.
+   *
+   */
+    rtems_raw_except_enable	on;
+  /*
+   * function for disabling raw exceptions. In order to be consistent
+   * with the fact that the raw connexion can defined in the
+   * libcpu library, this library should have no knowledge of
+   * board specific hardware to manage exceptions and thus the
+   * "on" routine must disable the except both at device and PIC level.
+   *
+   */
+  rtems_raw_except_disable	off;
+  /*
+   * function enabling to know what exception may currently occur
+   */
+  rtems_raw_except_is_enabled	isOn;
+}rtems_raw_except_connect_data;
+
+typedef struct {
+  /*
+   * size of all the table fields (*Tbl) described below.
+   */
+  unsigned int	 			exceptSize;
+  /*
+   * Default handler used when disconnecting exceptions.
+   */
+  rtems_raw_except_connect_data		defaultRawEntry;
+  /*
+   * Table containing initials/current value.
+   */
+  rtems_raw_except_connect_data*	rawExceptHdlTbl;
+}rtems_raw_except_global_settings;
+
+/*
+ * C callable function enabling to set up one raw idt entry
+ */
+extern int mpc5xx_set_exception (const rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to get one current raw idt entry
+ */
+extern int mpc5xx_get_current_exception (rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to remove one current raw idt entry
+ */
+extern int mpc5xx_delete_exception (const rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to check if vector is valid
+ */
+extern int mpc5xx_vector_is_valid(rtems_vector vector);
+
+inline static  void* mpc5xx_get_vector_addr(rtems_vector vector)
+{
+  return ((void*)  (((unsigned) vector) << 8));
+}
+/*
+ * Exception global init.
+ */
+extern int mpc5xx_init_exceptions (rtems_raw_except_global_settings* config);
+extern int mpc5xx_get_exception_config (rtems_raw_except_global_settings** config);
+
+# endif /* ASM */
+
+#define SIZEOF_
+
+#endif
Index: bsps/powerpc/include/libcpu/spr.h
===================================================================
--- bsps/powerpc/include/libcpu/spr.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/spr.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,78 @@
+/*
+ *  spr.h -- Access to special purpose registers.
+ *
+ *  Copyright (C) 1998 Gabriel Paubert, paubert@iram.es
+ *
+ *  Modified to compile in RTEMS development environment
+ *  by Eric Valette
+ *
+ *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ */
+
+
+#ifndef _LIBCPU_SPR_H
+#define _LIBCPU_SPR_H
+
+#include <rtems/powerpc/registers.h>
+
+#define __MFSPR(reg, val) \
+	__asm__ __volatile__("mfspr %0,"#reg : "=r" (val))
+
+#define __MTSPR(val, reg) \
+	__asm__ __volatile__("mtspr "#reg",%0" : : "r" (val))
+
+
+#define SPR_RW(reg) \
+static inline unsigned long _read_##reg(void) \
+{\
+	unsigned long val;\
+	__MFSPR(reg, val);\
+	return val;\
+}\
+static inline void _write_##reg(unsigned long val)\
+{\
+	__MTSPR(val,reg);\
+	return;\
+}
+
+#define SPR_RO(reg) \
+static inline unsigned long _read_##reg(void) \
+{\
+	unsigned long val;\
+	__MFSPR(reg,val);\
+	return val;\
+}
+
+static inline unsigned long _read_MSR(void)
+{
+	unsigned long val;
+	asm volatile("mfmsr %0" : "=r" (val));
+	return val;
+}
+
+static inline void _write_MSR(unsigned long val)
+{
+	asm volatile("mtmsr %0" : : "r" (val));
+	return;
+}
+
+static inline unsigned long _read_SR(void * va)
+{
+	unsigned long val;
+	asm volatile("mfsrin %0,%1" : "=r" (val): "r" (va));
+	return val;
+}
+
+static inline void _write_SR(unsigned long val, void * va)
+{
+	asm volatile("mtsrin %0,%1" : : "r"(val), "r" (va): "memory");
+	return;
+}
+
+
+#endif
Index: bsps/powerpc/include/libcpu/stackTrace.h
===================================================================
--- bsps/powerpc/include/libcpu/stackTrace.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/stackTrace.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,8 @@
+#ifndef _LIBCPU_STACKTRACE_H
+#define _LIBCPU_STACKTRACE_H
+
+void CPU_stack_take_snapshot(void **stack, int size, void *pc, void *lr, void *r1);
+
+void CPU_print_stack(void);
+
+#endif
Index: bsps/powerpc/include/libcpu/vectors.h
===================================================================
--- bsps/powerpc/include/libcpu/vectors.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
+++ bsps/powerpc/include/libcpu/vectors.h	(revision 2afb22b7e1ebcbe40373ff7e0efae7d207c655a9)
@@ -0,0 +1,115 @@
+/*
+ * vectors.h Exception frame related contant and API.
+ *
+ *  This include file describe the data structure and the functions implemented
+ *  by rtems to handle exceptions.
+ *
+ *
+ *  MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ *  Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ *  Derived from libbsp/powerpc/mbx8xx/vectors/vectors.h:
+ *
+ *  CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+#ifndef _LIBCPU_VECTORS_H
+#define _LIBCPU_VECTORS_H
+
+
+/*
+ * Size of hardware vector table.
+ */
+#define NUM_EXCEPTIONS		0x20
+
+/*
+ * The callee (high level exception code written in C)
+ * will store the Link Registers (return address) at entry r1 + 4 !!!.
+ * So let room for it!!!.
+ */
+#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
+#define SRR0_FRAME_OFFSET 8
+#define SRR1_FRAME_OFFSET 12
+#define EXCEPTION_NUMBER_OFFSET 16
+#define EXC_CR_OFFSET 20
+#define EXC_CTR_OFFSET 24
+#define EXC_XER_OFFSET 28
+#define EXC_LR_OFFSET 32
+#define GPR0_OFFSET 36
+#define GPR1_OFFSET 40
+#define GPR2_OFFSET 44
+#define GPR3_OFFSET 48
+#define GPR4_OFFSET 52
+#define GPR5_OFFSET 56
+#define GPR6_OFFSET 60
+#define GPR7_OFFSET 64
+#define GPR8_OFFSET 68
+#define GPR9_OFFSET 72
+#define GPR10_OFFSET 76
+#define GPR11_OFFSET 80
+#define GPR12_OFFSET 84
+#define GPR13_OFFSET 88
+#define GPR14_OFFSET 92
+#define GPR15_OFFSET 96
+#define GPR16_OFFSET 100
+#define GPR17_OFFSET 104
+#define GPR18_OFFSET 108
+#define GPR19_OFFSET 112
+#define GPR20_OFFSET 116
+#define GPR21_OFFSET 120
+#define GPR22_OFFSET 124
+#define GPR23_OFFSET 128
+#define GPR24_OFFSET 132
+#define GPR25_OFFSET 136
+#define GPR26_OFFSET 140
+#define GPR27_OFFSET 144
+#define GPR28_OFFSET 148
+#define GPR29_OFFSET 152
+#define GPR30_OFFSET 156
+#define GPR31_OFFSET 160
+/*
+ * maintain the EABI requested 8 bytes aligment
+ * As SVR4 ABI requires 16, make it 16 (as some
+ * exception may need more registers to be processed...)
+ */
+#define    EXCEPTION_FRAME_END 176
+
+#ifndef ASM
+
+#include <rtems.h>
+
+/*
+ * default raw exception handlers
+ */
+
+extern	void default_exception_vector_code_prolog(void);
+extern	int  default_exception_vector_code_prolog_size;
+extern  void initialize_exceptions(void);
+
+typedef void rtems_exception_handler_t (CPU_Exception_frame* excPtr);
+/*DEBUG typedef rtems_exception_handler_t cpuExcHandlerType; */
+
+/*
+ * Exception handler table.
+ *
+ * This table contains pointers to assembly-language exception handlers.
+ * The common exception prologue in vectors.S looks up an entry in this
+ * table and jumps to it.  No return address is saved, so the handlers in
+ * this table must return directly to the interrupted code.
+ *
+ * On entry to an exception handler, R1 points to a new exception stack
+ * frame in which R3, R4, and LR have been saved.  R4 holds the exception
+ * number.
+ */
+extern rtems_exception_handler_t* exception_handler_table[NUM_EXCEPTIONS];
+
+/* for compatability -- XXX remove */
+typedef rtems_exception_handler_t *cpuExcHandlerType;
+extern cpuExcHandlerType *globalExceptHdl;
+
+#endif /* ASM */
+
+#endif /* _LIBCPU_VECTORS_H */
