diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am | 42 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c | 193 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache | 202 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c | 535 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds | 259 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c | 132 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c | 44 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S | 383 |
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: |