change log for rtems (2011-08-30)

rtems-vc at rtems.org rtems-vc at rtems.org
Tue Aug 30 14:11:45 UTC 2011


 *sh*:
2011-08-30	Sebastian Huber <sebastian.huber at embedded-brains.de>

	* include/bsp.h: Define BSP_FEATURE_IRQ_EXTENSION.

M   1.69  c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog
M    1.7  c/src/lib/libbsp/powerpc/mpc55xxevb/include/bsp.h

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog:1.68 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog:1.69
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog:1.68	Fri Jun 10 02:06:14 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog	Tue Aug 30 08:13:25 2011
@@ -1,3 +1,7 @@
+2011-08-30	Sebastian Huber <sebastian.huber at embedded-brains.de>
+
+	* include/bsp.h: Define BSP_FEATURE_IRQ_EXTENSION.
+
 2011-06-10	Sebastian Huber <sebastian.huber at embedded-brains.de>
 
 	* network/smsc9218i.c: Optimizations.

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/include/bsp.h:1.6 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/include/bsp.h:1.7
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/include/bsp.h:1.6	Wed Dec 22 08:21:03 2010
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/include/bsp.h	Tue Aug 30 08:13:25 2011
@@ -37,6 +37,8 @@
 
 #define BSP_SMALL_MEMORY 1
 
+#define BSP_FEATURE_IRQ_EXTENSION
+
 #ifndef ASM
 
 /** @brief System clock frequency */


 *sh*:
2011-08-30	Sebastian Huber <sebastian.huber at embedded-brains.de>

	* libchip/network/smc91111exp.h, libchip/network/smc91111.c: Use
	BSP_FEATURE_IRQ_EXTENSION define.

M  1.554  c/src/ChangeLog
M   1.13  c/src/libchip/network/smc91111.c
M    1.4  c/src/libchip/network/smc91111exp.h

diff -u rtems/c/src/ChangeLog:1.553 rtems/c/src/ChangeLog:1.554
--- rtems/c/src/ChangeLog:1.553	Tue Aug 30 08:07:20 2011
+++ rtems/c/src/ChangeLog	Tue Aug 30 08:16:35 2011
@@ -1,3 +1,8 @@
+2011-08-30	Sebastian Huber <sebastian.huber at embedded-brains.de>
+
+	* libchip/network/smc91111exp.h, libchip/network/smc91111.c: Use
+	BSP_FEATURE_IRQ_EXTENSION define.
+
 2011-08-30	Peter Dufault <dufault at hda.com>
 
 	* libchip/network/smc91111.c: Modify to support the MPC5554 using new

diff -u rtems/c/src/libchip/network/smc91111.c:1.12 rtems/c/src/libchip/network/smc91111.c:1.13
--- rtems/c/src/libchip/network/smc91111.c:1.12	Tue Aug 30 08:07:20 2011
+++ rtems/c/src/libchip/network/smc91111.c	Tue Aug 30 08:16:35 2011
@@ -59,14 +59,14 @@
 #include "smc91111config.h"
 #include <libchip/smc91111.h>
 
-#ifdef _OLD_EXCEPTIONS
-#if defined(__m68k__)
-extern m68k_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
+#ifdef BSP_FEATURE_IRQ_EXTENSION
+  #include <rtems/irq-extension.h>
 #else
-extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
-#endif
-#else
-#include <rtems/irq-extension.h>
+  #if defined(__m68k__)
+    extern m68k_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
+  #else
+    extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
+  #endif
 #endif
 
 struct lan91cxx_priv_data smc91111;
@@ -1072,21 +1072,25 @@
 	cpd->txbusy = cpd->within_send = 0;
 
 	/* install interrupt vector */
-#ifdef _OLD_EXCEPTIONS
+#ifdef BSP_FEATURE_IRQ_EXTENSION
+	{
+		rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+		sc = rtems_interrupt_handler_install(
+			cpd->config.vector,
+			cpd->config.info,
+			cpd->config.options,
+			cpd->config.interrupt_wrapper,
+			cpd->config.arg
+		);
+		if (sc != RTEMS_SUCCESSFUL) {
+			printf("rtems_interrupt_handler_install returned %d.\n", sc);
+			return 0;
+		}
+	}
+#else
 	db_printf("Install lan91cxx irqvector at %d\n", cpd->config.vector);
 	set_vector(lan91cxx_interrupt_handler, cpd->config.vector, 1);
-#else
-    {
-        int r;
-        if ((r = rtems_interrupt_handler_install(cpd->config.vector,
-        cpd->config.info,
-        cpd->config.options,
-        cpd->config.interrupt_wrapper,
-        cpd->config.arg) )) {
-                printf("rtems_interrupt_handler_install returned %d.\n", r);
-                return 0;
-        }
-    }
 #endif
 
 	/* Reset chip */

diff -u rtems/c/src/libchip/network/smc91111exp.h:1.3 rtems/c/src/libchip/network/smc91111exp.h:1.4
--- rtems/c/src/libchip/network/smc91111exp.h:1.3	Tue Aug 30 08:07:21 2011
+++ rtems/c/src/libchip/network/smc91111exp.h	Tue Aug 30 08:16:35 2011
@@ -5,6 +5,8 @@
 #ifndef _SMC91111_EXP_H_
 #define _SMC91111_EXP_H_
 
+#include <bsp.h>
+
 typedef struct scmv91111_configuration {
   void                     *baseaddr;
   unsigned int              vector;
@@ -12,9 +14,7 @@
   unsigned int              ctl_rspeed;
   unsigned int              ctl_rfduplx;
   unsigned int              ctl_autoneg;
-#ifndef _OLD_EXCEPTIONS
-  /* New arguments for the Interrupt Manager Extension:
-   */
+#ifdef BSP_FEATURE_IRQ_EXTENSION
   const char *              info;
   rtems_option              options;
   rtems_interrupt_handler   interrupt_wrapper;


 *sh*:
2011-08-30	Peter Dufault <dufault at hda.com>

	* mpc55xx/misc/flash_support.c: New file.
	* Makefile.am: Reflect change above.
	* mpc55xx/include/mpc55xx.h: Add definitions for the FLASH interface
	and two memory protect interfaces.  Add modifications to eliminate
	warnings in some of the cache macros.
	* mpc55xx/include/regs.h: Add some structure tag names for some
	structures that I needed access to.  Don't define the ALTCADR for the
	MPC5554 - it is reserved and acess casues an exception.  Hide the C99
	designated initializers when compiling with C++.  Add some support for
	the EQADC.
	* mpc55xx/include/esci.h, mpc55xx/include/watchdog.h: Add C++
	protection.

M  1.391  c/src/lib/libcpu/powerpc/ChangeLog
M   1.67  c/src/lib/libcpu/powerpc/Makefile.am
M    1.3  c/src/lib/libcpu/powerpc/mpc55xx/include/esci.h
M    1.5  c/src/lib/libcpu/powerpc/mpc55xx/include/mpc55xx.h
M    1.7  c/src/lib/libcpu/powerpc/mpc55xx/include/regs.h
M    1.2  c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h
A    1.1  c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c

diff -u rtems/c/src/lib/libcpu/powerpc/ChangeLog:1.390 rtems/c/src/lib/libcpu/powerpc/ChangeLog:1.391
--- rtems/c/src/lib/libcpu/powerpc/ChangeLog:1.390	Wed Aug 24 04:45:20 2011
+++ rtems/c/src/lib/libcpu/powerpc/ChangeLog	Tue Aug 30 08:30:08 2011
@@ -1,3 +1,18 @@
+2011-08-30	Peter Dufault <dufault at hda.com>
+
+	* mpc55xx/misc/flash_support.c: New file.
+	* Makefile.am: Reflect change above.
+	* mpc55xx/include/mpc55xx.h: Add definitions for the FLASH interface
+	and two memory protect interfaces.  Add modifications to eliminate
+	warnings in some of the cache macros.
+	* mpc55xx/include/regs.h: Add some structure tag names for some
+	structures that I needed access to.  Don't define the ALTCADR for the
+	MPC5554 - it is reserved and acess casues an exception.  Hide the C99
+	designated initializers when compiling with C++.  Add some support for
+	the EQADC.
+	* mpc55xx/include/esci.h, mpc55xx/include/watchdog.h: Add C++
+	protection.
+
 2011-08-24	Sebastian Huber <sebastian.huber at embedded-brains.de>
 
 	* mpc6xx/clock/c_clock.c, mpc6xx/mmu/mmuAsm.S,

diff -u rtems/c/src/lib/libcpu/powerpc/Makefile.am:1.66 rtems/c/src/lib/libcpu/powerpc/Makefile.am:1.67
--- rtems/c/src/lib/libcpu/powerpc/Makefile.am:1.66	Thu Jul 21 10:03:31 2011
+++ rtems/c/src/lib/libcpu/powerpc/Makefile.am	Tue Aug 30 08:30:08 2011
@@ -468,7 +468,8 @@
 noinst_PROGRAMS += mpc55xx/misc.rel
 mpc55xx_misc_rel_SOURCES = mpc55xx/misc/copy.S \
 	mpc55xx/misc/fmpll.S \
-	mpc55xx/misc/flash.S
+	mpc55xx/misc/flash.S \
+	mpc55xx/misc/flash_support.c
 mpc55xx_misc_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
 
 endif

diff -u rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/esci.h:1.2 rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/esci.h:1.3
--- rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/esci.h:1.2	Sun Nov 29 23:07:53 2009
+++ rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/esci.h	Tue Aug 30 08:30:08 2011
@@ -29,6 +29,10 @@
 
 #include <rtems/termiostypes.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
 #define MPC55XX_ESCI_NUMBER 2
 
 struct ESCI_tag;
@@ -45,4 +49,8 @@
 
 extern mpc55xx_esci_driver_entry mpc55xx_esci_driver_table [ /* MPC55XX_ESCI_NUMBER */ ];
 
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
 #endif /* LIBCPU_POWERPC_MPC55XX_ESCI_H */

diff -u rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/mpc55xx.h:1.4 rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/mpc55xx.h:1.5
--- rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/mpc55xx.h:1.4	Fri Feb 11 07:05:24 2011
+++ rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/mpc55xx.h	Tue Aug 30 08:30:08 2011
@@ -61,6 +61,44 @@
 /* Defined in flash.S */
 void mpc55xx_flash_config();
 
+int mpc55xx_flash_copy(void *dest, const void *src, size_t nbytes);
+int mpc55xx_flash_copy_op(void *rdest, const void *src, size_t nbytes,
+  uint32_t opmask, uint32_t *p_fail_addr);
+int mpc55xx_flash_size(uint32_t *p_size);
+int mpc55xx_flash_writable(void);
+uint32_t mpc55xx_flash_address(void);
+void mpc55xx_flash_set_read_only(void);
+void mpc55xx_flash_set_read_write(void);
+
+int mpc55xx_physical_address(const void *addr, uint32_t *p_result);
+int mpc55xx_mapped_address(const void *addr, uint32_t *p_result);
+
+/* Bits for opmask. */
+#define MPC55XX_FLASH_BLANK_CHECK 0x01
+#define MPC55XX_FLASH_UNLOCK      0x02
+#define MPC55XX_FLASH_ERASE       0x04
+#define MPC55XX_FLASH_PROGRAM     0x08
+#define MPC55XX_FLASH_VERIFY      0x10
+
+/* Error returns.  CONFIG or SIZE might mean you just
+ * need to check for new configuration bits.
+ * SIZE and RANGE mean you are outside of a known flash region.
+ * ERASE means the erase failed,
+ * PROGRAM means the program failed,
+ * BLANK means it wasn't blank and BLANK_CHECK was specified,
+ * VERIFY means VERIFY was set and it didn't match the source,
+ * and LOCK means either the locking failed or you needed to
+ * specify MPC55XX_FLASH_UNLOCK and didn't.
+ */
+#define MPC55XX_FLASH_CONFIG_ERR    (-1)
+#define MPC55XX_FLASH_SIZE_ERR      (-2)
+#define MPC55XX_FLASH_RANGE_ERR     (-3)
+#define MPC55XX_FLASH_ERASE_ERR     (-4)
+#define MPC55XX_FLASH_PROGRAM_ERR   (-5)
+#define MPC55XX_FLASH_NOT_BLANK_ERR (-6)
+#define MPC55XX_FLASH_VERIFY_ERR    (-7)
+#define MPC55XX_FLASH_LOCK_ERR      (-8)
+
 #define MPC55XX_CACHE_ALIGNED_MASK ((uintptr_t) 0x1f)
 
 #define MPC55XX_CACHE_LINE_SIZE 32
@@ -73,9 +111,9 @@
 	return !(((uintptr_t) s & MPC55XX_CACHE_ALIGNED_MASK) || (n & MPC55XX_CACHE_ALIGNED_MASK));
 }
 
-static inline void* mpc55xx_cache_aligned_start( const void *s)
+static inline uintptr_t mpc55xx_cache_aligned_start( const void *s)
 {
-	return ((uintptr_t) s & MPC55XX_CACHE_ALIGNED_MASK) ? (((uintptr_t) s & ~MPC55XX_CACHE_ALIGNED_MASK) + MPC55XX_CACHE_LINE_SIZE) : s;
+	return ((uintptr_t) s & MPC55XX_CACHE_ALIGNED_MASK) ? (((uintptr_t) s & ~MPC55XX_CACHE_ALIGNED_MASK) + MPC55XX_CACHE_LINE_SIZE) : (uintptr_t)s;
 }
 
 static inline size_t mpc55xx_non_cache_aligned_size( const void *s)

diff -u rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/regs.h:1.6 rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/regs.h:1.7
--- rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/regs.h:1.6	Wed Apr  7 09:19:55 2010
+++ rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/regs.h	Tue Aug 30 08:30:09 2011
@@ -562,7 +562,7 @@
             } B;
         } MCR;
 
-        union {                 /* LML Register */
+        union LMLR_tag {                 /* LML Register */
             uint32_t R;
             struct {
                 uint32_t LME:1;
@@ -573,7 +573,7 @@
             } B;
         } LMLR;
 
-        union {                 /* HL Register */
+        union HLR_tag {                 /* HL Register */
             uint32_t R;
             struct {
                 uint32_t HBE:1;
@@ -582,7 +582,7 @@
             } B;
         } HLR;
 
-        union {                 /* SLML Register */
+        union SLMLR_tag {                 /* SLML Register */
             uint32_t R;
             struct {
                 uint32_t SLE:1;
@@ -1130,9 +1130,15 @@
                 } B;
             } CSR;              /* Channel Status Register */
 
+#if MPC55XX_CHIP_TYPE == 5554
+          /* ALTCADR is reserved on the MPC5554 and writes will cause an exception.
+           */
+            uint32_t altcadr_reserved;
+#else
             union {
                 uint32_t R;    /* Alternate Channel A Data Register */
             } ALTCADR;
+#endif
 
             uint32_t emios_channel_reserved[2];
 
@@ -2838,6 +2844,7 @@
         } TCD[64];              /* transfer_control_descriptor */
     };
 
+#ifndef __cplusplus
     static const struct tcd_t EDMA_TCD_DEFAULT = {
         .SADDR = 0,
         .SDF = { .R = 0 },
@@ -2848,6 +2855,7 @@
         .DLAST_SGA = 0,
         .BMF = { .R = 0 }
     };
+#endif
 
 #define EDMA_TCD_BITER_MASK 0x7fff
 
@@ -2982,7 +2990,7 @@
 
         uint32_t eqadc_reserved4;
 
-        union {
+        union EQADC_CFCR_tag {
             uint16_t R;
             struct {
                 uint16_t:5;
@@ -2996,7 +3004,7 @@
 
         uint32_t eqadc_reserved5;
 
-        union {
+        union EQADC_IDCR_tag {
             uint16_t R;
             struct {
                 uint16_t NCIE:1;
@@ -3017,7 +3025,7 @@
 
         uint32_t eqadc_reserved6;
 
-        union {
+        union EQADC_FISR_tag {
             uint32_t R;
             struct {
                 uint32_t NCF:1;
@@ -4381,6 +4389,7 @@
         } MAS6;
     };
 
+#ifndef __cplusplus
     static const struct MMU_tag MMU_DEFAULT = {
         .MAS0 = { .R = 0x10000000 },
         .MAS1 = { .R = 0 },
@@ -4389,6 +4398,41 @@
         .MAS4 = { .R = 0 },
         .MAS6 = { .R = 0 }
     };
+#endif
+
+/* Message Formats for On-Chip ADC Operation
+ */
+union EQADC_CONVERSION_COMMAND_tag {
+    uint32_t R;
+    struct {
+        uint32_t EOQ:1;
+        uint32_t PAUSE:1;
+            uint32_t:3;
+        uint32_t EB:1;
+        uint32_t BN:1;
+        uint32_t CAL:1;
+        uint32_t MESSAGE_TAG:4;
+        uint32_t LST:2;
+        uint32_t TSR:1;
+        uint32_t FMT:1;
+        uint32_t CHANNEL_NUMBER:8;
+            uint32_t:8;
+    } B;
+}; /* Conversion command */
+
+union EQADC_WRITE_CONFIGURATION_COMMAND_tag {
+    uint32_t R;
+    struct {
+        uint32_t EOQ:1;
+        uint32_t PAUSE:1;
+            uint32_t:3;
+        uint32_t EB:1;
+        uint32_t BN:1;
+        uint32_t RW:1;
+        uint32_t VALUE:16;
+        uint32_t ADDR:8;
+    } B;
+}; /* Write configuration command */
 
 #if ((MPC55XX_CHIP_TYPE >= 5510) && (MPC55XX_CHIP_TYPE <= 5517))
 /* Define memories */

diff -u rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h:1.1 rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h:1.2
--- rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h:1.1	Fri Jul 18 10:56:48 2008
+++ rtems/c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h	Tue Aug 30 08:30:09 2011
@@ -27,6 +27,10 @@
 
 #include <libcpu/powerpc-utility.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
 static inline void mpc55xx_watchdog_clear()
 {
 	PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_WIS);
@@ -56,4 +60,8 @@
 	return RTEMS_SUCCESSFUL;
 }
 
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
 #endif /* LIBCPU_POWERPC_MPC55XX_WATCHDOG_H */

diff -u /dev/null rtems/c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c:1.1
--- /dev/null	Tue Aug 30 09:11:43 2011
+++ rtems/c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c	Tue Aug 30 08:30:09 2011
@@ -0,0 +1,697 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ *  @brief MPC55XX flash memory support.
+ *
+ *  I set my MMU up to map what will finally be in flash into RAM and at the
+ *  same time I map the flash to a different location.  When the software
+ *  is tested I can use this to copy the RAM version of the program into
+ *  the flash and when I reboot I'm running out of flash.
+ *
+ *  I use a flag word located after the boot configuration half-word to
+ *  indicate that the MMU should be left alone, and I don't include the RCHW
+ *  or that flag in my call to this routine.
+ *
+ *  There are obviously other uses for this.
+ **/
+
+/*
+ * Copyright (c) 2009-2011
+ * HD Associates, Inc.
+ * 18 Main Street
+ * Pepperell, MA 01463
+ * USA
+ * dufault at hda.com
+ *
+ * The license and distribution terms for this file may be found in the file
+ * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <mpc55xx/regs.h>
+#include <mpc55xx/mpc55xx.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <rtems/powerpc/registers.h>
+
+/* Set up the memory ranges for the flash on
+ * the MPC5553, MPC5554, MPC5566 and MPC5567.
+ * I check if it is an unknown CPU and return an error.
+ *
+ * These CPUS have a low, mid, and high space of memory.
+ *
+ * Only the low space really needs a table like this, but for simplicity
+ * I do low, mid, and high the same way.
+ */
+struct range {          /* A memory range. */
+    uint32_t lower;
+    uint32_t upper;
+};
+
+/* The ranges of the memory banks for the low space.  All the
+ * chips I'm looking at share this low format, identified by LAS=6:
+ * 2 16K banks,
+ * 2 48K banks,
+ * 2 64K banks.
+ */
+static const struct range lsel_ranges[] = {
+    {                        0, (1*16              )*1024 - 1},
+    {(1*16              )*1024, (2*16              )*1024 - 1},
+    {(2*16              )*1024, (2*16 + 1*48       )*1024 - 1},
+    {(2*16 + 1*48       )*1024, (2*16 + 2*48       )*1024 - 1},
+    {(2*16 + 2*48       )*1024, (2*16 + 2*48 + 1*64)*1024 - 1},
+    {(2*16 + 2*48 + 1*64)*1024, (2*16 + 2*48 + 2*64)*1024 - 1},
+};
+
+/* The ranges of the memory blocks for the mid banks, 2 128K banks.
+ * Again, all the chips share this, identified by MAS=0.
+ */
+#define MBSTART ((2*16+2*48+2*64)*1024)
+static const struct range msel_ranges[] = {
+    {MBSTART             , MBSTART + 1*128*1024 - 1},
+    {MBSTART + 1*128*1024, MBSTART + 2*128*1024 - 1},
+};
+
+/* The ranges of the memory blocks for the high banks.
+ * There are N 128K banks, where N <= 20,
+ * and is identified by looking at the SIZE field.
+ *
+ * This could benefit from being redone to save a few bytes
+ * and provide for bigger flash spaces.
+ */
+#define HBSTART (MBSTART+2*128*1024)
+static const struct range hbsel_ranges[] = {
+    {HBSTART              , HBSTART +  1*128*1024 - 1},
+    {HBSTART +  1*128*1024, HBSTART +  2*128*1024 - 1},
+    {HBSTART +  2*128*1024, HBSTART +  3*128*1024 - 1},
+    {HBSTART +  3*128*1024, HBSTART +  4*128*1024 - 1},
+    {HBSTART +  4*128*1024, HBSTART +  5*128*1024 - 1},
+    {HBSTART +  5*128*1024, HBSTART +  6*128*1024 - 1},
+    {HBSTART +  6*128*1024, HBSTART +  7*128*1024 - 1},
+    {HBSTART +  7*128*1024, HBSTART +  8*128*1024 - 1},
+    {HBSTART +  8*128*1024, HBSTART +  9*128*1024 - 1},
+    {HBSTART +  9*128*1024, HBSTART + 10*128*1024 - 1},
+    {HBSTART + 10*128*1024, HBSTART + 11*128*1024 - 1},
+    {HBSTART + 11*128*1024, HBSTART + 12*128*1024 - 1},
+    {HBSTART + 12*128*1024, HBSTART + 13*128*1024 - 1},
+    {HBSTART + 13*128*1024, HBSTART + 14*128*1024 - 1},
+    {HBSTART + 14*128*1024, HBSTART + 15*128*1024 - 1},
+    {HBSTART + 15*128*1024, HBSTART + 16*128*1024 - 1},
+    {HBSTART + 16*128*1024, HBSTART + 17*128*1024 - 1},
+    {HBSTART + 17*128*1024, HBSTART + 18*128*1024 - 1},
+    {HBSTART + 18*128*1024, HBSTART + 19*128*1024 - 1},
+    {HBSTART + 19*128*1024, HBSTART + 20*128*1024 - 1},
+};
+
+/* Set bits in a bitmask to indicate which banks are
+ * within the range "first" and "last".
+ */
+static void
+range_set(
+  uint32_t first,
+  uint32_t last,
+  int *p_bits,
+  const struct range *pr,
+  int n_range
+)
+{
+    int i;
+    int bits = 0;
+    for (i = 0; i < n_range; i++) {
+        /* If the upper limit is less than "first" or the lower limit
+         * is greater than "last" then the block is not in range.
+         */
+        if ( !(pr[i].upper < first || pr[i].lower > last)) {
+            bits |= (1 << i);   /* This block is in the range, set the bit. */
+        }
+
+    }
+    *p_bits = bits;
+}
+
+#define N(ARG) (sizeof(ARG)/sizeof(ARG[0]))
+
+/** Return the size of the on-chip flash
+ *  verifying that this is a device that we know about.
+ * @return 0 for OK, non-zero for error:
+ *  - MPC55XX_FLASH_VERIFY_ERR for LAS not 6 or MAS not 0.
+ *    @note This is overriding what verify means!
+ *  - MPC55XX_FLASH_SIZE_ERR Not a chip I've checked against the manual,
+ *                           athat is, SIZE not 5, 7, or 11.
+ */
+int
+mpc55xx_flash_size(
+  uint32_t *p_size  /**< The size is returned here. */
+)
+{
+    /* On the MPC5553, MPC5554, MPC5566, and MP5567 the
+     *  low address space LAS field is 0x6 and all have
+     *  six blocks sized 2*16k, 2*48k, and 2*64k.
+     *
+     * All the mid and high address spaces have 128K blocks.
+     *
+     * The mid address space MAS size field is 0 for the above machines,
+     * and they all have 2 128K blocks.
+     *
+     * For the high address space we look at the
+     * size field to figure out the size.  The SIZE field is:
+     *
+     * 5 for 1.5MB (MPC5553)
+     * 7 for 2MB (MPC5554, MPC5567)
+     * 11 for 3MB  (MPC5566)
+     */
+    int hblocks;    /* The number of blocks in the high address space. */
+
+    /* Verify the configuration matches one of the chips that I've checked out.
+     */
+    if (FLASH.MCR.B.LAS != 6 || FLASH.MCR.B.MAS != 0) {
+        return MPC55XX_FLASH_VERIFY_ERR;
+    }
+
+    switch(FLASH.MCR.B.SIZE) {
+        case 5:
+        hblocks = 8;
+        break;
+
+        case 7:
+        hblocks = 12;
+        break;
+
+        case 11:
+        hblocks = 20;
+        break;
+
+        default:
+        return MPC55XX_FLASH_SIZE_ERR;
+    }
+
+    /* The first two banks are 256K.
+     * The high block has "hblocks" 128K blocks.
+     */
+    *p_size = 256*1024 + 256*1024 + hblocks * 128*1024;
+    return 0;
+}
+
+/* Unlock the flash blocks if "p_locked" points to something that is 0.
+ * If it is a NULL pointer then we aren't allowed to do the unlock.
+ */
+static int
+unlock_once(int lsel, int msel, int hbsel, int *p_locked)
+{
+    union LMLR_tag lmlr;
+    union SLMLR_tag slmlr;
+    union HLR_tag hlr;
+    rtems_interrupt_level level;
+
+    /* If we're already locked return.
+     */
+    if (p_locked && (*p_locked == 1)) {
+        return 0;
+    }
+
+    /* Do we have to lock something in the low or mid block?
+     */
+    rtems_interrupt_disable(level);
+    lmlr = FLASH.LMLR;
+    if ((lsel || msel) && (lmlr.B.LME == 0)) {
+        union LMLR_tag lmlr_unlock;
+        lmlr_unlock.B.LLOCK=~lsel;
+        lmlr_unlock.B.MLOCK=~msel;
+        lmlr_unlock.B.SLOCK=1;
+
+        if (lmlr.B.LLOCK != lmlr_unlock.B.LLOCK ||
+        lmlr.B.MLOCK != lmlr_unlock.B.MLOCK) {
+            if (p_locked == 0) {
+                rtems_interrupt_enable(level);
+                return MPC55XX_FLASH_LOCK_ERR;
+            } else {
+                *p_locked = 1;
+            }
+            FLASH.LMLR.R = 0xA1A11111;  /* Unlock. */
+            FLASH.LMLR = lmlr_unlock;
+        }
+    }
+    rtems_interrupt_enable(level);
+
+    rtems_interrupt_disable(level);
+    slmlr = FLASH.SLMLR;
+    if ((lsel || msel) && (slmlr.B.SLE == 0)) {
+        union SLMLR_tag slmlr_unlock;
+        slmlr_unlock.B.SLLOCK=~lsel;
+        slmlr_unlock.B.SMLOCK=~msel;
+        slmlr_unlock.B.SSLOCK=1;
+
+        if (slmlr.B.SLLOCK != slmlr_unlock.B.SLLOCK ||
+        slmlr.B.SMLOCK != slmlr_unlock.B.SMLOCK) {
+            if (p_locked == 0) {
+                rtems_interrupt_enable(level);
+                return MPC55XX_FLASH_LOCK_ERR;
+            } else {
+                *p_locked = 1;
+            }
+            FLASH.SLMLR.R = 0xC3C33333;  /* Unlock. */
+            FLASH.SLMLR = slmlr_unlock;
+        }
+    }
+    rtems_interrupt_enable(level);
+
+    /* Do we have to unlock something in the high block?
+     */
+    rtems_interrupt_disable(level);
+    hlr = FLASH.HLR;
+    if (hbsel && (hlr.B.HBE == 0)) {
+        union HLR_tag hlr_unlock;
+        hlr_unlock.B.HBLOCK = ~hbsel;
+
+        if (hlr.B.HBLOCK != hlr_unlock.B.HBLOCK) {
+            if (p_locked == 0) {
+                return MPC55XX_FLASH_LOCK_ERR;
+                rtems_interrupt_enable(level);
+            } else {
+                *p_locked = 1;
+            }
+            FLASH.HLR.R = 0xB2B22222;   /* Unlock. */
+            FLASH.HLR = hlr_unlock;
+        }
+    }
+    rtems_interrupt_enable(level);
+
+    return 0;
+}
+
+static inline uint32_t
+tsize(int i)
+{
+  return 1 << (10 + 2 * i);
+}
+
+static int
+addr_map(
+  int to_phys,         /* If 1 lookup physical else lookup mapped. */
+  const void *addr,    /* The address to look up. */
+  uint32_t *p_result   /* Result is here. */
+)
+{
+    uint32_t u_addr = (uint32_t)addr;
+    uint32_t mas0, mas1, mas2, mas3;
+    uint32_t start, end;
+    rtems_interrupt_level level;
+    int i;
+
+    for (i = 0; i < 32; i++) {
+      mas0 = 0x10000000 | (i << 16);
+      rtems_interrupt_disable(level);
+      PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS0, mas0);
+      asm volatile("tlbre");
+      mas1 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS1);
+      mas2 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS2);
+      mas3 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3);
+      rtems_interrupt_enable(level);
+
+      if (mas1 & 0x80000000) {
+        /* Valid. */
+        start = (to_phys ? mas2 : mas3) & 0xFFFFF000;
+        end = start + tsize((mas1 >> 8) & 0x0000000F);
+        /* Are we within range?
+         */
+        if (start <= u_addr && end >= u_addr) {
+          uint32_t offset = (to_phys ? mas3 : mas2) & 0xFFFFF000;
+          *p_result = u_addr - offset;
+          return 0;
+        }
+      }
+    }
+
+    /* Not found in a TLB.
+     */
+    return ESRCH;
+}
+
+/** Return the physical address corresponding to a mapped address.
+  @return 0 if OK, ESRCH if not found in TLB1.
+ **/
+int
+mpc55xx_physical_address(
+  const void *addr,     /**< Mapped address. */
+  uint32_t *p_result    /**< Result returned here. */
+)
+{
+    return addr_map(1, addr, p_result);
+}
+
+/** Return the mapped address corresponding to a mapped address.
+  @return 0 if OK, ESRCH if not found in TLB1.
+ **/
+int
+mpc55xx_mapped_address(
+  const void *addr,     /**< Mapped address. */
+  uint32_t *p_result    /**< Result returned here. */
+)
+{
+    return addr_map(0, addr, p_result);
+}
+
+/**
+ * Copy memory from an address into the flash when flash is relocated
+ * If programming fails the address that it failed at can be returned.
+ @note At end of operation the flash may be left writable.
+ *     Use mpc55xx_flash_read_only() to set read-only.
+ @return Zero for OK, non-zero for error:
+ * - ESRCH                       Can't lookup where something lives.
+ * - EPERM                       Attempt to write to non-writable flash.
+ * - ETXTBSY                     Attempt to flash overlapping regions.
+ * - MPC55XX_FLASH_CONFIG_ERR    for LAS not 6 or MAS not 0.
+ * - MPC55XX_FLASH_SIZE_ERR      for SIZE not 5, 7, or 11.
+ * - MPC55XX_FLASH_RANGE_ERR     for illegal access:
+ *                               - first or first+last outside of flash;
+ *                               - first not on a mod(8) boundary;
+ *                               - nbytes not multiple of 8.
+ * - MPC55XX_FLASH_ERASE_ERR     Erase requested but failed.
+ * - MPC55XX_FLASH_PROGRAM_ERR   Program requested but failed.
+ * - MPC55XX_FLASH_NOT_BLANK_ERR Blank check requested but not blank.
+ * - MPC55XX_FLASH_VERIFY_ERR    Verify requested but failed.
+ * - MPC55XX_FLASH_LOCK_ERR      Unlock requested but failed.
+ **/
+
+int
+mpc55xx_flash_copy_op(
+  void *dest,       /**< An address in the flash to copy to. */
+  const void *src,  /**< An address in memory to copy from. */
+  size_t nbytes,    /**< The number of bytes to copy. */
+  uint32_t opmask,  /**< Bitmask of operations to perform.
+                     * - MPC55XX_FLASH_UNLOCK:      Unlock the blocks.
+                     * - MPC55XX_FLASH_ERASE:       Erase the blocks.
+                     * - MPC55XX_FLASH_BLANK_CHECK: Verify the blocks are blank.
+                     * - MPC55XX_FLASH_PROGRAM:     Program the FLASH.
+                     * - MPC55XX_FLASH_VERIFY:      Verify the regions match.
+                     **/
+  uint32_t *p_fail  /**< If not NULL then the address where the operation
+                     *   failed is returned here.
+                     **/
+)
+{
+    uint32_t udest, usrc, flash_size;
+    int r;
+    int peg;            /* Program or Erase Good - Did it work? */
+
+    int lsel;           /* Low block select bits. */
+    int msel;           /* Mid block select bits. */
+    int hbsel;          /* High block select bits. */
+
+    int s_lsel;           /* Source Low block select bits. */
+    int s_msel;           /* Source Mid block select bits. */
+    int s_hbsel;          /* Source High block select bits. */
+
+    int unlocked = 0;
+    int *p_unlocked;
+    int i;
+    int nwords;         /* The number of 32 bit words to write. */
+    volatile uint32_t *flash;    /* Where the flash is mapped in. */
+    volatile uint32_t *memory;   /* What to copy into flash. */
+    uint32_t offset;    /* Where the FLASH is mapped into memory. */
+    rtems_interrupt_level level;
+
+    if ( (r = mpc55xx_flash_size(&flash_size))) {
+        return r;
+    }
+
+    /* Get where the flash is mapped in.
+     */
+    offset = mpc55xx_flash_address();
+
+    udest = ((uint32_t)dest) - offset;
+    if ( (r = mpc55xx_physical_address(src, &usrc)) ) {
+      return r;
+    }
+
+    /* Verify that the address being programmed is in flash and that it is
+     * a multiple of 64 bits.
+     * Someone else can remove the 64-bit restriction.
+     */
+    if (udest > flash_size ||
+    udest + nbytes > flash_size ||
+    (udest & 0x7) != 0 ||
+    (nbytes & 0x7) != 0) {
+        return MPC55XX_FLASH_RANGE_ERR;
+    }
+
+    if (opmask == 0) {
+        return 0;
+    }
+
+    /* If we're going to do a write-style operation the flash must be writable.
+     */
+    if ((opmask &
+        (MPC55XX_FLASH_UNLOCK | MPC55XX_FLASH_ERASE | MPC55XX_FLASH_PROGRAM)) &&
+        !mpc55xx_flash_writable()
+    ) {
+      return EPERM;
+    }
+
+    /* If we aren't allowed to unlock then set the pointer to zero.
+     * That is how "unlock_once" decides we can't unlock.
+     */
+    p_unlocked = (opmask & MPC55XX_FLASH_UNLOCK) ? &unlocked : 0;
+
+    /* Set up the bit masks for the blocks to program or erase.
+     */
+    range_set(udest, udest + nbytes, &lsel,   lsel_ranges, N( lsel_ranges));
+    range_set(udest, udest + nbytes, &msel,   msel_ranges, N( msel_ranges));
+    range_set(udest, udest + nbytes, &hbsel, hbsel_ranges, N(hbsel_ranges));
+
+    range_set(usrc, usrc + nbytes, &s_lsel,   lsel_ranges, N( lsel_ranges));
+    range_set(usrc, usrc + nbytes, &s_msel,   msel_ranges, N( msel_ranges));
+    range_set(usrc, usrc + nbytes, &s_hbsel, hbsel_ranges, N(hbsel_ranges));
+
+    /* Are we attempting overlapping flash?
+     */
+    if ((lsel & s_lsel) | (msel & s_msel) | (hbsel & s_hbsel)) {
+      return ETXTBSY;
+    }
+
+    nwords = nbytes / 4;
+    flash = (volatile uint32_t *)dest;
+    memory = (volatile uint32_t *)src;
+
+  /* In the following sections any "Step N" notes refer to
+   * the steps in "13.4.2.3 Flash Programming" in the reference manual.
+   * XXX Do parts of this neeed to be protected by interrupt locks?
+   */
+
+    if (opmask & MPC55XX_FLASH_ERASE) {   /* Erase. */
+        if ( (r = unlock_once(lsel, msel, hbsel, p_unlocked)) ) {
+            return r;
+        }
+
+        rtems_interrupt_disable(level);
+        FLASH.MCR.B.ERS = 1;        /* Step 1: Select erase. */
+
+        FLASH.LMSR.B.LSEL = lsel;   /* Step 2: Select blocks to be erased. */
+        FLASH.LMSR.B.MSEL = msel;
+        FLASH.HSR.B.HBSEL = hbsel;
+
+        flash[0] = 1;               /* Step 3: Write to any address in the flash
+                                     * (the "erase interlock write)".
+                                     */
+        FLASH.MCR.B.EHV = 1;         /* Step 4: Enable high V to start erase. */
+        rtems_interrupt_enable(level);
+        while (FLASH.MCR.B.DONE == 0) { /* Step 5: Wait until done. */
+        }
+        rtems_interrupt_disable(level);
+        peg = FLASH.MCR.B.PEG;       /* Save result. */
+        FLASH.MCR.B.EHV = 0;         /* Disable high voltage. */
+        FLASH.MCR.B.ERS = 0;         /* De-select erase. */
+        rtems_interrupt_enable(level);
+        if (peg == 0) {
+            return MPC55XX_FLASH_ERASE_ERR; /* Flash erase failed. */
+        }
+    }
+
+    if (opmask & MPC55XX_FLASH_BLANK_CHECK) {    /* Verify blank. */
+        for (i = 0; i < nwords; i++) {
+           if (flash[i] != 0xffffffff) {
+                if (p_fail) {
+                    *p_fail = (uint32_t)(flash + i);
+                }
+                return MPC55XX_FLASH_NOT_BLANK_ERR; /* Not blank. */
+           }
+        }
+    }
+
+  /* Program.
+   */
+    if (opmask & MPC55XX_FLASH_PROGRAM) {
+        int chunk = 0;  /* Used to collect programming into 256 bit chunks. */
+
+        if ( (r = unlock_once(lsel, msel, hbsel, p_unlocked)) ) {
+            return r;
+        }
+        FLASH.MCR.B.PGM = 1;                /* Step 1 */
+
+       rtems_interrupt_disable(level);
+
+        for (i = 0; i < nwords; i += 2) {
+           flash[i] = memory[i];            /* Step 2 */
+           flash[i + 1] = memory[i + 1];    /* Always program in min 64 bits. */
+
+          /* Step 3 is "write additional words" */
+
+           /* Try to program in chunks of 256 bits.
+            * Collect the 64 bit writes into 256 bit ones:
+            */
+           chunk++;
+           if (chunk == 4) {
+                /* Collected 4 64-bits for a 256 bit chunk. */
+                FLASH.MCR.B.EHV = 1;            /* Step 4: Enable high V. */
+
+                rtems_interrupt_enable(level);
+                while (FLASH.MCR.B.DONE == 0) { /* Step 5: Wait until done. */
+                }
+                rtems_interrupt_disable(level);
+
+                peg = FLASH.MCR.B.PEG;          /* Step 6: Save result. */
+                FLASH.MCR.B.EHV = 0;            /* Step 7: Disable high V. */
+                if (peg == 0) {
+                    FLASH.MCR.B.PGM = 0;
+                    rtems_interrupt_enable(level);
+                    if (p_fail) {
+                        *p_fail = (uint32_t)(flash + i);
+                    }
+                    return MPC55XX_FLASH_PROGRAM_ERR; /* Programming failed. */
+                }
+                chunk = 0;                       /* Reset chunk counter. */
+            }
+                                                 /* Step 8: Back to step 2. */
+        }
+
+       if (!chunk) {
+            FLASH.MCR.B.PGM = 0;
+            rtems_interrupt_enable(level);
+       } else {
+           /* If there is anything left in that last chunk flush it out:
+            */
+            FLASH.MCR.B.EHV = 1;
+
+            rtems_interrupt_enable(level);
+            while (FLASH.MCR.B.DONE == 0) {     /* Wait until done. */
+            }
+            rtems_interrupt_disable(level);
+
+            peg = FLASH.MCR.B.PEG;              /* Save result. */
+            FLASH.MCR.B.EHV = 0;                /* Disable high voltage. */
+            FLASH.MCR.B.PGM = 0;
+            rtems_interrupt_enable(level);
+
+            if (peg == 0) {
+                if (p_fail) {
+                    *p_fail = (uint32_t)(flash + i);
+                }
+                return MPC55XX_FLASH_PROGRAM_ERR; /* Programming failed. */
+            }
+        }
+    }
+
+    if (opmask & MPC55XX_FLASH_VERIFY) {        /* Verify memory matches. */
+        for (i = 0; i < nwords; i++) {
+           if (flash[i] != memory[i]) {
+                if (p_fail) {              /* Return the failed address. */
+                    *p_fail = (uint32_t)(flash + i);
+                }
+                return MPC55XX_FLASH_VERIFY_ERR; /* Verification failed. */
+           }
+        }
+    }
+
+    return 0;
+}
+
+/** Simple flash copy with a signature that matches memcpy.
+ @note At end of operation the flash may be left writable.
+ *     Use mpc55xx_flash_read_only() to set read-only.
+ @return Zero for OK, non-zero for error.
+ *       see flash_copy_op() for possible errors.
+ **/
+int
+mpc55xx_flash_copy(
+  void *dest,       /**< An address in the flash to copy to. */
+  const void *src,  /**< An address in the flash copy from. */
+  size_t nbytes     /**< The number of bytes to copy. */
+)
+{
+    return mpc55xx_flash_copy_op(dest, src, nbytes,
+        (MPC55XX_FLASH_UNLOCK      |
+         MPC55XX_FLASH_ERASE       |
+         MPC55XX_FLASH_BLANK_CHECK |
+         MPC55XX_FLASH_PROGRAM     |
+         MPC55XX_FLASH_VERIFY      ), 0);
+}
+
+/** Make the flash read-write.
+ @note This assumes the flash is mapped by TLB1 entry 1.
+ */
+void
+mpc55xx_flash_set_read_write(void)
+{
+    rtems_interrupt_level level;
+    rtems_interrupt_disable(level);
+    PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000);
+    asm volatile("tlbre");
+    PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(FSL_EIS_MAS3, 0x0000000C);
+    asm volatile("tlbwe");
+    rtems_interrupt_enable(level);
+}
+
+/** Make the flash read-only.
+ @note This assumes the flash is mapped by TLB1 entry 1.
+ */
+void
+mpc55xx_flash_set_read_only(void)
+{
+    rtems_interrupt_level level;
+    rtems_interrupt_disable(level);
+    PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000);
+    asm volatile("tlbre");
+    PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(FSL_EIS_MAS3, 0x0000000C);
+    asm volatile("tlbwe");
+    rtems_interrupt_enable(level);
+}
+
+/** See if the flash is writable.
+ *  @note This assumes the flash is mapped by TLB1 entry 1.
+ *  @note It needs to be writable by both user and supervisor.
+ */
+int
+mpc55xx_flash_writable(void)
+{
+    uint32_t mas3;
+    rtems_interrupt_level level;
+
+    rtems_interrupt_disable(level);
+    PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000);
+    asm volatile("tlbre");
+    mas3 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3);
+    rtems_interrupt_enable(level);
+
+    return ((mas3 & 0x0000000C) == 0x0000000C) ? 1 : 0;
+}
+
+/** Return the address where the flash is mapped in.
+ @note This assumes the flash is mapped by TLB1 entry 1.
+ **/
+uint32_t
+mpc55xx_flash_address(void)
+{
+    uint32_t mas2;
+    rtems_interrupt_level level;
+
+    rtems_interrupt_disable(level);
+    PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000);
+    asm volatile("tlbre");
+    mas2 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS2);
+    rtems_interrupt_enable(level);
+
+    return mas2 & 0xFFFFF000;
+}


 *sh*:
2011-08-30	Peter Dufault <dufault at hda.com>

	* make/custom/phycore_mpc5554.cfg, startup/linkcmds.phycore_mpc5554,
	network/if_smc.c: New files.
	* Makefile.am, preinstall.am: Reflect changes above.
	* configure.ac: Add support for the Phytec PhyCORE MPC5554.  Includes:
	  - HAS_SMC91111 to indicate a BSP has that neworking.
	  - SMC91111_ENADDR_IS_SETUP so that it skips code to set up the MAC
	  address.
	  - MPC55XX_CLOCK_EMIOS_CHANNEL to permit one to set which eMIOS
	  channel to use for the clock.
	  - MPC55XX_BOOTFLAGS: Skips two words above the RCHW in the startup
	  for use in skpping over the MMU setup.  Required for debugging via a
	  cheap emulator where code is loaded into RAM and then mapped in as
	  flash.
	 - BOARD_PHYCORE_MPC5554 If defined, use custom settings for the
	 Phytec PhyCORE MPC5554 SOM.
	* clock/clock-config.c: Modify so that the EMIOS channel used for the
	clock can be selected at configuration time.  For MPC5544 only:
	  - Conditionally skip access to a register that faults if accessed on
	  the MPC5554
	  - Do not set the control register mode as was done for GW_LCFM
	  support, it breaks interrupts.
	* make/custom/mpc55xx.inc: Make it possible to override the soft-float
	to set the type of floating point BSP will use.
	* startup/start.S: Add support for the "boot flags", two long-words
	that I manipulate with the debugger to skip over MMU setup.  Use an
	external for the start of external SRAM instead of the hardwired
	number 0x20000000.  Disable write access to the internal flash.

M   1.70  c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog
M   1.27  c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am
M    1.6  c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c
M   1.18  c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac
M    1.3  c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc
A    1.1  c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/phycore_mpc5554.cfg
A    1.1  c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c
M   1.11  c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am
A    1.1  c/src/lib/libbsp/powerpc/mpc55xxevb/startup/linkcmds.phycore_mpc5554
M    1.9  c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog:1.69 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog:1.70
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog:1.69	Tue Aug 30 08:13:25 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog	Tue Aug 30 08:58:05 2011
@@ -1,3 +1,33 @@
+2011-08-30	Peter Dufault <dufault at hda.com>
+
+	* make/custom/phycore_mpc5554.cfg, startup/linkcmds.phycore_mpc5554,
+	network/if_smc.c: New files.
+	* Makefile.am, preinstall.am: Reflect changes above.
+	* configure.ac: Add support for the Phytec PhyCORE MPC5554.  Includes:
+	  - HAS_SMC91111 to indicate a BSP has that neworking.
+	  - SMC91111_ENADDR_IS_SETUP so that it skips code to set up the MAC
+	  address.
+	  - MPC55XX_CLOCK_EMIOS_CHANNEL to permit one to set which eMIOS
+	  channel to use for the clock.
+	  - MPC55XX_BOOTFLAGS: Skips two words above the RCHW in the startup
+	  for use in skpping over the MMU setup.  Required for debugging via a
+	  cheap emulator where code is loaded into RAM and then mapped in as
+	  flash.
+	 - BOARD_PHYCORE_MPC5554 If defined, use custom settings for the
+	 Phytec PhyCORE MPC5554 SOM.
+	* clock/clock-config.c: Modify so that the EMIOS channel used for the
+	clock can be selected at configuration time.  For MPC5544 only:
+	  - Conditionally skip access to a register that faults if accessed on
+	  the MPC5554
+	  - Do not set the control register mode as was done for GW_LCFM
+	  support, it breaks interrupts.
+	* make/custom/mpc55xx.inc: Make it possible to override the soft-float
+	to set the type of floating point BSP will use.
+	* startup/start.S: Add support for the "boot flags", two long-words
+	that I manipulate with the debugger to skip over MMU setup.  Use an
+	external for the start of external SRAM instead of the hardwired
+	number 0x20000000.  Disable write access to the internal flash.
+
 2011-08-30	Sebastian Huber <sebastian.huber at embedded-brains.de>
 
 	* include/bsp.h: Define BSP_FEATURE_IRQ_EXTENSION.

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am:1.26 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am:1.27
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am:1.26	Tue Jun  7 09:10:54 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am	Tue Aug 30 08:58:05 2011
@@ -24,8 +24,11 @@
 
 # Link commands
 project_lib_DATA += startup/linkcmds
-dist_project_lib_DATA += startup/linkcmds.gwlcfm  startup/linkcmds.mpc5566evb \
-	startup/linkcmds.base	
+dist_project_lib_DATA += \
+	startup/linkcmds.gwlcfm \
+	startup/linkcmds.phycore_mpc5554 \
+	startup/linkcmds.mpc5566evb \
+	startup/linkcmds.base
 
 noinst_LIBRARIES += libbsp.a
 libbsp_a_SOURCES =
@@ -71,7 +74,7 @@
 
 # Network
 if HAS_NETWORKING
-libbsp_a_SOURCES += network/smsc9218i.c
+libbsp_a_SOURCES += network/smsc9218i.c network/if_smc.c
 endif
 
 # BSP library

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c:1.5 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c:1.6
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c:1.5	Tue Jun  7 04:14:06 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c	Tue Aug 30 08:58:05 2011
@@ -31,8 +31,6 @@
 
 #include <rtems/status-checks.h>
 
-#define MPC55XX_CLOCK_EMIOS_CHANNEL (MPC55XX_EMIOS_CHANNEL_NUMBER - 1)
-
 /* This is defined in clockdrv_shell.h */
 rtems_isr Clock_isr( rtems_vector_number vector);
 
@@ -104,10 +102,21 @@
   /* Set unused registers */
   regs->CBDR.R = 0;
   regs->CCNTR.R = 0;
+#if MPC55XX_CHIP_TYPE != 5554
+  /* This is reserved on the MPC5554.
+   */
   regs->ALTCADR.R = 0;
+#endif
 
   /* Set control register */
+  /* The mode change, made by Thomas for GW_LCFM support, breaks interrupts
+   * on the MPC5554.
+   */
+#if MPC55XX_CHIP_TYPE == 5554
+  ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
+#else
   ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
+#endif
   ccr.B.UCPREN = 1;
   ccr.B.FEN = 1;
   ccr.B.FREN = 1;

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac:1.17 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac:1.18
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac:1.17	Tue Jun  7 08:30:46 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac	Tue Aug 30 08:58:05 2011
@@ -50,6 +50,7 @@
 [Define to 1 if you want interrupt-driven I/O for the SCI ports.])
 
 RTEMS_BSPOPTS_SET([PRINTK_MINOR],[gwlcfm],[MPC55XX_ESCI_A_MINOR])
+RTEMS_BSPOPTS_SET([PRINTK_MINOR],[phytec_mpc5554],[MPC55XX_ESCI_A_MINOR])
 RTEMS_BSPOPTS_SET([PRINTK_MINOR],[*]     ,[MPC55XX_ESCI_B_MINOR])
 RTEMS_BSPOPTS_HELP([PRINTK_MINOR],
 [Must be defined to be one of MPC55XX_ESCI_A_MINOR or MPC55XX_ESCI_B_MINOR.  Determines which
@@ -83,12 +84,28 @@
 RTEMS_BSPOPTS_HELP([MPC55XX_EMIOS_PRESCALER],
 [Must be defined to set the EMIOS prescaler])
 
+RTEMS_BSPOPTS_SET([HAS_SMC91111],[phycore_mpc5554],[1])
+RTEMS_BSPOPTS_HELP([HAS_SMC91111],
+[If defined the board has the SMC91111 networking chip.])
+
+RTEMS_BSPOPTS_SET([SMC91111_ENADDR_IS_SETUP],[phycore_mpc5554],[1])
+RTEMS_BSPOPTS_HELP([SMC91111_ENADDR_IS_SETUP],
+[If defined the SMC91111 chip has the ethernet address loaded at reset.])
+
+RTEMS_BSPOPTS_SET([MPC55XX_CLOCK_EMIOS_CHANNEL],[*],[(MPC55XX_EMIOS_CHANNEL_NUMBER-1)])
+RTEMS_BSPOPTS_HELP([MPC55XX_CLOCK_EMIOS_CHANNEL],
+[Define to the eMIOS channel to use for the BSP clock.
+ The default is the last channel.])
+
 RTEMS_BSPOPTS_SET([MPC55XX_CHIP_TYPE],[mpc5566evb],[5566])
 RTEMS_BSPOPTS_SET([MPC55XX_CHIP_TYPE],[gwlcfm]    ,[5516])
 RTEMS_BSPOPTS_SET([MPC55XX_CHIP_TYPE],[*]         ,[5554])
 RTEMS_BSPOPTS_HELP([MPC55XX_CHIP_TYPE],
 [specifies the chip type in use (e.g. 5554 for MPC5554)])
 
+RTEMS_BSPOPTS_HELP([MPC55XX_BOOTFLAGS],
+[If defined, builds in bootflags above the RCHW for setup in a debugger to avoid startup MMU setup])
+
 RTEMS_BSPOPTS_SET([BOARD_GWLCFM],[gwlcfm],[1])
 RTEMS_BSPOPTS_HELP([BOARD_GWLCFM],
 [If defined, use custom settings of for the GW_LCFM board])
@@ -98,6 +115,10 @@
 RTEMS_BSPOPTS_SET([RTEMS_BSP_I2C_EEPROM_DEVICE_PATH],[gwlcfm],['"/dev/i2c1.eeprom"'])
 RTEMS_BSPOPTS_HELP([RTEMS_BSP_I2C_EEPROM_DEVICE_PATH],[EEPROM device file path])
 
+RTEMS_BSPOPTS_SET([BOARD_PHYCORE_MPC5554],[phycore_mpc5554],[1])
+RTEMS_BSPOPTS_HELP([BOARD_PHYCORE_MPC5554],
+[If defined, use custom settings for the Phytec PhyCORE MPC5554 SOM])
+
 AC_CONFIG_FILES([Makefile
 include/bspopts.h])
 

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc:1.2 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc:1.3
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc:1.2	Wed Dec 22 08:21:03 2010
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc	Tue Aug 30 08:58:05 2011
@@ -13,8 +13,10 @@
 
 RTEMS_CPU_MODEL = mpc55xx
 
+CPU_CFLAGS_FLOAT?=-msoft-float
+
 # FIXME
-CPU_CFLAGS = -mcpu=8540 -meabi -msdata -fno-common -msoft-float \
+CPU_CFLAGS = -mcpu=8540 -meabi -msdata -fno-common $(CPU_CFLAGS_FLOAT) \
     -D__ppc_generic -mstrict-align
 
 CFLAGS_OPTIMIZE_V = -O2 -g -fno-keep-inline-functions

diff -u /dev/null rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/phycore_mpc5554.cfg:1.1
--- /dev/null	Tue Aug 30 09:11:44 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/phycore_mpc5554.cfg	Tue Aug 30 08:58:05 2011
@@ -0,0 +1,16 @@
+##
+#
+# @file
+#
+# @ingroup mpc55xx_config
+#
+# @brief configuration file for the Phytec PhyCORE MPC5554
+#
+
+RTEMS_LINKCMDS=linkcmds.phycore_mpc5554
+
+ifeq ($(PPC_USE_SPE),1)
+CPU_CFLAGS_FLOAT=-mfloat-gprs=single -mspe
+endif
+
+include $(RTEMS_ROOT)/make/custom/mpc55xx.inc

diff -u /dev/null rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c:1.1
--- /dev/null	Tue Aug 30 09:11:44 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c	Tue Aug 30 08:58:05 2011
@@ -0,0 +1,167 @@
+/*
+ *  $Id$
+ */
+
+#include <mpc55xx/mpc55xx.h>
+#include <mpc55xx/regs.h>
+
+#include <rtems.h>
+
+#include <bsp.h>
+
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+#include <libcpu/powerpc-utility.h>
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/irq-extension.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <libchip/smc91111exp.h>
+
+
+
+/* The SMC91111 on the MPC5554SOM is IRQ2.
+ */
+#define SMC91111_BASE_ADDR (void*)0x22000300
+#define SMC91111_BASE_IRQ  MPC55XX_IRQ_SIU_EXTERNAL_2
+#define SMC91111_BASE_PIO  4
+
+extern rtems_isr lan91cxx_interrupt_handler(rtems_vector_number v);
+
+static const union SIU_EISR_tag clear_eisr_2 = {.B.EIF2 = 1};
+
+static void rtems_smc91111_interrupt_wrapper(rtems_vector_number v, void *arg)
+{
+    /* Clear external interrupt status */
+
+    SIU.EISR = clear_eisr_2;
+
+    lan91cxx_interrupt_handler(v);
+
+}
+
+scmv91111_configuration_t mpc5554_scmv91111_configuration = {
+  SMC91111_BASE_ADDR, /* base address */ 
+  SMC91111_BASE_IRQ,  /* vector number */ 
+  SMC91111_BASE_PIO,  /* XXX: What's this? */ 
+  100,                /* 100b */
+  1,                  /* fulldx */
+  1,                  /* autoneg */
+  "SMC91111",
+  RTEMS_INTERRUPT_UNIQUE,
+  rtems_smc91111_interrupt_wrapper,
+  (void *)0
+};
+
+int _rtems_smc91111_driver_attach(
+  struct rtems_bsdnet_ifconfig *config,
+  scmv91111_configuration_t    *scm_config
+);
+
+/*
+ * Attach an SMC91111 driver to the system
+ */
+int rtems_smc91111_driver_attach_mpc5554(struct rtems_bsdnet_ifconfig *config)
+{
+  /* Configure IRQ2 (GPIO pin 211) is set up properly:
+   * Secondary, Alternate, Input.
+   */
+  static const union SIU_PCR_tag irq_input_pcr = {
+      .B.PA = 2,     /* Alternate function 1 */
+      .B.OBE = 0,
+      .B.IBE = 1,    /* Input Buffer Enable */
+      .B.DSC = 0,
+      .B.ODE = 0,
+      .B.HYS = 1,
+      .B.SRC = 3,    /* Maximum slew rate */
+      .B.WPE = 0,    /* Disable weak pullup/pulldown */
+      .B.WPS = 1     /* Specify weak pullup?  But it isn't enabled! */
+    };
+
+    union SIU_ORER_tag orer = MPC55XX_ZERO_FLAGS;
+    union SIU_DIRER_tag direr = MPC55XX_ZERO_FLAGS;
+    union SIU_IREER_tag ireer = MPC55XX_ZERO_FLAGS;
+    union SIU_IFEER_tag ifeer = MPC55XX_ZERO_FLAGS;
+    union SIU_IDFR_tag idfr = MPC55XX_ZERO_FLAGS;
+    union SIU_DIRSR_tag dirsr = MPC55XX_ZERO_FLAGS;
+    rtems_interrupt_level level;
+
+#define MPC55XX_EBI_CS_2_BR 0x22000003
+#define MPC55XX_EBI_CS_2_OR 0xff000010
+#if MPC55XX_EBI_CS_2_BR
+    static const union SIU_PCR_tag primary_50pf_weak_pullup = {                 /* 0x4c3 */
+        .B.PA = 1,
+        .B.DSC = 3,
+        .B.WPE = 1,
+        .B.WPS = 1
+    };
+    EBI.CS[2].BR.R = MPC55XX_EBI_CS_2_BR;
+    EBI.CS[2].OR.R = MPC55XX_EBI_CS_2_OR;
+    SIU.PCR[2] = primary_50pf_weak_pullup;
+#endif
+
+    SIU.PCR[211] = irq_input_pcr;
+
+    /* XXX These should be using bit set and bit clear instructions */
+
+    /* DMA/Interrupt Request Select */
+    rtems_interrupt_disable(level);
+    dirsr.R = SIU.DIRSR.R;
+    dirsr.B.DIRS2 = 0;                  /* Select interrupt not DMA */
+    SIU.DIRSR.R = dirsr.R;
+    rtems_interrupt_enable(level);
+
+    /* Overrun Request Enable */
+    rtems_interrupt_disable(level);
+    orer.R = SIU.ORER.R;
+    orer.B.ORE2 = 0;                    /* Disable overruns. */
+    SIU.ORER.R = orer.R;
+    rtems_interrupt_enable(level);
+
+    /* IRQ Rising-Edge Enable */
+    rtems_interrupt_disable(level);
+    ireer.R = SIU.IREER.R;
+    ireer.B.IREE2 = 1;              /* Enable rising edge. */
+    SIU.IREER.R = ireer.R;
+    rtems_interrupt_enable(level);
+
+    /* IRQ Falling-Edge Enable */
+    rtems_interrupt_disable(level);
+    ifeer.R = SIU.IFEER.R;
+    ifeer.B.IFEE2 = 0;              /* Disable falling edge. */
+    SIU.IFEER.R = ifeer.R;
+    rtems_interrupt_enable(level);
+
+    /* IRQ Digital Filter */
+    rtems_interrupt_disable(level);
+    idfr.R = SIU.IDFR.R;
+    idfr.B.DFL = 0;                 /* Minimal digital filter. */
+    SIU.IDFR.R = idfr.R;
+    rtems_interrupt_enable(level);
+
+    /* Clear external interrupt status */
+    SIU.EISR = clear_eisr_2;
+
+    /* DMA/Interrupt Request Enable */
+    rtems_interrupt_disable(level);
+    direr.R = SIU.DIRER.R;
+    direr.B.EIRE2 = 1;              /* Enable. */
+    SIU.DIRER.R = direr.R;
+    rtems_interrupt_enable(level);
+
+    return _rtems_smc91111_driver_attach(config,&mpc5554_scmv91111_configuration);
+};

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am:1.10 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am:1.11
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am:1.10	Wed Dec 29 04:54:57 2010
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am	Tue Aug 30 08:58:05 2011
@@ -57,6 +57,10 @@
 	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.gwlcfm
 PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.gwlcfm
 
+$(PROJECT_LIB)/linkcmds.phycore_mpc5554: startup/linkcmds.phycore_mpc5554 $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.phycore_mpc5554
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.phycore_mpc5554
+
 $(PROJECT_LIB)/linkcmds.mpc5566evb: startup/linkcmds.mpc5566evb $(PROJECT_LIB)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.mpc5566evb
 PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.mpc5566evb

diff -u /dev/null rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/linkcmds.phycore_mpc5554:1.1
--- /dev/null	Tue Aug 30 09:11:44 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/linkcmds.phycore_mpc5554	Tue Aug 30 08:58:05 2011
@@ -0,0 +1,39 @@
+/*
+ * Debug RAM is the top 4MB of external RAM and is swapped with the
+ * FLASH for development.
+ */
+MEMORY
+{
+	ROM (RX)       : ORIGIN = 0x00000000, LENGTH = 2M
+    RAM (AIW)      : ORIGIN = 0x40000000, LENGTH = 64K
+	RAM_EXT (AIW)  : ORIGIN = 0x21000000, LENGTH = 4M
+	DEBUG_RAM (AIW): ORIGIN = 0x21400000, LENGTH = 4M
+	NIRVANA        : ORIGIN = 0x00000000, LENGTH = 0
+}
+
+bsp_ram_start = ORIGIN (RAM);
+bsp_ram_end = ORIGIN (RAM) + LENGTH (RAM);
+bsp_ram_size = LENGTH (RAM);
+
+bsp_rom_start = ORIGIN (ROM);
+bsp_rom_end = ORIGIN (ROM) + LENGTH (ROM);
+bsp_rom_size = LENGTH (ROM);
+
+bsp_external_ram_start = ORIGIN (RAM_EXT);
+bsp_external_ram_end = ORIGIN (RAM_EXT) + LENGTH (RAM_EXT);
+bsp_external_ram_size = LENGTH (RAM_EXT);
+
+bsp_debug_ram_start = ORIGIN (DEBUG_RAM);
+bsp_debug_ram_end = ORIGIN (DEBUG_RAM) + LENGTH (DEBUG_RAM);
+bsp_debug_ram_size = LENGTH (DEBUG_RAM);
+
+bsp_section_align = 32;
+
+REGION_ALIAS ("REGION_TEXT",      ROM);
+REGION_ALIAS ("REGION_VECTORS",   RAM);
+REGION_ALIAS ("REGION_DATA",      RAM);
+REGION_ALIAS ("REGION_BSS",       RAM_EXT);
+
+INCLUDE linkcmds.base
+
+bsp_workspace_start = bsp_section_bss_end;

diff -u rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S:1.8 rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S:1.9
--- rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S:1.8	Tue Jun  7 08:30:47 2011
+++ rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S	Tue Aug 30 08:58:05 2011
@@ -29,6 +29,10 @@
 #include <bspopts.h>
 	
 .section ".bsp_start_text", "ax"
+#ifdef MPC55XX_BOOTFLAGS
+PUBLIC_VAR (mpc55xx_bootflag_0)
+PUBLIC_VAR (mpc55xx_bootflag_1)
+#endif
 PUBLIC_VAR (start)
 .globl  fmpll_syncr_vals
 bam_rchw:
@@ -39,8 +43,27 @@
 	/* BAM: RCHW */
 	.int 0x005a0000
 
-	/* BAM: Address of start instruction */
-	.int 0x8
+#ifdef MPC55XX_BOOTFLAGS
+	/* BAM: Address of start instruction
+     *      We skip over the next two boot flag words to the next
+     *      64-bit aligned start address. It is 64-bit aligned
+     *      to play well with FLASH programming.
+     *      These boot flags can be set by debuggers and emulators to
+     *      customize boot.
+     *      Currently bit0 of bootflag_0 means to "skip setting up the MMU",
+     *      allowing external MMU setup in a debugger before branching
+     *      to 0x10.  This can be used e.g., to map FLASH into RAM.
+     */
+	.int 0x00000010 /* Start address is 0x10. */
+
+mpc55xx_bootflag_0:
+    .int 0xffffffff
+mpc55xx_bootflag_1:
+    .int 0xffffffff
+
+#else
+	.int 0x00000008 /* Start address is 0x08. */
+#endif
 
 /*
  * Enable time base
@@ -97,6 +120,8 @@
 .equ MAS2, 626
 .equ MAS3, 627
 
+/* Read back MMU TLB1 entry 3 (internal SRAM) and enable the cache.
+ */
 	LWI r3, 0x10030000
 	mtspr MAS0, r3
 	tlbre
@@ -110,17 +135,32 @@
  * TODO, FIXME: Set MMU for the external SRAM
  */
 
+/* Read back MMU TLB1 entry 2 (external SRAM) and set the
+ * logical address to the external RAM start.
+ */
 	LWI r3, 0x10020000
 	mtspr MAS0, r3
 	tlbre
 	LWI r4, 0xfff
 	mfspr r3, MAS3
 	and r3, r3, r4
-	LWI r4, 0x20000000
+	LA r4, bsp_external_ram_start
 	or r3, r3, r4
 	mtspr MAS3, r3
 	tlbwe
 
+/* Read back MMU TLB1 entry 1 (internal flash) and disable
+ * write access.
+ */
+	LWI r3, 0x10010000
+	mtspr MAS0, r3
+	tlbre
+	LWI r4, ~0x0000000C
+	mfspr r3, MAS3
+	and r3, r3, r4
+	mtspr MAS3, r3
+	tlbwe
+
 /*
  * Zero RAM (needed to get proper ECC)
  */


 *sh*:
2011-08-30	Peter Dufault <dufault at hda.com>

	* rtems/score/cpu.h: Add more context access functionality.  Needed to
	get GDB debugger hooks working.

M  1.168  cpukit/score/cpu/powerpc/ChangeLog
M   1.47  cpukit/score/cpu/powerpc/rtems/score/cpu.h

diff -u rtems/cpukit/score/cpu/powerpc/ChangeLog:1.167 rtems/cpukit/score/cpu/powerpc/ChangeLog:1.168
--- rtems/cpukit/score/cpu/powerpc/ChangeLog:1.167	Wed Aug 24 04:43:06 2011
+++ rtems/cpukit/score/cpu/powerpc/ChangeLog	Tue Aug 30 09:05:50 2011
@@ -1,3 +1,8 @@
+2011-08-30	Peter Dufault <dufault at hda.com>
+
+	* rtems/score/cpu.h: Add more context access functionality.  Needed to
+	get GDB debugger hooks working.
+
 2011-08-24	Sebastian Huber <sebastian.huber at embedded-brains.de>
 
 	* rtems/powerpc/registers.h: Renamed defines XER in PPC_XER, LR in

diff -u rtems/cpukit/score/cpu/powerpc/rtems/score/cpu.h:1.46 rtems/cpukit/score/cpu/powerpc/rtems/score/cpu.h:1.47
--- rtems/cpukit/score/cpu/powerpc/rtems/score/cpu.h:1.46	Thu Jul 21 09:49:47 2011
+++ rtems/cpukit/score/cpu/powerpc/rtems/score/cpu.h	Tue Aug 30 09:05:50 2011
@@ -309,11 +309,25 @@
       (_context)->gpr1 = _sp; \
     } while (0)
 
+  #define PPC_CONTEXT_GET_CR( _context ) \
+    (_context)->cr
+
+  #define PPC_CONTEXT_GET_MSR( _context ) \
+    (_context)->msr
+
   #define PPC_CONTEXT_SET_MSR( _context, _msr ) \
     do { \
       (_context)->msr = _msr; \
     } while (0)
 
+  #define PPC_CONTEXT_FIRST_SAVED_GPR 13
+
+  #define PPC_CONTEXT_GET_FIRST_SAVED( _context ) \
+    (_context)->gpr13
+
+  #define PPC_CONTEXT_GET_PC( _context ) \
+    (_context)->pc
+
   #define PPC_CONTEXT_SET_PC( _context, _pc ) \
     do { \
       (_context)->pc = _pc; \
@@ -361,11 +375,25 @@
       PPC_CONTEXT_FIELD( _context, PPC_CONTEXT_OFFSET_SP ) = _sp; \
     } while (0)
 
+  #define PPC_CONTEXT_GET_CR( _context ) \
+    PPC_CONTEXT_FIELD( _context, PPC_CONTEXT_OFFSET_CR )
+
+  #define PPC_CONTEXT_GET_MSR( _context ) \
+    PPC_CONTEXT_FIELD( _context, PPC_CONTEXT_OFFSET_MSR )
+
   #define PPC_CONTEXT_SET_MSR( _context, _msr ) \
     do { \
       PPC_CONTEXT_FIELD( _context, PPC_CONTEXT_OFFSET_MSR ) = _msr; \
     } while (0)
 
+  #define PPC_CONTEXT_FIRST_SAVED_GPR 14
+
+  #define PPC_CONTEXT_GET_FIRST_SAVED( _context ) \
+    PPC_CONTEXT_FIELD( _context, PPC_CONTEXT_OFFSET_GPR14 )
+
+  #define PPC_CONTEXT_GET_PC( _context ) \
+    PPC_CONTEXT_FIELD( _context, PPC_CONTEXT_OFFSET_LR )
+
   #define PPC_CONTEXT_SET_PC( _context, _pc ) \
     do { \
       PPC_CONTEXT_FIELD( _context, PPC_CONTEXT_OFFSET_LR ) = _pc; \



--

Generated by Deluxe Loginfo [http://www.codewiz.org/projects/index.html#loginfo] 2.122 by Bernardo Innocenti <bernie at develer.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/vc/attachments/20110830/b3953b85/attachment.html>


More information about the vc mailing list