summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mbx8xx/startup
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mbx8xx/startup')
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am42
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c193
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache202
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c535
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds259
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c132
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c44
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S383
8 files changed, 1790 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am b/c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am
new file mode 100644
index 0000000000..3b2eb17f8d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am
@@ -0,0 +1,42 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+VPATH = @srcdir@:@srcdir@/../../../shared
+
+PGM = $(ARCH)/startup.rel
+
+C_FILES = bspclean.c bsplibc.c bsppost.c bspstart.c bootcard.c imbx8xx.c main.c \
+ mmutlbtab.c sbrk.c setvec.c gnatinstallhandler.c
+C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+
+S_FILES = start.s
+S_O_FILES = $(S_FILES:%.s=$(ARCH)/%.o)
+
+OBJS = $(C_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(PGM): $(OBJS)
+ $(make-rel)
+
+$(PROJECT_RELEASE)/lib/linkcmds: linkcmds
+ $(INSTALL_DATA) $< $@
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/linkcmds
+
+all-local: $(ARCH) $(OBJS) $(PGM) $(TMPINSTALL_FILES)
+
+.PRECIOUS: $(PGM)
+
+EXTRA_DIST = bspstart.c imbx8xx.c linkcmds mmutlbtab.c setvec.c
+
+include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c
new file mode 100644
index 0000000000..2180df9b44
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c
@@ -0,0 +1,193 @@
+/* bspstart.c
+ *
+ * This set of routines starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * Modifications for MBX860:
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include <libcsupport.h>
+
+#include <string.h>
+
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+/*
+ * The original table from the application (in ROM) and our copy of it with
+ * some changes. Configuration is defined in <confdefs.h>. Make sure that
+ * our configuration tables are uninitialized so that they get allocated in
+ * the .bss section (RAM).
+ */
+extern rtems_configuration_table Configuration;
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+/*
+ * Use the shared implementations of the following routines.
+ * Look in rtems/c/src/lib/libbsp/shared/bsppost.c and
+ * rtems/c/src/lib/libbsp/shared/bsplibc.c.
+ */
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ * bsp_pretasking_hook
+ *
+ * Called when RTEMS initialization is complete but before interrupts and
+ * tasking are enabled. Used to setup libc and install any BSP extensions.
+ *
+ * Must not use libc (to do io) from here, since drivers are not yet
+ * initialized.
+ *
+ * Installed in the rtems_cpu_table defined in
+ * rtems/c/src/exec/score/cpu/m68k/cpu.h in main() below. Called from
+ * rtems_initialize_executive() defined in rtems/c/src/exec/sapi/src/init.c
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_pretasking_hook(void)
+{
+ /*
+ * These are assigned addresses in the linkcmds file for the BSP. This
+ * approach is better than having these defined as manifest constants and
+ * compiled into the kernel, but it is still not ideal when dealing with
+ * multiprocessor configuration in which each board as a different memory
+ * map. A better place for defining these symbols might be the makefiles.
+ * Consideration should also be given to developing an approach in which
+ * the kernel and the application can be linked and burned into ROM
+ * independently of each other.
+ */
+ extern unsigned char _HeapStart;
+ extern unsigned char _HeapEnd;
+
+ bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
+
+#ifdef STACK_CHECKER_ON
+ /*
+ * Initialize the stack bounds checker
+ * We can either turn it on here or from the app.
+ */
+
+ Stack_check_Initialize();
+#endif /* STACK_CHECKER_ON */
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+
+/*
+ * bsp_start()
+ *
+ * Board-specific initialization code. Called from the generic boot_card()
+ * function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
+ * does some of the board independent initialization. It is called from the
+ * MBX8xx entry point _start() defined in
+ * rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
+ *
+ * _start() has set up a stack, has zeroed the .bss section, has turned off
+ * interrupts, and placed the processor in the supervisor mode. boot_card()
+ * has left the processor in that state when bsp_start() was called.
+ *
+ * RUNS WITH ADDRESS TRANSLATION AND CACHING TURNED OFF!
+ * ASSUMES THAT THE VIRTUAL ADDRESSES WILL BE IDENTICAL TO THE PHYSICAL
+ * ADDRESSES. Software-controlled address translation would be required
+ * otherwise.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_start(void)
+{
+ extern void *_WorkspaceBase;
+
+ mmu_init();
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+ #ifdef INSTRUCTION_CACHE_ENABLE
+ rtems_enable_inst_cache();
+ #endif
+
+ #ifdef DATA_CACHE_ENABLE
+ rtems_enable_data_cache();
+ #endif
+
+ /*
+ * Allocate the memory for the RTEMS Work Space. This can come from
+ * a variety of places: hard coded address, malloc'ed from outside
+ * RTEMS world (e.g. simulator or primitive memory manager), or (as
+ * typically done by stock BSPs) by subtracting the required amount
+ * of work space from the last physical address on the CPU board.
+ *
+ * In this case, the memory is not malloc'ed. It is just
+ * "pulled from the air".
+ */
+ BSP_Configuration.work_space_start = (void *)&_WorkspaceBase;
+
+ /*
+ * initialize the CPU table for this BSP
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ if( Cpu_table.interrupt_stack_size < 4 * 1024 )
+ Cpu_table.interrupt_stack_size = 4 * 1024;
+
+ Cpu_table.clicks_per_usec = 1; /* for 4MHz extclk */
+ Cpu_table.serial_per_sec = 10000000;
+ Cpu_table.serial_external_clock = 1;
+ Cpu_table.serial_xon_xoff = 0;
+ Cpu_table.serial_cts_rts = 1;
+ Cpu_table.serial_rate = 9600;
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ Cpu_table.clock_speed = 50000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#else
+ Cpu_table.clock_speed = 40000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#endif
+
+ /*
+ * Call this in case we use TERMIOS for console I/O
+ */
+ m8xx_uart_reserve_resources( &BSP_Configuration );
+
+ m8xx.scc2.sccm=0;
+ m8xx.scc2p.rbase=0;
+ m8xx.scc2p.tbase=0;
+ m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache
new file mode 100644
index 0000000000..055e84ad27
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache
@@ -0,0 +1,202 @@
+/* bspstart.c
+ *
+ * This set of routines starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * Modifications for MBX860:
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include <libcsupport.h>
+
+#include <string.h>
+
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+/*
+ * The original table from the application (in ROM) and our copy of it with
+ * some changes. Configuration is defined in <confdefs.h>. Make sure that
+ * our configuration tables are uninitialized so that they get allocated in
+ * the .bss section (RAM).
+ */
+extern rtems_configuration_table Configuration;
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+/*
+ * Use the shared implementations of the following routines.
+ * Look in rtems/c/src/lib/libbsp/shared/bsppost.c and
+ * rtems/c/src/lib/libbsp/shared/bsplibc.c.
+ */
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ * bsp_pretasking_hook
+ *
+ * Called when RTEMS initialization is complete but before interrupts and
+ * tasking are enabled. Used to setup libc and install any BSP extensions.
+ *
+ * Must not use libc (to do io) from here, since drivers are not yet
+ * initialized.
+ *
+ * Installed in the rtems_cpu_table defined in
+ * rtems/c/src/exec/score/cpu/m68k/cpu.h in main() below. Called from
+ * rtems_initialize_executive() defined in rtems/c/src/exec/sapi/src/init.c
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_pretasking_hook(void)
+{
+ /*
+ * These are assigned addresses in the linkcmds file for the BSP. This
+ * approach is better than having these defined as manifest constants and
+ * compiled into the kernel, but it is still not ideal when dealing with
+ * multiprocessor configuration in which each board as a different memory
+ * map. A better place for defining these symbols might be the makefiles.
+ * Consideration should also be given to developing an approach in which
+ * the kernel and the application can be linked and burned into ROM
+ * independently of each other.
+ */
+ extern unsigned char _HeapStart;
+ extern unsigned char _HeapEnd;
+
+ bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
+
+#ifdef STACK_CHECKER_ON
+ /*
+ * Initialize the stack bounds checker
+ * We can either turn it on here or from the app.
+ */
+
+ Stack_check_Initialize();
+#endif /* STACK_CHECKER_ON */
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+
+/*
+ * bsp_start()
+ *
+ * Board-specific initialization code. Called from the generic boot_card()
+ * function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
+ * does some of the board independent initialization. It is called from the
+ * MBX8xx entry point _start() defined in
+ * rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
+ *
+ * _start() has set up a stack, has zeroed the .bss section, has turned off
+ * interrupts, and placed the processor in the supervisor mode. boot_card()
+ * has left the processor in that state when bsp_start() was called.
+ *
+ * RUNS WITH ADDRESS TRANSLATION AND CACHING TURNED OFF!
+ * ASSUMES THAT THE VIRTUAL ADDRESSES WILL BE IDENTICAL TO THE PHYSICAL
+ * ADDRESSES. Software-controlled address translation would be required
+ * otherwise.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_start(void)
+{
+ extern void *_WorkspaceBase;
+ unsigned32 r1;
+
+ mmu_init();
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+ #ifdef INSTRUCTION_CACHE_ENABLE
+ r1 = M8xx_CACHE_CMD_ENABLE;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ #endif
+
+ /*
+ * Warning: EPPCBug 1.1 chokes to death if the data cache is turned on.
+ * Set DATA_CACHE_ENABLE to zero in mbx8xx.cfg if EPPCBUG is used.
+ */
+ #ifdef DATA_CACHE_ENABLE
+ r1 = M8xx_CACHE_CMD_ENABLE;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ #endif
+
+ /*
+ * Allocate the memory for the RTEMS Work Space. This can come from
+ * a variety of places: hard coded address, malloc'ed from outside
+ * RTEMS world (e.g. simulator or primitive memory manager), or (as
+ * typically done by stock BSPs) by subtracting the required amount
+ * of work space from the last physical address on the CPU board.
+ *
+ * In this case, the memory is not malloc'ed. It is just
+ * "pulled from the air".
+ */
+ BSP_Configuration.work_space_start = (void *)&_WorkspaceBase;
+
+ /*
+ * initialize the CPU table for this BSP
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ if( Cpu_table.interrupt_stack_size < 4 * 1024 )
+ Cpu_table.interrupt_stack_size = 4 * 1024;
+
+ Cpu_table.clicks_per_usec = 1; /* for 4MHz extclk */
+ Cpu_table.serial_per_sec = 10000000;
+ Cpu_table.serial_external_clock = 1;
+ Cpu_table.serial_xon_xoff = 0;
+ Cpu_table.serial_cts_rts = 1;
+ Cpu_table.serial_rate = 9600;
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ Cpu_table.clock_speed = 50000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#else
+ Cpu_table.clock_speed = 40000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#endif
+
+ /*
+ * Call this in case we use TERMIOS for console I/O
+ */
+ m8xx_uart_reserve_resources( &BSP_Configuration );
+
+ m8xx.scc2.sccm=0;
+ m8xx.scc2p.rbase=0;
+ m8xx.scc2p.tbase=0;
+ m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c
new file mode 100644
index 0000000000..423f933079
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c
@@ -0,0 +1,535 @@
+/*
+ * imbx8xx.c
+ *
+ * MBX860/MBX821 initialization routines.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#include <bsp.h>
+
+/*
+ * EPPCBug rev 1.1 is stupid. It clears the interrupt mask register
+ * in the SIU when it takes control, but does not restore it before
+ * returning control to the program. We thus keep a copy of the
+ * register, and restore it from gdb using the hook facilities.
+ *
+ * We arrange for simask_copy to be initialized to zero so that
+ * it resides in the .data section. This avoids having gdb set
+ * the mask to crud before we get to initialize explicitly. Of
+ * course, the code will not be safely restartable, but then again,
+ * a lot of the library code isn't either, so there!
+ */
+unsigned32 simask_copy = 0;
+
+/*
+ * The memory controller's UPMA Ram array values.
+ * The values in table 2-6 and 2-7 in the "MBX Series Embedded
+ * Controller Programmer's Reference Guide", part number MBXA/PG2,
+ * differ from the ones in the older MBX Programmer's Guide, part
+ * number MBXA/PG1. We are assuming that the values in MBXA/PG1
+ * are for the older MBX boards whose part number does not have
+ * the "B" suffix, but we have discovered that the values from
+ * MBXA/PG2 work better, even for the older boards.
+ *
+ * THESE VALUES HAVE ONLY BEEN VERIFIED FOR THE MBX821-001 and
+ * MBX860-002. USE WITH CARE!
+ *
+ * NOTE: The MBXA/PG2 manual lists the clock speed of the MBX821_001B
+ * as being 50 MHz, while the MBXA/IH2.1 manual lists it as 40 MHz.
+ * We think the MBX821_001B is an entry level board and thus is 50 MHz,
+ */
+static unsigned32 upmaTable[64] = {
+
+#if ( defined(mbx860_001b) || \
+ defined(mbx821_001b) || \
+ defined(mbx821_001) )
+
+ /* 50 MHz MBX */
+ /*
+ * Note: For the mbx821_001, the following values (from the
+ * MBXA/PG2 manual) work better than, but are different
+ * from those published in the original MBXA/PG1 manual and
+ * initialized by EPPCBug 1.1. In particular, the original
+ * burst-write values do not work! Also, the following values
+ * facilitate higher performance.
+ */
+ /* DRAM 60ns - single read. (offset 0x00 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
+ 0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst read. (offset 0x08 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x00AF0C04,
+ 0x07AF0C08, 0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08,
+ 0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08, 0x0CAF0C04,
+ 0x10AF0C04, 0xF0AFC000, 0xF3BF4805, 0xFFFFC005,
+
+ /* DRAM 60ns - single write. (offset 0x18 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
+ 0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst write. (offset 0x20 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Refresh 60ns. (offset 0x30 in UPM RAM) */
+ 0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+ 0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Exception. (offset 0x3c in UPM RAM) */
+ 0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007
+
+#elif ( defined(mbx860_002b) || \
+ defined(mbx860_003b) || \
+ defined(mbx860_004b) || \
+ defined(mbx860_005b) || \
+ defined(mbx860_006b) || \
+ defined(mbx821_002b) || \
+ defined(mbx821_003b) || \
+ defined(mbx821_004b) || \
+ defined(mbx821_005b) || \
+ defined(mbx821_006b) || \
+ defined(mbx860_001) || \
+ defined(mbx860_002) || \
+ defined(mbx860_003) || \
+ defined(mbx860_004) || \
+ defined(mbx860_005) || \
+ defined(mbx821_002) || \
+ defined(mbx821_003) || \
+ defined(mbx821_004) || \
+ defined(mbx821_005) )
+
+ /* 40 MHz MBX */
+ /*
+ * Note: For the older MBX models (i.e. without the "b"
+ * suffix, e.g. mbx860_001), the following values (from the
+ * MBXA/PG2 manual) work better than, but are different
+ * from those published in the original MBXA/PG1 manual and
+ * initialized by EPPCBug 1.1. In particular, the following
+ * burst-read and burst-write values facilitate higher
+ * performance.
+ */
+ /* DRAM 60ns - single read. (offset 0x00 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
+ 0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst read. (offset 0x08 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
+ 0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
+ 0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - single write. (offset 0x18 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF4004, 0x0CFF0C00, 0x33FF4804,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst write. (offset 0x20 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF4004, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Refresh 60ns. (offset 0x30 in UPM RAM) */
+ 0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+ 0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Exception. (offset 0x3c in UPM RAM) */
+ 0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007
+#else
+#error "MBX board model not specified."
+#endif
+};
+
+/*
+ * Initialize MBX8xx
+ */
+void _InitMBX8xx (void)
+{
+ register unsigned32 r1, i;
+ extern unsigned32 simask_copy;
+
+ /*
+ * Get the SIU interrupt mask.
+ */
+ simask_copy = m8xx.simask;
+
+ /*
+ * Initialize the Debug Enable Register (DER) to an appropriate
+ * value for EPPCBug debugging.
+ * (This value should also work for BDM debugging.)
+ */
+ r1 = 0x70C67C07; /* All except EXTIE, ALIE, DECIE */
+ _mtspr( M8xx_DER, r1 );
+
+ /*
+ * Initialize the Instruction Support Control Register (ICTRL) to a
+ * an appropriate value for normal operation. A different value,
+ * such as 0x0, may be more appropriate for debugging.
+ */
+ r1 = 0x00000007;
+ _mtspr( M8xx_ICTRL, r1 );
+
+ /*
+ * Disable and invalidate the instruction and data caches.
+ */
+ r1 = M8xx_CACHE_CMD_DISABLE;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_UNLOCKALL;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+
+ r1 = M8xx_CACHE_CMD_DISABLE;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_UNLOCKALL;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+
+ /*
+ * Initialize the Internal Memory Map Register (IMMR)
+ *
+ * Use the value in MBXA/PG2, which is also the value that EPPC-Bug
+ * programmed into our boards. The alternative is the value in
+ * MBXA/PG1: 0xFFA00000. This value might well depend on the revision
+ * of the firmware.
+ *
+ * THIS VALUE IS ALSO DECLARED IN THE linkcmds FILE and mmutlbtab.c!
+ */
+ r1 = 0xFA200000;
+ _mtspr( M8xx_IMMR, r1 );
+
+ /*
+ * Initialize the SIU Module Configuration Register (SIUMCR)
+ * m8xx.siumcr = 0x00602900, the default MBX and firmware value.
+ */
+ m8xx.siumcr = M8xx_SIUMCR_EARP0 | M8xx_SIUMCR_DBGC3 | M8xx_SIUMCR_DBPC0 |
+ M8xx_SIUMCR_DPC | M8xx_SIUMCR_MLRC2 | M8xx_SIUMCR_SEME;
+
+ /*
+ * Initialize the System Protection Control Register (SYPCR).
+ * The SYPCR can only be written once after Reset.
+ * - Enable bus monitor
+ * - Disable software watchdog timer
+ * m8xx.sypcr = 0xFFFFFF88, the default MBX and firmware value.
+ */
+ m8xx.sypcr = M8xx_SYPCR_SWTC(0xFFFF) | M8xx_SYPCR_BMT(0xFF) |
+ M8xx_SYPCR_BME | M8xx_SYPCR_SWF;
+
+ /* Initialize the SIU Interrupt Edge Level Mask Register (SIEL) */
+ m8xx.siel = 0xAAAA0000; /* Default MBX and firmware value. */
+
+ /* Initialize the Transfer Error Status Register (TESR) */
+ m8xx.tesr = 0xFFFFFFFF; /* Default firmware value. */
+
+ /* Initialize the SDMA Configuration Register (SDCR) */
+ m8xx.sdcr = 0x00000001; /* Default firmware value. */
+
+ /*
+ * Initialize the Timebase Status and Control Register (TBSCR)
+ * m8xx.tbscr = 0x00C3, default MBX and firmware value.
+ */
+ m8xx.tbscrk = M8xx_UNLOCK_KEY; /* unlock TBSCR */
+ m8xx.tbscr = M8xx_TBSCR_REFA | M8xx_TBSCR_REFB |
+ M8xx_TBSCR_TBF | M8xx_TBSCR_TBE;
+
+ /* Initialize the Real-Time Clock Status and Control Register (RTCSC) */
+ m8xx.rtcsk = M8xx_UNLOCK_KEY; /* unlock RTCSC */
+ m8xx.rtcsc = 0x00C3; /* Default MBX and firmware value. */
+
+ /* Unlock other Real-Time Clock registers */
+ m8xx.rtck = M8xx_UNLOCK_KEY; /* unlock RTC */
+ m8xx.rtseck = M8xx_UNLOCK_KEY; /* unlock RTSEC */
+ m8xx.rtcalk = M8xx_UNLOCK_KEY; /* unlock RTCAL */
+
+ /* Initialize the Periodic Interrupt Status and Control Register (PISCR) */
+ m8xx.piscrk = M8xx_UNLOCK_KEY; /* unlock PISCR */
+ m8xx.piscr = 0x0083; /* Default MBX and firmware value. */
+
+ /* Initialize the System Clock and Reset Control Register (SCCR)
+ * Set the clock sources and division factors:
+ * Timebase Source is GCLK2 / 16
+ * Real-Time Clock Select is EXTCLK (4.192MHz)
+ * Real-Time Clock Divide is /4
+ */
+ m8xx.sccrk = M8xx_UNLOCK_KEY; /* unlock SCCR */
+ m8xx.sccr = 0x02800000; /* for MBX860/MBX821 */
+
+ /* Initialize the PLL, Low-Power, and Reset Control Register (PLPRCR) */
+ /* - set the clock speed and set normal power mode */
+ m8xx.plprck = M8xx_UNLOCK_KEY; /* unlock PLPRCR */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.plprcr = 0x5F500000;
+#else
+ m8xx.plprcr = 0x4C400000;
+#endif
+ /* Unlock the timebase and decrementer registers. */
+ m8xx.tbk = M8xx_UNLOCK_KEY;
+
+ /*
+ * Initialize decrementer register to a large value to
+ * guarantee that a decrementer interrupt will not be
+ * generated before the kernel is fully initialized.
+ */
+ r1 = 0x7FFFFFFF;
+ _mtspr( M8xx_DEC, r1 );
+
+ /* Initialize the timebase register (TB is 64 bits) */
+ r1 = 0x00000000;
+ _mtspr( M8xx_TBU_WR, r1 );
+ _mtspr( M8xx_TBL_WR, r1 );
+
+ /*
+ * Memory Controller Initialization
+ */
+
+ /*
+ * User Programmable Machine A (UPMA) Initialization
+ *
+ * If this initialization code is running from DRAM, it is very
+ * dangerous to change the value of any UPMA Ram array word from
+ * what the firmware (EPPCBug) initialized it to. Thus we don't
+ * initialize UPMA if EPPCBUG_VECTORS is defined; we assume EPPCBug
+ * has done the appropriate initialization.
+ *
+ * An exception to our rule, is that, for the older MBX boards
+ * (those without the "B" suffix, e.g. MBX821-001 and MBX860-002),
+ * we do re-initialize the burst-read and burst-write values with
+ * values that are more efficient. Also, in the MBX821 case,
+ * the burst-write original values set by EPPCBug do not work!
+ * This change can be done safely because the caches have not yet
+ * been activated.
+ *
+ * The RAM array of UPMA is initialized by writing to each of
+ * its 64 32-bit RAM locations.
+ * Note: UPM register initialization should occur before
+ * initialization of the corresponding BRx and ORx registers.
+ */
+#if ( !defined(EPPCBUG_VECTORS) )
+ for( i = 0; i < 64; ++i ) {
+ m8xx.mdr = upmaTable[i];
+ m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
+ }
+#elif ( defined(mbx860_001) || \
+ defined(mbx860_002) || \
+ defined(mbx860_003) || \
+ defined(mbx860_004) || \
+ defined(mbx860_005) || \
+ defined(mbx821_001) || \
+ defined(mbx821_002) || \
+ defined(mbx821_003) || \
+ defined(mbx821_004) || \
+ defined(mbx821_005) )
+ /* Replace the burst-read and burst-write values with better ones. */
+ /* burst-read values */
+ for( i = 8; i < 24; ++i ) {
+ m8xx.mdr = upmaTable[i];
+ m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
+ }
+ /* burst-write values */
+ for( i = 32; i < 48; ++i ) {
+ m8xx.mdr = upmaTable[i];
+ m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
+ }
+#endif
+
+#if ( !defined(EPPCBUG_VECTORS) )
+ /*
+ * Initialize the memory periodic timer.
+ * Memory Periodic Timer Prescaler Register (MPTPR: 16-bit register)
+ * m8xx.mptpr = 0x0200;
+ */
+ m8xx.mptpr = M8xx_MPTPR_PTP(0x2);
+
+ /*
+ * Initialize the Machine A Mode Register (MAMR)
+ *
+ * ASSUMES THAT DIMMs ARE NOT INSTALLED!
+ *
+ * Without DIMMs:
+ * m8xx.mamr = 0x13821000 (40 MHz) or 0x18821000 (50 MHz).
+ *
+ * With DIMMs:
+ * m8xx.mamr = 0x06821000 (40 MHz) or 0x08821000 (50 MHz).
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.mamr = M8xx_MEMC_MMR_PTP(0x18) | M8xx_MEMC_MMR_PTE |
+ M8xx_MEMC_MMR_DSP(0x1) | M8xx_MEMC_MMR_G0CL(0) | M8xx_MEMC_MMR_UPWAIT;
+#else
+ m8xx.mamr = M8xx_MEMC_MMR_PTP(0x13) | M8xx_MEMC_MMR_PTE |
+ M8xx_MEMC_MMR_DSP(0x1) | M8xx_MEMC_MMR_G0CL(0) | M8xx_MEMC_MMR_UPWAIT;
+#endif
+#endif /* ! defined(EPPCBUG_VECTORS) */
+
+ /*
+ * Initialize the Base and Option Registers (BR0-BR7 and OR0-OR7)
+ * Note: For all chip selects, ORx should be programmed before BRx,
+ * except when programming the boot chip select (CS0) after hardware
+ * reset, in which case, BR0 should be programmed before OR0.
+ *
+ * MPC860/MPX821 Memory Map Summary:
+ * S-ADDR E-ADDR CS PS PE WP MS BI V DESCRIPTION
+ * FE000000 FE7FFFFF 0 32 N N GPCM Y Y Soldered FLASH Memory
+ * 00000000 00zFFFFF 1 32 N N UPMA N Y Local DRAM Memory
+ * 00X00000 0XXXXXXX 2 0 N N UPMA N N DIMM Memory - Bank #0
+ * 00X00000 0XXXXXXX 3 0 N N UPMA N N DIMM Memory - Bank #1
+ * FA000000 FA1FFFFF 4 8 N N GPCM Y Y NVRAM & BCSR
+ * 80000000 DFFFFFFF 5 32 N N GPCM Y Y PCI/ISA I/O & Memory
+ * FA210000 FA21FFFF 6 32 N N GPCM Y Y QSpan Registers
+ * FC000000 FC7FFFFF 7 8 N N GPCM Y Y Socketed FLASH Memory
+ *
+ * z = 3 for 4MB installed on the motherboard, z = F for 16M
+ *
+ * NOTE: The devices selected by CS0 and CS7 can be selected with jumper J4.
+ * This table assumes that the 32-bit soldered flash device is the boot ROM.
+ */
+
+ /*
+ * CS0 : Soldered (32-bit) Flash Memory at 0xFE000000
+ *
+ * CHANGE THIS CODE IF YOU CHANGE JUMPER J4 FROM ITS FACTORY DEFAULT SETTING!
+ * (or better yet, don't reprogram BR0 and OR0; just program BR7 and OR7 to
+ * access whatever flash device is not selected during hard reset.)
+ *
+ * MBXA/PG2 appears to lie in note 14 for table 2-4. The manual states that
+ * "EPPCBUG configures the reset flash device at the lower address, and the
+ * nonreset flash device at the higher address." If we take reset flash device
+ * to mean the boot flash memory, then the statement must mean that BR0 must
+ * point to the device at the lower address, i.e. 0xFC000000, while BR7 must
+ * point to the device at the highest address, i.e. 0xFE000000.
+ *
+ * THIS IS NOT THE CASE!
+ *
+ * The boot flash is always configured to start at 0xFE000000, and the other
+ * one to start at 0xFC000000. Changing jumper J4 only changes the width of
+ * the memory ports into these two region.
+ *
+ * BR0 = 0xFE000001
+ * Base addr [0-16] 0b11111110000000000 = 0xFE000000
+ * Address type [17-19] 0b000
+ * Port size [20-21] 0b00 = 32 bits
+ * Parity enable [22] 0b0 = disabled
+ * Write protect [23] 0b0 = r/w
+ * Machine select [24-25] 0b00 = GPCM
+ * Reserved [26-30] 0b00000
+ * Valid Bit [31] 0b1 = this bank is valid
+ * OR0 = 0xFF800930 @ 40 MHz, 0xFF800940 @ 50 MHz
+ * Address mask [0-16] 0b11111111100000000 = 0xFF800000
+ * Addr type mask [17-19] 0b000 = no address-type protection
+ * CS negation time [20] 0b1
+ * ACS [21-22] 0b00 = CS output at same time as address lines
+ * Burst inhibit [23] 0b1 = bank does not support burst accesses
+ * Cycle length [24-27] 0b0011/0b0100 = 3/4 clock cycle wait states
+ * SETA [28] 0b0 = TA generated internally
+ * Timing relaxed [29] 0b0 = not relaxed
+ * Extended hold time [30] 0b0 = not extended
+ * Reserved [31] 0b0
+ *
+ * m8xx.memc[0]._or = 0xFF800930 (40 MHz)
+ * m8xx.memc[0]._or = 0xFF800940 (50 MHz)
+ * m8xx.memc[0]._br = 0xFE000001
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.memc[0]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(4);
+#else
+ m8xx.memc[0]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
+#endif
+ m8xx.memc[0]._br = M8xx_BR_BA(0xFE000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS1 : Local DRAM Memory at 0x00000000
+ * m8xx.memc[1]._or = 0xFFC00400;
+ * m8xx.memc[1]._br = 0x00000081;
+ */
+ m8xx.memc[1]._or = M8xx_MEMC_OR_4M | M8xx_MEMC_OR_ATM(0) |
+ M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
+ m8xx.memc[1]._br = M8xx_BR_BA(0x00000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_UPMA | M8xx_MEMC_BR_V;
+
+ /*
+ * CS2 : DIMM Memory - Bank #0, not present
+ * m8xx.memc[2]._or = 0x00000400;
+ * m8xx.memc[2]._br = 0x00000080;
+ */
+ m8xx.memc[2]._or = M8xx_MEMC_OR_ATM(0) |
+ M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
+ m8xx.memc[2]._br = M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_UPMA; /* ! M8xx_MEMC_BR_V */
+
+ /*
+ * CS3 : DIMM Memory - Bank #1, not present
+ * m8xx.memc[3]._or = 0x00000400;
+ * m8xx.memc[3]._br = 0x00000080;
+ */
+ m8xx.memc[3]._or = M8xx_MEMC_OR_ATM(0) |
+ M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
+ m8xx.memc[3]._br = M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_UPMA; /* ! M8xx_MEMC_BR_V */
+
+ /*
+ * CS4 : Battery-Backed SRAM at 0xFA000000
+ * m8xx.memc[4]._or = 0xFFE00920@ 40 MHz, 0xFFE00930 @ 50 MHz
+ * m8xx.memc[4]._br = 0xFA000401;
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.memc[4]._or = M8xx_MEMC_OR_2M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
+#else
+ m8xx.memc[4]._or = M8xx_MEMC_OR_2M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(2);
+#endif
+ m8xx.memc[4]._br = M8xx_BR_BA(0xFA000000) | M8xx_BR_AT(0) | M8xx_BR_PS8 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS5 : PCI I/O and Memory at 0x80000000
+ * m8xx.memc[5]._or = 0xA0000108;
+ * m8xx.memc[5]._br = 0x80000001;
+ */
+ m8xx.memc[5]._or = 0xA0000000 | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_ACS_NORM |
+ M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(0) | M8xx_MEMC_OR_SETA;
+ m8xx.memc[5]._br = M8xx_BR_BA(0x80000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS6 : QSPAN Registers at 0xFA210000
+ * m8xx.memc[6]._or = 0xFFFF0108;
+ * m8xx.memc[6]._br = 0xFA210001;
+ */
+ m8xx.memc[6]._or = M8xx_MEMC_OR_64K | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_ACS_NORM |
+ M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(0) | M8xx_MEMC_OR_SETA;
+ m8xx.memc[6]._br = M8xx_BR_BA(0xFA210000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS7 : Socketed (8-bit) Flash at 0xFC000000
+ * m8xx.memc[7]._or = 0xFF800930 @ 40 MHz, 0xFF800940 @ 50 MHz
+ * m8xx.memc[7]._br = 0xFC000401;
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.memc[7]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(4);
+#else
+ m8xx.memc[7]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
+#endif
+ m8xx.memc[7]._br = M8xx_BR_BA(0xFC000000) | M8xx_BR_AT(0) | M8xx_BR_PS8 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+}
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds b/c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds
new file mode 100644
index 0000000000..565e7f175b
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds
@@ -0,0 +1,259 @@
+/*
+ * This file contains directives for the GNU linker that are specific
+ * to the MBX860-2 board.
+ *
+ * $Id$
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+ENTRY(start)
+
+/*
+ * Declare some sizes.
+ * XXX: The assignment of ". += XyzSize;" fails in older gld's if the
+ * number used there is not constant. If this happens to you, edit
+ * the lines marked XXX below to use a constant value.
+ */
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0x100000; /* 1M Heap */
+StackSize = DEFINED(StackSize) ? StackSize : 0x1000;
+
+MEMORY
+ {
+ ram : org = 0x0, l = 4M
+ nvram : org = 0xfa000000, l = 32K
+ dpram : org = 0xfa200000, l = 16K
+ flash : org = 0xfc000000, l = 2M
+ immr : org = 0xfa200000, l = 16K
+ }
+
+
+SECTIONS
+{
+ /*
+ * If the vectors are specified statically rather than created at run time,
+ * accumulate them starting at VMA 0x0.
+ */
+ .vectors :
+ {
+ *(.vectors)
+ } >ram
+
+ /*
+ * The stack will live in this area - between the vectors and
+ * the text section.
+ */
+
+ .text 0x10000:
+ {
+ /* Read-only sections, merged into text segment: */
+
+ text.start = .;
+
+ /* Entry point is the .entry section */
+ *(.entry)
+ *(.entry2)
+
+ /* Actual code */
+ *(.text)
+ *(.text.*)
+
+ /* C++ constructors/destructors */
+ *(.gnu.linkonce.t*)
+
+ /* Initialization and finalization code.
+ *
+ * Various files can provide initialization and finalization functions.
+ * The bodies of these functions are in .init and .fini sections. We
+ * accumulate the bodies here, and prepend function prologues from
+ * ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
+ * first; ecrtn.o must be linked last. Because these are wildcards, it
+ * doesn't matter if the user does not actually link against ecrti.o and
+ * ecrtn.o; the linker won't look for a file to match a wildcard. The
+ * wildcard also means that it doesn't matter which directory ecrti.o
+ * and ecrtn.o are in.
+ */
+ PROVIDE (_init = .);
+ *ecrti.o(.init)
+ *(.init)
+ *ecrtn.o(.init)
+
+ PROVIDE (_fini = .);
+ *ecrti.o(.fini)
+ *(.fini)
+ *ecrtn.o(.init)
+
+ /*
+ * C++ constructors and destructors for static objects.
+ * PowerPC EABI does not use crtstuff yet, so we build "old-style"
+ * constructor and destructor lists that begin with the list lenght
+ * end terminate with a NULL entry.
+ */
+
+ PROVIDE (__CTOR_LIST__ = .);
+ /* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.ctors)
+ *(.ctors)
+ *crtend.o(.ctors)
+ LONG(0)
+ PROVIDE (__CTOR_END__ = .);
+
+ PROVIDE (__DTOR_LIST__ = .);
+ /* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.dtors)
+ *(.dtors)
+ *crtend.o(.dtors)
+ LONG(0)
+ PROVIDE (__DTOR_END__ = .);
+
+ /* Exception frame info */
+ *(.eh_frame)
+
+ /* Miscellaneous read-only data */
+ _rodata_start = . ;
+ *(.gnu.linkonce.r*)
+ *(.lit)
+ *(.shdata)
+ *(.rodata)
+ *(.rodata1)
+ *(.descriptors)
+ *(rom_ver)
+ _erodata = .;
+
+
+ /* Various possible names for the end of the .text section */
+ etext = ALIGN(0x10);
+ _etext = .;
+ _endtext = .;
+ text.end = .;
+ PROVIDE (etext = .);
+ PROVIDE (__etext = .);
+ } > ram
+
+ /* R/W Data */
+ .data :
+ {
+ data_start = .;
+
+ *(.data)
+ *(.data.*)
+ *(.data1)
+
+ PROVIDE (__SDATA_START__ = .);
+ *(.sdata)
+ *(.gnu.linkonce.d*)
+ PROVIDE (__SDATA_END__ = .);
+
+ PROVIDE (__EXCEPT_START__ = .);
+ *(.gcc_except_table)
+ PROVIDE (__EXCEPT_END__ = .);
+
+ PROVIDE(__GOT_START__ = .);
+ *(.got.plt)
+ *(.got)
+ PROVIDE(__GOT_END__ = .);
+
+ *(.got1)
+
+ PROVIDE (__GOT2_START__ = .);
+ PROVIDE (_GOT2_START_ = .);
+ *(.got2)
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (__FIXUP_START__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ *(.fixup)
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+
+ /* We want the small data sections together, so single-instruction offsets
+ * can access them all.
+ */
+ PROVIDE (__SDATA2_START__ = .);
+ *(.sdata2)
+ PROVIDE (__SDATA2_END__ = .);
+ } > ram
+
+
+ .bss :
+ {
+ PROVIDE (__SBSS_START__ = .);
+
+ PROVIDE (__SBSS2_START__ = .);
+ *(.sbss2)
+ PROVIDE (__SBSS2_END__ = .);
+
+ bss.start = .;
+ *(.bss)
+ *(.sbss)
+ *(COMMON)
+ . = ALIGN(4);
+ bss.end = .;
+
+ PROVIDE (__SBSS_END__ = .);
+
+ } > ram
+
+ bss.size = bss.end - bss.start;
+ text.size = text.end - text.start;
+ PROVIDE(_end = bss.end);
+
+ _HeapStart = .;
+ __HeapStart = .;
+ . += HeapSize; /* XXX -- Old gld can't handle this */
+ /* . += 0x80000; */ /* HeapSize for old gld */
+ _HeapEnd = .;
+ __HeapEnd = .;
+ clear_end = .;
+
+ _WorkspaceBase = .;
+ __WorkspaceBase = .;
+
+ dpram :
+ {
+ m8xx = .;
+ _m8xx = .;
+ . += (16 * 1024);
+ } >immr
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c
new file mode 100644
index 0000000000..45c22d8951
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c
@@ -0,0 +1,132 @@
+/*
+ * mmutlbtab.c
+ *
+ * This file defines the MMU_TLB_table for the MBX8xx.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#include <bsp.h>
+#include <mpc8xx/mmu.h>
+
+/*
+ * This MMU_TLB_table is used to statically initialize the Table Lookaside
+ * Buffers in the MMU of the MBX8xx board.
+ *
+ * We initialize the entries in both the instruction and data TLBs
+ * with the same values - a few bits relevant to the data TLB are unused
+ * in the instruction TLB.
+ *
+ * An Effective Page Number (EPN), Tablewalk Control Register (TWC) and
+ * Real Page Number (RPN) value are supplied in the table for each TLB entry.
+ *
+ * The instruction and data TLBs each can hold 32 entries, so _TLB_Table must
+ * not have more than 32 lines in it!
+ *
+ * We set up the virtual memory map so that virtual address of a
+ * location is equal to its real address.
+ */
+MMU_TLB_table_t MMU_TLB_table[] = {
+ /*
+ * DRAM: CS1, Start address 0x00000000, 4M,
+ * ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, not cache-inhibited.
+ * Last 512K block is cache-inhibited, but not guarded for use by EPPCBug.
+ * EPN TWC RPN
+ */
+ { 0x00000200, 0x05, 0x000009FD }, /* DRAM - PS=512K */
+ { 0x00080200, 0x05, 0x000809FD }, /* DRAM - PS=512K */
+ { 0x00100200, 0x05, 0x001009FD }, /* DRAM - PS=512K */
+ { 0x00180200, 0x05, 0x001809FD }, /* DRAM - PS=512K */
+ { 0x00200200, 0x05, 0x002009FD }, /* DRAM - PS=512K */
+ { 0x00280200, 0x05, 0x002809FD }, /* DRAM - PS=512K */
+ { 0x00300200, 0x05, 0x003009FD }, /* DRAM - PS=512K */
+ { 0x00380200, 0x05, 0x003809FF }, /* DRAM - PS=512K, cache-inhibited */
+ /*
+ *
+ * NVRAM: CS4, Start address 0xFA000000, 32K,
+ * ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ *
+ * EPN TWC RPN
+ */
+ { 0xFA000200, 0x01, 0xFA0009FF }, /* NVRAM - PS=16K */
+ { 0xFA004200, 0x01, 0xFA0049FF }, /* NVRAM - PS=16K */
+ /*
+ *
+ * Board Control/Status Register #1/#2: CS4, Start address 0xFA100000, (4 x 8 bits?)
+ * ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFA100200, 0x11, 0xFA1009F7 }, /* BCSR - PS=4K */
+ /*
+ *
+ * (IMMR-SPRs) Dual Port RAM: Start address 0xFA200000, 16K,
+ * ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ *
+ * Note: We use the value in MBXA/PG2, which is also the value that
+ * EPPC-Bug programmed into our boards. The alternative is the value
+ * in MBXA/PG1: 0xFFA00000. This value might well depend on the revision
+ * of the firmware.
+ * EPN TWC RPN
+ */
+ { 0xFA200200, 0x11, 0xFA2009FF }, /* IMMR - PS=16K */
+ /*
+ *
+ * Flash: CS0, Start address 0xFE000000, 4M, (BootROM-EPPCBug)
+ * ASID=0x0, APG=0x0, not guarded memory,
+ * R/O,X for all, no ASID comparison, not cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFE000200, 0x05, 0xFE000CFD }, /* Flash - PS=512K */
+ { 0xFE080200, 0x05, 0xFE080CFD }, /* Flash - PS=512K */
+ { 0xFE100200, 0x05, 0xFE100CFD }, /* Flash - PS=512K */
+ { 0xFE180200, 0x05, 0xFE180CFD }, /* Flash - PS=512K */
+ { 0xFE200200, 0x05, 0xFE200CFD }, /* Flash - PS=512K */
+ { 0xFE280200, 0x05, 0xFE280CFD }, /* Flash - PS=512K */
+ { 0xFE300200, 0x05, 0xFE300CFD }, /* Flash - PS=512K */
+ { 0xFE380200, 0x05, 0xFE380CFD }, /* Flash - PS=512K */
+ /*
+ * BootROM: CS7, Start address 0xFC000000, 4M?, (socketed FLASH)
+ * ASID=0x0, APG=0x0, not guarded memory,
+ * R/O,X for all, no ASID comparison, not cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFC000200, 0x05, 0xFC000CFD }, /* BootROM - PS=512K */
+ /*
+ *
+ * PCI/ISA I/O Space: CS5, Start address 0x80000000, 512M?
+ * ASID=0x0, APG=0x0, guarded memory,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0x80000200, 0x1D, 0x800009FF }, /* PCI I/O - PS=8M */
+ /*
+ *
+ * PCI/ISA Memory Space: CS5, Start address 0xC0000000, 512M?
+ * ASID=0x0, APG=0x0, guarded memory,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xC0000200, 0x1D, 0xC00009FF }, /* PCI Memory - PS=8M */
+ /*
+ *
+ * PCI Bridge/QSPAN Registers: CS6, Start address 0xFA210000, 4K
+ * ASID=0x0, APG=0x0, guarded memory,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFA210200, 0x11, 0xFA2109F7 } /* QSPAN - PS=4K */
+};
+
+/*
+ * MMU_N_TLB_Table_Entries is defined here because the size of the
+ * MMU_TLB_table is only known in this file.
+ */
+int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c
new file mode 100644
index 0000000000..b32dc8aaec
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c
@@ -0,0 +1,44 @@
+/* set_vector
+ *
+ * This routine installs an interrupt vector on the target Board/CPU.
+ * This routine is allowed to be as board dependent as necessary.
+ *
+ * INPUT:
+ * handler - interrupt handler entry point
+ * vector - vector number
+ * type - 0 indicates raw hardware connect
+ * 1 indicates RTEMS interrupt connect
+ *
+ * RETURNS:
+ * address of previous interrupt handler
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+rtems_isr_entry set_vector( /* returns old vector */
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector, /* vector number */
+ int type /* RTEMS or RAW intr */
+)
+{
+ rtems_isr_entry previous_isr;
+
+ if (type) {
+ rtems_interrupt_catch(handler, vector, (rtems_isr_entry *) &previous_isr );
+ } else {
+ /* XXX: install non-RTEMS ISR as "raw" interupt */
+ }
+ return previous_isr;
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S b/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
new file mode 100644
index 0000000000..c487a58a33
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
@@ -0,0 +1,383 @@
+/* start.S
+ *
+ * This file contains the entry veneer for RTEMS programs
+ * on the MBX8xx board.
+ * It jumps to the BSP which is responsible for performing
+ * all remaining initialization.
+ *
+ * This file is based on several others:
+ *
+ * (1) start360.s from the gen68360 BSP by
+ * W. Eric Norum (eric@skatter.usask.ca)
+ * with the following copyright and license:
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * (2) start.s for the eth_comm port by
+ * Jay Monkman (jmonkman@fracsa.com),
+ * which itself is based on the
+ *
+ * (3) dlentry.s for the Papyrus BSP, written by:
+ * Andrew Bray <andy@i-cubed.co.uk>
+ * with the following copyright and license:
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * (4) start860.S for the MBX821/MBX860, written by:
+ * Darlene A. Stewart <darlene.stewart@iit.nrc.ca>
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications (for MBX8xx) of respective RTEMS files:
+ * Copyright (c) 1999, National Research Council of Canada
+ */
+
+#include "asm.h"
+
+/*
+ * The initial stack is set to run BELOW the code base address.
+ * (between the vectors and text sections)
+ *
+ * All the entry veneer has to do is to clear the BSS.
+ */
+
+/*
+ * GDB likes to have debugging information for the entry veneer.
+ * Play compiler and provide some DWARF information.
+ *
+ * CHANGE TO SUIT YOUR SETUP!
+ */
+
+ .section .entry,"ax",@progbits
+.L_text_b:
+.L_LC1:
+ .previous
+
+.section .debug_sfnames
+.L_sfnames_b:
+ .byte "rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/"
+ .byte 0
+.L_F0:
+ .byte "start.S"
+ .byte 0
+ .previous
+
+.section .line
+.L_line_b:
+ .4byte .L_line_e-.L_line_b
+ .4byte .L_text_b
+.L_LE1:
+.L_line_last:
+ .4byte 0x0
+ .2byte 0xffff
+ .4byte .L_text_e-.L_text_b
+.L_line_e:
+ .previous
+
+.section .debug_srcinfo
+.L_srcinfo_b:
+ .4byte .L_line_b
+ .4byte .L_sfnames_b
+ .4byte .L_text_b
+ .4byte .L_text_e
+ .4byte 0xffffffff
+ .4byte .L_LE1-.L_line_b
+ .4byte .L_F0-.L_sfnames_b
+ .4byte .L_line_last-.L_line_b
+ .4byte 0xffffffff
+ .previous
+
+.section .debug_pubnames
+ .4byte .L_debug_b
+ .4byte .L_P0
+ .byte "start"
+ .byte 0
+ .4byte 0x0
+ .byte 0
+ .previous
+
+.section .debug_aranges
+ .4byte .L_debug_b
+ .4byte .L_text_b
+ .4byte .L_text_e-.L_text_b
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0x0
+ .4byte 0x0
+ .previous
+
+.section .debug
+.L_debug_b:
+.L_D1:
+ .4byte .L_D1_e-.L_D1
+ .2byte 0x11 /* TAG_compile_unit */
+ .2byte 0x12 /* AT_sibling */
+ .4byte .L_D2
+ .2byte 0x38 /* AT_name */
+ .byte "start.S"
+ .byte 0
+ .2byte 0x258 /* AT_producer */
+ .byte "GAS 2.5.2"
+ .byte 0
+ .2byte 0x111 /* AT_low_pc */
+ .4byte .L_text_b
+ .2byte 0x121 /* AT_high_pc */
+ .4byte .L_text_e
+ .2byte 0x106 /* AT_stmt_list */
+ .4byte .L_line_b
+ .2byte 0x1b8 /* AT_comp_dir */
+ .byte "rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/"
+ .byte 0
+ .2byte 0x8006 /* AT_sf_names */
+ .4byte .L_sfnames_b
+ .2byte 0x8016 /* AT_src_info */
+ .4byte .L_srcinfo_b
+.L_D1_e:
+.L_P0:
+.L_D3:
+ .4byte .L_D3_e-.L_D3
+ .2byte 0x6 /* TAG_global_subroutine */
+ .2byte 0x12 /* AT_sibling */
+ .4byte .L_D4
+ .2byte 0x38 /* AT_name */
+ .byte "start"
+ .byte 0
+ .2byte 0x278 /* AT_prototyped */
+ .byte 0
+ .2byte 0x111 /* AT_low_pc */
+ .4byte .L_text_b
+ .2byte 0x121 /* AT_high_pc */
+ .4byte .L_text_e
+ .2byte 0x8041 /* AT_body_begin */
+ .4byte .L_text_b
+ .2byte 0x8051 /* AT_body_end */
+ .4byte .L_text_e
+.L_D3_e:
+
+.L_D4:
+ .4byte .L_D4_e-.L_D4
+ .align 2
+.L_D4_e:
+.L_D2:
+ .previous
+
+/*
+ * Tell C's eabi-ctor's that we have an atexit function,
+ * and that it is to register __do_global_dtors.
+ */
+ EXTERN_PROC(atexit)
+ PUBLIC_VAR(__atexit)
+ .section ".sdata","aw"
+ .align 2
+SYM(__atexit):
+ EXT_PROC_REF(atexit)@fixup
+ .previous
+
+ .section ".fixup","aw"
+ .align 2
+ EXT_SYM_REF(__atexit)
+ .previous
+
+/* That should do it */
+
+/*
+ * Put the entry point in its own section. That way, we can guarantee
+ * to put it first in the .text section in the linker script.
+ */
+ .section .entry
+
+ PUBLIC_VAR (start)
+SYM(start):
+ bl .startup /* or bl .spin */
+base_addr:
+
+/*
+ * Parameters from linker
+ */
+toc_pointer:
+ .long __GOT_START__
+bss_length:
+ .long bss.size
+bss_addr:
+ .long bss.start
+
+PUBLIC_VAR (text_addr)
+text_addr:
+ .long text.start
+
+PUBLIC_VAR (text_length)
+text_length:
+ .long text.size
+
+/*
+ * Spin, if necessary, to acquire control from debugger (CodeWarrior).
+ */
+spin:
+ .long 0x0001
+.spin:
+ lis r3, spin@ha
+ lwz r3, spin@l(r3)
+ cmpwi r3, 0x1
+ beq .spin
+
+/*
+ * Initialization code
+ */
+.startup:
+ /* Get the start address. */
+ mflr r1
+
+ /* Initialize essential registers. */
+ bl initregs
+ nop
+
+ /*
+ * C_setup.
+ */
+
+ /* set toc */
+ lwz r2, toc_pointer-base_addr(r1)
+
+ /* Set up stack pointer = beginning of text section - 56 */
+ addi r1, r1, -56-4
+
+ /* Initialize the memory mapped MPC821 registers (done in C). */
+ EXTERN_PROC (_InitMBX8xx)
+ bl PROC (_InitMBX8xx)
+ nop
+
+ /* Clear the bss section. */
+ bl bssclr
+ nop
+
+ /* clear argc and argv */
+ xor r3, r3, r3
+ xor r4, r4, r4
+
+ EXTERN_PROC (boot_card)
+ bl PROC (boot_card) /* call the first C routine */
+ nop
+
+ /* we should never return from boot_card, but in case we do ... */
+ /* The next instructions are dependent on your runtime environment */
+
+ /* Return to EPPCBug */
+ lis r10, 0x0400 /* Data cache disable */
+ mtspr 568, r10
+ isync
+
+ mtspr 560, r10 /* Instruction cache disable */
+ isync
+
+stop_here:
+ li r10, 0x0F00 /* .RETURN */
+ sc
+
+ b stop_here
+ nop
+
+/*
+ * bssclr - zero out bss
+ */
+bssclr:
+ lis r3, base_addr@ha
+ addi r3, r3, base_addr@l
+ lwz r4, bss_addr-base_addr(r3) /* Start of bss */
+ lwz r5, bss_length-base_addr(r3) /* Length of bss */
+
+ rlwinm. r5,r5,30,0x3FFFFFFF /* form length/4 */
+ beqlr /* no bss - return */
+ mtctr r5 /* set ctr reg */
+
+ li r5,0x0000 /* r5 = 0 */
+clear_bss:
+ stw r5,0(r4) /* store r6 */
+ addi r4,r4,0x4 /* update r4 */
+ bdnz clear_bss /* dec counter and loop */
+
+ blr /* return */
+
+/*
+ * initregs
+ * Initialize the MSR and basic core PowerPC registers
+ *
+ * Register usage:
+ * r0 - scratch
+ */
+initregs:
+ /*
+ * Disable address translation. We should already be running in real space,
+ * so this should be a no-op, i.e. no need to switch instruction stream
+ * addresses from virtual space to real space. Other bits set the processor
+ * for big-endian mode, exceptions vectored to 0x000n_nnnn (vectors are
+ * already in low memory!), no execution tracing, machine check exceptions
+ * enabled, floating-point not available (MPC8xx has none), supervisor
+ * priviledge level, external interrupts disabled, power management
+ * disabled (normal operation mode).
+ */
+ li r0, 0x1000 /* MSR_ME */
+ mtmsr r0 /* Context-synchronizing */
+ isync
+
+ /*
+ * Clear the exception handling registers.
+ * Note SPRG3 is reserved for use by EPPCBug on the MBX8xx.
+ */
+ li r0, 0x0000
+ mtdar r0
+ mtspr sprg0, r0
+ mtspr sprg1, r0
+ mtspr sprg2, r0
+ mtspr srr0, r0
+ mtspr srr1, r0
+
+ mr r6, r0
+ mr r7, r0
+ mr r8, r0
+ mr r9, r0
+ mr r10, r0
+ mr r11, r0
+ mr r12, r0
+ mr r13, r0
+ mr r14, r0
+ mr r15, r0
+ mr r16, r0
+ mr r17, r0
+ mr r18, r0
+ mr r19, r0
+ mr r20, r0
+ mr r21, r0
+ mr r22, r0
+ mr r23, r0
+ mr r24, r0
+ mr r25, r0
+ mr r26, r0
+ mr r27, r0
+ mr r28, r0
+ mr r29, r0
+ mr r30, r0
+ mr r31, r0
+
+ blr /* return */
+
+.L_text_e: