Virtex5 BSP: Various updates and improvements.

This BSP now uses the MPC6xx clock driver instead of a modified PPC403 clock
driver.  Support for the MMU has been added, but is not enabled by default.
This commit is contained in:
Ric Claus
2012-11-30 15:58:32 -08:00
committed by Sebastian Huber
parent 5b822ab26a
commit 655bd39676
12 changed files with 1125 additions and 214 deletions

View File

@@ -35,14 +35,14 @@ libbsp_a_SOURCES = startup/bspclean.c \
startup/bspstart.c \
../../shared/bootcard.c \
../../shared/sbrk.c \
../../shared/gnatinstallhandler.c
../../shared/gnatinstallhandler.c \
../shared/src/memcpy.c
# start
libbsp_a_SOURCES += startup/start.S
# clock & timer
libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/ppc403/clock/clock.c
libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/ppc403/timer/timer.c
libbsp_a_SOURCES += ../../powerpc/shared/clock/p_clock.c
# console
libbsp_a_SOURCES += startup/dummy_console.c \
@@ -52,6 +52,10 @@ libbsp_a_SOURCES += startup/dummy_console.c \
include_bsp_HEADERS += include/irq.h
libbsp_a_SOURCES += irq/irq_init.c
# mmu
include_bsp_HEADERS += include/mmu.h
libbsp_a_SOURCES += mmu/mmu.c
#vectors
include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h
include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_supp.h
@@ -59,7 +63,9 @@ include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_s
libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/exc_bspsupport.rel \
../../../libcpu/@RTEMS_CPU@/shared/cache.rel \
../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel
../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
../../../libcpu/@RTEMS_CPU@/e500/clock.rel \
../../../libcpu/@RTEMS_CPU@/e500/timer.rel
EXTRA_DIST = times

View File

@@ -0,0 +1,86 @@
# Adapted from virtex BSP
BSP NAME: virtex5
BOARD: N/A
BUS: N/A
CPU FAMILY: ppc
CPU: PowerPC 440x5
COPROCESSORS: N/A
MODE: 32 bit mode
DEBUG MONITOR:
PERIPHERALS
===========
TIMERS: 440 internal
SERIAL PORTS: none
REAL-TIME CLOCK: none
DMA: Xilinx virtex internal
VIDEO: none
SCSI: none
NETWORKING: none
DRIVER INFORMATION
==================
CLOCK DRIVER: PPC Decrementer
IOSUPP DRIVER: N/A
SHMSUPP: N/A
TIMER DRIVER: N/A
TTY DRIVER: N/A
STDIO
=====
PORT: N/A
ELECTRICAL: N/A
BAUD: N/A
BITS PER CHARACTER: N/A
PARITY: N/A
STOP BITS: N/A
Notes
=====
Board description
-----------------
clock rate: 465 MHz
ROM: N/A
RAM: 4GByte DRAM
Virtex only supports single processor operations.
Porting
-------
This board support package is written for a naked Virtex 5/PPC FPGA
system. The rough features of such a board are described above.
The BSP itself makes no assumptions on what is loaded in the FPGA,
other than that the CPU has access to some memory, either on-board
or external, from which code can be run.
This BSP has been constructed so that an application of both firmware
and software can be layered on top of it by supplying implementations
for the various 'weak' symbols. These symbols are prefaced with the
term 'app_'. Applications can thus be built outside of the RTEMS
directory tree by linking with the appropriate libraries.
The linkcmds file describes the memory layout. Included in this
definition is a section of memory named MsgArea. Output sent to
stdout is recorded in this area and can be dumped using the JTAG
interface, for example.
For adapting this BSP to other boards, the following files should be
modified:
- c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds
for the memory layout required
- c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c
Here you can select the clock source for the timers and the
serial interface (system clock or external clock pin), the
clock rates, etc.
- c/src/lib/libbsp/powerpc/virtex5/include/bsp.h
some BSP-related constants
- c/src/lib/libbsp/powerpc/virtex5/*
well, they should be generic, so there _should_ be no reason
to mess around there (but who knows...)

View File

@@ -1,102 +0,0 @@
#include <rtems.h>
#include <rtems/libio.h>
#include <string.h>
ssize_t app_memory_write(int minor, const char* buf, size_t len)
__attribute__(( weak, alias("__bsp_memory_write") ));
ssize_t __bsp_memory_write(int minor, const char* buf, size_t len);
rtems_device_driver console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg);
rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg);
rtems_device_driver console_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg);
rtems_device_driver console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg);
rtems_device_driver console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg);
rtems_device_driver console_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg);
ssize_t __bsp_memory_write(int minor, const char* buf, size_t len)
{
const char* const last = buf+len;
while (buf < last)
{
BSP_output_char(*buf++);
}
return len;
}
static rtems_termios_callbacks gMemCallbacks = {
0, /* firstOpen */
0, /* lastClose */
0, /* PollRead */
app_memory_write, /* write */
0, /* SetAttr */
0, /* stopRemoteTx */
0, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
rtems_device_driver console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg)
{
rtems_status_code status;
rtems_termios_initialize();
status = rtems_io_register_name("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg)
{
rtems_status_code sc;
sc = rtems_termios_open (major, minor, arg, &gMemCallbacks);
return sc;
}
rtems_device_driver console_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg)
{
return rtems_termios_close(arg);
}
rtems_device_driver console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg)
{
return rtems_termios_read(arg);
}
rtems_device_driver console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg)
{
return rtems_termios_write(arg);
}
rtems_device_driver console_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void* arg)
{
return rtems_termios_ioctl(arg);
}

View File

@@ -71,6 +71,10 @@ extern "C" {
#ifdef __cplusplus
}
#define BSP_DEC BSP_PIT
#define BSP_DECREMENTER BSP_PIT
#endif
#endif /* ASM */

View File

@@ -0,0 +1,287 @@
#ifndef RTEMS_VIRTEX5_MMU_H
#define RTEMS_VIRTEX5_MMU_H
/**
* @file
*
* @ingroup Virtex5MMU
*
* @brief Routines to manipulate the PPC 440 MMU.
*/
/*
* Authorship
* ----------
* This software was created by
* Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
* and was transcribed for the PPC 440 by
* R. Claus <claus@slac.stanford.edu>, 2012,
* Stanford Linear Accelerator Center, Stanford University,
*
* Acknowledgement of sponsorship
* ------------------------------
* This software was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <inttypes.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup Virtex5MMU Virtex 5 - MMU Support
*
* @ingroup Virtex5
*
* @brief MMU support.
*
* @{
*/
/* Some routines require or return an index 'key'.
*/
typedef int bsp_tlb_idx_t;
/* Cache the relevant TLB entries so that we can make sure the user cannot
* create conflicting (overlapping) entries. Keep them public for informational
* purposes.
*/
typedef struct {
struct {
uint32_t pad:24;
uint32_t tid:8; /** Translation ID */
} id;
struct {
uint32_t epn:22; /** Effective page number */
uint32_t v:1; /** Valid */
uint32_t ts:1; /** Translation Address Space */
uint32_t size:4; /** Page size */
uint32_t tpar:4; /** Tag parity */
} w0;
struct {
uint32_t rpn:22; /** The real (translated) page number. */
uint32_t par1:2; /** For matching the TLB array parity */
uint32_t pad:4;
uint32_t erpn:4; /** Extended Real Page Number */
} w1;
struct {
uint32_t par2:2; /** Parity for TLB word 2 */
uint32_t pad1:14;
uint32_t att:4; /** User-defined attributes */
uint32_t wimge:5; /** Write-Through/Caching Inhibited/Memory Coherent/Guarded/Endian */
uint32_t pad2:1;
uint32_t perm:6; /** User-State Executable/Writeable/Readable Supervisor-State Executable/Writeable/Readable */
} w2;
} bsp_tlb_entry_t;
#define NTLBS 64
extern bsp_tlb_entry_t* bsp_mmu_cache;
// These constants will have to be shifted right by 20 bits before
// being inserted the high word of the TLB.
#define MMU_M_SIZE_1K (0x00000000U)
#define MMU_M_SIZE_4K (0x08000000U)
#define MMU_M_SIZE_16K (0x10000000U)
#define MMU_M_SIZE_64K (0x18000000U)
#define MMU_M_SIZE_256K (0x20000000U)
#define MMU_M_SIZE_1M (0x28000000U)
#define MMU_M_SIZE_16M (0x38000000U)
#define MMU_M_SIZE_256M (0x48000000U)
#define MMU_M_SIZE_MIN (MMU_M_SIZE_1K)
#define MMU_M_SIZE_MAX (MMU_M_SIZE_256M)
#define MMU_M_SIZE (0x78000000U)
#define MMU_V_SIZE (27)
// These constants have the same bit positions they'll occupy
// in low word of the TLB.
#define MMU_M_ATTR_USER0 (0x00010000U)
#define MMU_M_ATTR_USER1 (0x00008000U)
#define MMU_M_ATTR_USER2 (0x00004000U)
#define MMU_M_ATTR_USER3 (0x00002000U)
#define MMU_M_ATTR (0x0001e000U)
#define MMU_V_ATTR (13)
#define MMU_M_PROP_WRITE_THROUGH (0x00001000U)
#define MMU_M_PROP_UNCACHED (0x00000800U)
#define MMU_M_PROP_MEM_COHERENT (0x00000400U)
#define MMU_M_PROP_GUARDED (0x00000200U)
#define MMU_M_PROP_LITTLE_ENDIAN (0x00000100U)
#define MMU_M_PROP (0x00000f00U)
#define MMU_V_PROP (8)
#define MMU_M_PERM_USER_EXEC (0x00000020U)
#define MMU_M_PERM_USER_WRITE (0x00000010U)
#define MMU_M_PERM_USER_READ (0x00000008U)
#define MMU_M_PERM_SUPER_EXEC (0x00000004U)
#define MMU_M_PERM_SUPER_WRITE (0x00000002U)
#define MMU_M_PERM_SUPER_READ (0x00000001U)
#define MMU_M_PERM (0x0000003fU)
#define MMU_V_PERM (0)
/*
* Dump (cleartext) content info from cached TLB entries
* to a file (stdout if f==NULL).
*/
void
bsp_mmu_dump_cache(FILE *f);
/* Read a TLB entry from the hardware and store the settings in the
* bsp_mmu_cache[] structure.
*
* The routine can perform this operation quietly or
* print information to a file.
*
* 'key': TLB entry index.
* 'quiet': perform operation silently (no info printed) if nonzero.
* 'f': open FILE where to print information. May be NULL, in
* which case 'stdout' is used.
*
* RETURNS:
* 0: success; TLB entry is VALID
* +1: success but TLB entry is INVALID
* < 0: error (-1: invalid argument)
* (-2: driver not initialized)
*/
int
bsp_mmu_update(bsp_tlb_idx_t key, bool quiet, FILE *f);
/* Initialize cache. Should be done only once although this is not enforced.
*
* RETURNS: zero on success, nonzero on error; in this case the driver will
* refuse to change TLB entries (other than disabling them).
*/
int
bsp_mmu_initialize(void);
/* Find first free TLB entry by examining all entries' valid bit. The first
* entry without the valid bit set is returned.
*
* RETURNS: A free TLB entry number. -1 if no entry can be found.
*/
bsp_tlb_idx_t
bsp_mmu_find_first_free(void);
/* Write a TLB entry (can also be used to disable an entry).
*
* The routine checks against the cached data in bsp_mmu_cache[]
* to prevent the user from generating overlapping entries.
*
* 'idx': TLB entry # to manipulate
* 'ea': Effective address (must be page aligned)
* 'pa': Physical address (must be page aligned)
* 'sz': Page size selector; page size is 1024 * 2^(2*sz) bytes.
* 'sz' may also be one of the following:
* - page size in bytes ( >= 1024 ); the selector
* value is then computed by this routine.
* However, 'sz' must be a valid page size
* or -1 will be returned.
* - a value < 0 to invalidate/disable the
* TLB entry.
* 'flgs': Page's User-defined flags, permissions and WIMGE page attributes
* 'tid': Translation ID
* 'ts': Translation Space
* 'erpn': Extended Real Page Number
*
* RETURNS: 0 on success, nonzero on error:
*
* >0: requested mapping would overlap with
* existing mapping in another entry. Return
* value gives conflicting entry + 1; i.e.,
* if a value of 4 is returned then the request
* conflicts with existing mapping in entry 3.
* -1: invalid argument
* -3: driver not initialized (or initialization failed).
* <0: other error
*/
bsp_tlb_idx_t
bsp_mmu_write(bsp_tlb_idx_t idx, uint32_t ea, uint32_t pa, int sz,
uint32_t flgs, uint32_t tid, uint32_t ts, uint32_t erpn);
/* Check if a ea/tid/ts/sz mapping overlaps with an existing entry.
*
* 'ea': The Effective Address to match against
* 'sz': The 'logarithmic' size selector; the page size
* is 1024*2^(2*sz).
* 'tid': Translation ID
* 'ts': Translation Space
*
* RETURNS:
* >= 0: index of TLB entry that already provides a mapping
* which overlaps within the ea range.
* -1: SUCCESS (no conflicting entry found)
* <=-2: ERROR (invalid input)
*/
bsp_tlb_idx_t
bsp_mmu_match(uint32_t ea, int sz, uint32_t tid, uint32_t ts);
/* Find TLB index that maps 'ea/tid/ts' combination
*
* 'ea': Effective address to match against
* 'tid': Translation ID
* 'ts': Translation Space
*
* RETURNS: index 'key'; i.e., the index number.
*
* On error (no mapping) -1 is returned.
*/
bsp_tlb_idx_t
bsp_mmu_find(uint32_t ea, uint32_t tid, uint32_t ts);
/* Mark TLB entry as invalid ('disabled').
*
* 'key': TLB entry index.
*
* RETURNS: zero on success, nonzero on error (TLB unchanged).
*
* NOTE: If a TLB entry is disabled the associated
* entry in bsp_tlb_cache[] is also marked as disabled.
*/
int
bsp_mmu_invalidate(bsp_tlb_idx_t key);
/** @} */
#ifdef __cplusplus
};
#endif
#endif

View File

@@ -35,21 +35,21 @@ rtems_irq_global_settings* BSP_rtems_irq_config;
* these functions just do nothing fulfill the semantic
* requirements to enable/disable a certain interrupt or exception
*/
void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
static void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
{
/*
* nothing to do
*/
}
void BSP_irq_nop_hdl(void *hdl)
static void BSP_irq_nop_hdl(void *hdl)
{
/*
* nothing to do
*/
}
int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
{
/*
* nothing to do
@@ -64,7 +64,7 @@ int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
/***********************************************************
* functions to enable/disable/query external/critical interrupts
*/
void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data)
{
uint32_t msr_value;
/*
@@ -76,7 +76,7 @@ void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
_CPU_MSR_SET(msr_value);
}
void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
{
uint32_t msr_value;
/*
@@ -88,6 +88,20 @@ void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
_CPU_MSR_SET(msr_value);
}
SPR_RW(BOOKE_TSR)
int C_dispatch_dec_handler (BSP_Exception_frame *frame, unsigned int excNum)
{
/* Acknowledge the interrupt */
_write_BOOKE_TSR( BOOKE_TSR_DIS );
/* Handle the interrupt */
BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
return 0;
}
/***********************************************************
* High level IRQ handler called from shared_raw_irq_code_entry
*/
@@ -100,9 +114,12 @@ int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
case ASM_EXT_VECTOR:
BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
break;
#if 0 /* Dealt with by C_dispatch_dec_handler(), above */
case ASM_BOOKE_DEC_VECTOR:
BSP_rtems_irq_tbl[BSP_PIT].hdl(BSP_rtems_irq_tbl[BSP_PIT].handle);
_write_BOOKE_TSR( BOOKE_TSR_DIS );
BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
break;
#endif
#if 0 /* Critical interrupts not yet supported */
case ASM_BOOKE_CRIT_VECTOR:
BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
@@ -275,7 +292,7 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
* dummy for an empty IRQ handler entry
*/
static rtems_irq_connect_data emptyIrq = {
0, /* Irq Name */
0, /* IRQ Name */
BSP_irq_nop_hdl, /* handler function */
NULL, /* handle passed to handler */
BSP_irq_nop_func, /* on function */
@@ -284,8 +301,8 @@ static rtems_irq_connect_data emptyIrq = {
};
static rtems_irq_global_settings initialConfig = {
BSP_IRQ_NUMBER, /* irqNb */
{ 0, /* Irq Name */
BSP_IRQ_NUMBER, /* IRQ number */
{ 0, /* IRQ Name */
BSP_irq_nop_hdl, /* handler function */
NULL, /* handle passed to handler */
BSP_irq_nop_func, /* on function */
@@ -305,7 +322,7 @@ void BSP_rtems_irq_mngt_init(unsigned cpuId)
* connect all exception vectors needed
*/
ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler);
ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler);
ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler);
/*
* setup interrupt handlers table

View File

@@ -0,0 +1,581 @@
/**
* @file
*
* @ingroup Virtex5MMU
*
* @brief Implementation of routines to manipulate the PPC 440 MMU.
*
* Since this is a real-time OS we want to stay away from
* software TLB replacement.
*/
/*
* Authorship
* ----------
* This software was created by
* Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
* and was transcribed for the PPC 440 by
* R. Claus <claus@slac.stanford.edu>, 2012,
* Stanford Linear Accelerator Center, Stanford University,
*
* Acknowledgement of sponsorship
* ------------------------------
* This software was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
/* 440 MSR definitions; note that there are *substantial* differences
* compared to classic powerpc; in particular, IS/DS are *different*
* from IR/DR; the ppc440 MMU cannot be switched off!
*
* Also: To disable/enable all external interrupts, CE and EE must both be
* controlled.
*/
#include <rtems.h>
#include <rtems/bspIo.h>
#include <rtems/powerpc/powerpc.h>
#include <inttypes.h>
#include <stdio.h>
#include <bsp/mmu.h>
#ifdef DEBUG
#define STATIC
#else
#define STATIC static
#endif
bsp_tlb_entry_t* bsp_mmu_cache = 0;
/* Since it is likely that these routines are used during
* early initialization when stdio is not available yet
* we provide a helper that resorts to 'printk()'
*/
static void
myprintf(FILE *f, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (!f || !_impure_ptr->__sdidinit) {
/* Might be called at an early stage when stdio is not yet initialized. */
vprintk(fmt,ap);
} else {
vfprintf(f,fmt,ap);
}
va_end(ap);
}
void
bsp_mmu_dump_cache(FILE *f)
{
bsp_tlb_idx_t idx;
if ( !bsp_mmu_cache ) {
myprintf(stderr,"MMU TLB cache not initialized\n");
return;
}
for ( idx=0; idx<NTLBS; idx++ ) {
bsp_tlb_entry_t *tlb = bsp_mmu_cache + idx;
if ( !tlb->w0.v )
continue;
myprintf(f, "#%2i: EA 0x%08x .. 0x%08x, TID 0x%03x, TS %i\n",
idx,
tlb->w0.epn<<10,
(tlb->w0.epn<<10) + (1024<<(2*tlb->w0.size))-1,
tlb->id.tid,
tlb->w0.ts);
myprintf(f, " PA 0x%08"PRIx32", U0-3 0x%01x, WIMGE 0x%02x, PERM 0x%03x\n",
tlb->w1.rpn<<10,
tlb->w2.att,
tlb->w2.wimge,
tlb->w2.perm);
}
}
static void
fetch(bsp_tlb_idx_t key, bsp_tlb_entry_t* tlb)
{
register uint32_t tmp;
__asm__ volatile ("mfpid %[tmp] \n\t"
"stw %[tmp],0(%[tlb]) \n\t"
"tlbre %[tmp],%[key],0 \n\t"
"stw %[tmp],4(%[tlb]) \n\t"
"tlbre %[tmp],%[key],1 \n\t"
"stw %[tmp],8(%[tlb]) \n\t"
"tlbre %[tmp],%[key],2 \n\t"
"stw %[tmp],12(%[tlb]) \n\t"
"sync \n\t"
: [tmp]"=&r"(tmp)
: [key]"r"(key),
[tlb]"b"(tlb)
);
}
static void
store(bsp_tlb_idx_t key, bsp_tlb_entry_t* tlb)
{
register uint32_t tmp;
__asm__ volatile ("lwz %[tmp],0(%[tlb]) \n\t"
"mtpid %[tmp] \n\t"
"lwz %[tmp],4(%[tlb]) \n\t"
"tlbwe %[tmp],%[idx],0 \n\t"
"lwz %[tmp],8(%[tlb]) \n\t"
"tlbwe %[tmp],%[idx],1 \n\t"
"lwz %[tmp],12(%[tlb]) \n\t"
"tlbwe %[tmp],%[idx],2 \n\t"
: [tmp]"=&r"(tmp)
: [tlb]"b"(tlb),
[idx]"r"(key)
);
}
static void
commit(void)
{
__asm__ volatile("isync \n\t");
}
/*
* Read a TLB entry from the hardware store the current settings in the
* bsp_mmu_cache[] structure.
*
* The routine can perform this operation quietly or
* print information to a file.
*
* 'idx': which TLB entry to access.
* 'quiet': perform operation silently (no info printed)
* if nonzero.
* 'f': open FILE where to print information. May be
* NULL in which case 'stdout' is used.
*
* RETURNS:
* 0: success; TLB entry is VALID
* +1: success but TLB entry is INVALID
* < 0: error (-1: invalid argument)
* (-2: driver not initialized)
*/
int
bsp_mmu_update(bsp_tlb_idx_t key, bool quiet, FILE *f)
{
rtems_interrupt_level lvl;
bsp_tlb_entry_t* tlb;
int idx;
idx = key;
if ( idx < 0 || idx > NTLBS-1 )
return -1;
if (!bsp_mmu_cache)
return -2;
tlb = bsp_mmu_cache + idx;
rtems_interrupt_disable(lvl);
fetch(idx, tlb);
rtems_interrupt_enable(lvl);
if ( tlb->w0.v ) {
if ( !quiet ) {
/*
"TLB Entry # 0 spans EA range 0x00000000 - 0x00000000
"Mapping: VA [TS 0 / TID 0x00 / EPN 0x00000] -> RPN 0x00000"
"Size: TSIZE 0x0 (4^sz KB = 000000 KB = 0x00000000 B)
"Attributes: PERM 0x000 (ux/uw/ur/sx/sw/sr) WIMGE 0x00 U0-3 0x0"
*/
myprintf(f,
"TLB Entry # %2d spans EA range 0x%08x - 0x%08x\n",
idx,
(tlb->w0.epn << 10),
(tlb->w0.epn << 10) + (1024<<(2*tlb->w0.size)) - 1
);
myprintf(f,
"Mapping: VA [TS %d / TID 0x%02x / EPN 0x%05x] -> RPN 0x%05"PRIx32"\n",
tlb->w0.ts, tlb->id.tid, tlb->w0.epn, tlb->w1.rpn
);
myprintf(f,
"Size: TSIZE 0x%x (4^sz KB = %6d KB = 0x%08x B)\n",
tlb->w0.size, (1<<(2*tlb->w0.size)), (1024<<(2*tlb->w0.size))
);
myprintf(f,
"Properties: PERM 0x%03x (ux/uw/ur/sx/sw/sr) WIMGE 0x%02x U0-3 0x%01x\n",
tlb->w2.perm, tlb->w2.wimge, tlb->w2.att
);
}
} else {
if ( !quiet ) {
myprintf(f, "TLB Entry # %2d <OFF> (size 0x%x = 0x%xb)\n",
idx, tlb->w0.size, (1024<<(2*tlb->w0.size)));
}
return 1;
}
return 0;
}
/* Initialize cache. Should be done only once although this is not enforced.
*
* RETURNS: zero on success, nonzero on error; in this case the driver will
* refuse to change TLB entries (other than disabling them).
*/
int
bsp_mmu_initialize()
{
static bsp_tlb_entry_t mmu_cache[NTLBS];
bsp_tlb_entry_t* tlb = mmu_cache; /* Should malloc if it's not too early */
rtems_interrupt_level lvl;
bsp_tlb_idx_t idx;
rtems_interrupt_disable(lvl);
for (idx=0; idx<NTLBS; tlb++, idx++)
{
fetch(idx, tlb);
}
rtems_interrupt_enable(lvl);
bsp_mmu_cache = mmu_cache;
return 0;
}
/* Find first free TLB entry by examining all entries' valid bit. The first
* entry without the valid bit set is returned.
*
* RETURNS: A free TLB entry number. -1 if no entry can be found.
*/
bsp_tlb_idx_t
bsp_mmu_find_first_free()
{
bsp_tlb_idx_t idx;
bsp_tlb_entry_t entry;
for (idx=0; idx<NTLBS; idx++) {
register uint32_t tmp;
__asm__ volatile ("tlbre %[tmp],%[idx],0 \n\t"
"stw %[tmp],4(%[tlb]) \n\t" /* entry.w0 */
"sync \n\t"
: [tmp]"=&r"(tmp)
: [idx]"r"(idx),
[tlb]"b"(&entry)
: "memory"
);
if (!(entry.w0.v))
break;
}
return (idx < NTLBS) ? idx : -1;
}
/*
* Write TLB entry (can also be used to disable an entry).
*
* The routine checks against the cached data in
* bsp_mmu_cache[] to prevent the user from generating
* overlapping entries.
*
* 'idx': TLB entry # to manipulate
* 'ea': Effective address (must be page aligned)
* 'pa': Physical address (must be page aligned)
* 'sz': Page size selector; page size is
* 1024 * 2^(2*sz) bytes.
* 'sz' may also be one of the following:
* - page size in bytes ( >= 1024 ); the selector
* value is then computed by this routine.
* However, 'sz' must be a valid page size
* or -1 will be returned.
* - a value < 0 to invalidate/disable the
* TLB entry.
* 'flgs': Page's User-defined flags, permissions and WIMGE page attributes
* 'tid': Translation ID
* 'ts': Translation Space
* 'erpn': Extended Real Page Number
*
* RETURNS: 0 on success, nonzero on error:
*
* >0: requested mapping would overlap with
* existing mapping in other entry. Return
* value gives conflicting entry + 1; i.e.,
* if a value of 4 is returned then the request
* conflicts with existing mapping in entry 3.
* -1: invalid argument
* -3: driver not initialized (or initialization failed).
* <0: other error
*/
bsp_tlb_idx_t
bsp_mmu_write(bsp_tlb_idx_t idx, uint32_t ea, uint32_t pa, int sz,
uint32_t flgs, uint32_t tid, uint32_t ts, uint32_t erpn)
{
bsp_tlb_entry_t tlb;
uint32_t msk;
bsp_tlb_idx_t lkup;
rtems_interrupt_level lvl;
if ( sz >= 1024 ) {
/* Assume they literally specify a size */
msk = sz;
sz = 0;
while ( msk != (1024<<(sz+sz)) ) {
if ( ++sz > 15 ) {
return -1;
}
}
/* OK, acceptable */
}
msk = sz > 0 ? (1024<<(sz+sz)) - 1 : 0;
if ( !bsp_mmu_cache && sz > 0 ) {
myprintf(stderr,"MMU driver not initialized; refusing to enable any entry\n");
return -3;
}
if ( (ea & msk) || (pa & msk) ) {
myprintf(stderr,"Misaligned EA (%08x) or PA (%08x) (mask is %08x)\n", ea, pa, msk);
return -1;
}
if ( idx < 0 || idx > NTLBS-1 )
return -1;
/* Not all 16 possible sizes are supported */
if ( sz == 6 || sz == 8 || sz > 9 ) {
myprintf(stderr,"Invalid size %u = %08x = %u KB\n", sz, 1024<<(sz+sz), (1024<<(sz+sz))/1024);
return -1;
}
if ( sz >=0 ) {
lkup = bsp_mmu_match(ea, sz, tid, ts);
if ( lkup < -1 ) {
/* some error */
return lkup;
}
if ( lkup >= 0 && lkup != idx && (bsp_mmu_cache[lkup].w0.v != 0) ) {
myprintf(stderr,"TLB #%i overlaps with requested mapping\n", lkup);
bsp_mmu_update( lkup, false, stderr);
return lkup+1;
}
}
/* OK to proceed */
tlb.id.tid = tid;
tlb.w0.v = sz >= 0;
tlb.w0.ts = ts;
tlb.w0.size = sz;
tlb.w0.epn = (ea & (0xfffffc00 << (sz+sz))) >> 10;
if (sz < 11) {
tlb.w1.rpn = (pa & (0xfffffc00 << (sz+sz))) >> 10;
tlb.w1.erpn = erpn;
}
else {
sz -= 11;
tlb.w1.rpn = 0;
tlb.w1.erpn = (erpn & (0xf << (sz+sz))) & 0xf;
}
tlb.w2.att = (flgs & MMU_M_ATTR) >> MMU_V_ATTR;
tlb.w2.wimge = (flgs & MMU_M_PROP) >> MMU_V_PROP;
tlb.w2.perm = (flgs & MMU_M_PERM) >> MMU_V_PERM;
rtems_interrupt_disable(lvl);
store(idx, &tlb);
commit();
rtems_interrupt_enable(lvl);
/* update cache */
bsp_mmu_update(idx, true, 0);
return 0;
}
/*
* Check if a ea/tid/ts/sz mapping overlaps with an existing entry.
*
* 'ea': The Effective Address to match against
* 'sz': The 'logarithmic' size selector; the page size
* is 1024*2^(2*sz).
* 'tid': Translation ID
* 'ts': Translation Space
*
* RETURNS:
* >= 0: index of the TLB entry that already provides a mapping
* which overlaps within the ea range.
* -1: SUCCESS (no conflicting entry found)
* <=-2: ERROR (invalid input)
*/
bsp_tlb_idx_t
bsp_mmu_match(uint32_t ea, int sz, uint32_t tid, uint32_t ts)
{
bsp_tlb_idx_t idx;
uint32_t m,a;
bsp_tlb_entry_t* tlb;
if ( sz < 0 || sz == 6 || sz == 8 || sz > 9 )
return -4;
sz = (1024<<(2*sz));
if ( !bsp_mmu_cache ) {
/* cache not initialized */
return -3;
}
if ( ea & (sz-1) ) {
/* misaligned ea */
return -2;
}
for ( idx=0, tlb=bsp_mmu_cache; idx<NTLBS; idx++, tlb++ ) {
if ( ! tlb->w0.v )
continue;
if ( tlb->id.tid && tlb->id.tid != tid )
continue;
if ( tlb->w0.ts != ts )
continue;
/* TID and TS match a valid entry */
m = (1024<<(2*tlb->w0.size)) - 1;
/* calculate starting address of this entry */
a = tlb->w0.epn<<10;
if ( ea <= a + m && ea + sz -1 >= a ) {
/* overlap */
return idx;
}
}
return -1;
}
/* Find TLB index that maps 'ea/tid/ts' combination
*
* 'ea': Effective address to match against
* 'tid': Translation ID
* 'ts': Translation Space
*
* RETURNS: index 'key' which indicates whether
* the mapping was found.
*
* On error (no mapping) -1 is returned.
*/
bsp_tlb_idx_t
bsp_mmu_find(uint32_t ea, uint32_t tid, uint32_t ts)
{
rtems_interrupt_level lvl;
register uint32_t mmucr;
register bsp_tlb_idx_t idx;
register int failure;
rtems_interrupt_disable(lvl);
__asm__ volatile ("mfspr %[mmucr],0x3b2 \n\t" /* Save MMUCR */
: [mmucr]"=r"(mmucr)
);
__asm__ volatile ("mtspr 0x3b2,%[tid] \n\t"
"tlbsx. %[idx],0,%[ea] \n\t" /* Failure changes the index reg randomly. */
"mfcr %[failure] \n\t"
"mtspr 0x3b2,%[mmucr] \n\t" /* Restore MMUCR */
: [idx]"=&r"(idx),
[failure]"=&r"(failure)
: [tid]"r"((mmucr & 0xfffeff00) | (ts << 16) | tid),
[ea]"r"(ea),
[mmucr]"r"(mmucr)
: "cc"
);
rtems_interrupt_enable(lvl);
return (failure & 0x20000000) ? idx : -1;
}
/* Mark TLB entry as invalid ('disabled').
*
* 'key': TLB entry (index).
*
* RETURNS: zero on success, nonzero on error (TLB unchanged).
*
* NOTE: If a TLB entry is disabled the associated
* entry in bsp_mmu_cache[] is also
* marked as disabled.
*/
int
bsp_mmu_invalidate(bsp_tlb_idx_t key)
{
bsp_tlb_idx_t k0;
rtems_interrupt_level lvl;
bsp_tlb_entry_t tlb;
/* minimal guard against bad key */
if ( key < 0 || key > NTLBS-1 )
return -1;
/* Must not invalidate page 0 which holds vectors, text etc... */
k0 = bsp_mmu_find(0, 0, 0);
if ( -1 == k0 ) {
myprintf(stderr,"No mapping for address 0 found\n");
return -2;
}
/* NOTE: we assume PID is ignored */
if ( k0 == key ) {
myprintf(stderr,"Cannot invalidate page holding address 0 (always needed)\n");
return -3;
}
rtems_interrupt_disable(lvl);
fetch(key, &tlb);
/* Invalidate old entries */
tlb.w0.v = 0;
store(key, &tlb);
commit();
/* Update cache */
bsp_mmu_cache[ key ].w0.v = tlb.w0.v;
rtems_interrupt_enable(lvl);
return 0;
}

View File

@@ -69,6 +69,10 @@ $(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
$(PROJECT_INCLUDE)/bsp/mmu.h: include/mmu.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/mmu.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/mmu.h
$(PROJECT_INCLUDE)/bsp/vectors.h: ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h

View File

@@ -54,20 +54,23 @@
* Modifications for PPC405GP by Dennis Ehlin
* Modifications for Virtex5 by Richard Claus <claus@slac.stanford.edu>
*/
#include <string.h>
#include <fcntl.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/vectors.h>
#include <rtems.h>
#include <rtems/config.h>
#include <rtems/bspIo.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <rtems/sptables.h> /* for RTEMS_VERSION */
#include <libcpu/cpuIdent.h>
#include <libcpu/spr.h>
#include <bsp.h>
#include <bsp/vectors.h>
#include <bsp/bootcard.h>
#include <bsp/irq.h>
#include <string.h>
#include <fcntl.h>
#define DO_DOWN_ALIGN(x,a) ((x) & ~((a)-1))
#define DO_UP_ALIGN(x,a) DO_DOWN_ALIGN(((x) + (a) - 1 ),a)
@@ -76,13 +79,6 @@
#define CPU_UP_ALIGN(x) DO_UP_ALIGN(x, CPU_ALIGNMENT)
/* Expected by clock.c */
uint32_t bsp_clicks_per_usec;
bool bsp_timer_internal_clock; /* true, when timer runs with CPU clk */
uint32_t bsp_timer_least_valid;
uint32_t bsp_timer_average_overhead;
/* Defined in linkcmds linker script */
LINKER_SYMBOL(RamBase);
LINKER_SYMBOL(RamSize);
@@ -96,35 +92,37 @@ LINKER_SYMBOL(WorkAreaBase);
LINKER_SYMBOL(MsgAreaBase);
LINKER_SYMBOL(MsgAreaSize);
LINKER_SYMBOL(__phy_ram_end);
LINKER_SYMBOL(bsp_exc_vector_base);
/* Expected by clock.c */
uint32_t bsp_clicks_per_usec;
bool bsp_timer_internal_clock; /* true, when timer runs with CPU clk */
uint32_t bsp_timer_least_valid;
uint32_t bsp_timer_average_overhead;
/*
* Bus Frequency
*/
unsigned int BSP_bus_frequency;
/*
* processor clock frequency
*/
unsigned int BSP_processor_frequency;
/*
* Time base divisior (bus freq / TB clock)
*/
unsigned int BSP_time_base_divisor;
/*
* Provide weak aliases so that RTEMS distribution builds
*/
static void _noopfun(void) {}
static void _bsp_start(void)
{
uintptr_t intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start);
uintptr_t intrStackSize = rtems_configuration_get_interrupt_stack_size();
/*
* Initialize default raw exception handlers.
*
* This BSP does not assume anything about firmware possibly loaded in the
* FPGA, so the external interrupt should not be enabled in order to avoid
* spurious interrupts.
*/
ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT & ~MSR_EE,
intrStackStart,
intrStackSize);
/* Install our own set of exception vectors */
BSP_rtems_irq_mngt_init(0);
}
void app_bsp_start(void)
__attribute__(( weak, alias("_bsp_start") ));
__attribute__(( weak, alias("_noopfun") ));
void app_bsp_pretasking_hook(void)
__attribute__(( weak, alias("_noopfun") ));
@@ -147,20 +145,31 @@ static void __bsp_outchar_to_memory(char c)
void BSP_ask_for_reset(void)
{
printk("\nSystem stopped, issue RESET");
for(;;);
}
void BSP_panic(char *s)
{
printk("\n%s PANIC %s\n", _RTEMS_version, s);
rtems_interrupt_level level;
rtems_interrupt_disable(level);
printk("\n%s PANIC %s\n", rtems_get_version_string(), s);
BSP_ask_for_reset();
}
void _BSP_Fatal_error(unsigned int v)
{
printk("\n%s FATAL ERROR %x\n", _RTEMS_version, v);
rtems_interrupt_level level;
rtems_interrupt_disable(level);
printk("\n%s FATAL ERROR %x\n", rtems_get_version_string(), v);
BSP_ask_for_reset();
}
@@ -176,13 +185,14 @@ void bsp_start(void)
{
uintptr_t intrStackStart;
uintptr_t intrStackSize;
ppc_cpu_id_t myCpu;
ppc_cpu_revision_t myCpuRevision;
/* Set the character output function; The application may override this */
BSP_output_char = __bsp_outchar_to_memory;
printk("\nWelcome to RTEMS %s\n", _RTEMS_version );
printk("RTEMS %s\n", rtems_get_version_string());
/*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type()
@@ -197,8 +207,13 @@ void bsp_start(void)
* Initialize the device driver parameters
*/
/* For mpc6xx clock driver: */
BSP_bus_frequency = 465000000;
BSP_processor_frequency = 465000000; /* Measured with a DPM 440 2012/8/13 */
BSP_time_base_divisor = 1000;
/* Timebase register ticks/microsecond; The application may override these */
bsp_clicks_per_usec = 450;
bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
bsp_timer_internal_clock = true;
bsp_timer_average_overhead = 2;
bsp_timer_least_valid = 3;
@@ -208,6 +223,12 @@ void bsp_start(void)
*/
intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start);
intrStackSize = rtems_configuration_get_interrupt_stack_size();
ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
intrStackStart,
intrStackSize);
/* Let the user know what parameters we were compiled with */
printk(" Base/Start End Size\n"
"RAM: 0x%08x 0x%x\n"
"RTEMS: 0x%08x\n"
@@ -224,6 +245,11 @@ void bsp_start(void)
(uint32_t)MsgAreaBase, (uint32_t)MsgAreaSize,
(uint32_t)__phy_ram_end);
/*
* Initialize RTEMS IRQ system
*/
BSP_rtems_irq_mngt_init(0);
/* Continue with application-specific initialization */
app_bsp_start();
}

View File

@@ -20,16 +20,17 @@ HeapSize = DEFINED(HeapSize) ? HeapSize : 0; /* 0=Use def */
MEMORY
{
VECTORS : ORIGIN = 0x00000000, LENGTH = 8K
RAM : ORIGIN = 0x00002000, LENGTH = 2048M - 8K
VECTORS : ORIGIN = 0x00000000, LENGTH = 512
RAM : ORIGIN = 0x00000200, LENGTH = 2048M - 512
}
SECTIONS
{
__exeentry = download_entry;
__exestart = 0x100;
.vectors __exestart : { *(.vectors) } > VECTORS
bsp_exc_vector_base = 0;
__exeentry = download_entry;
__exestart = bsp_exc_vector_base;
.vectors bsp_exc_vector_base : { *(.vectors) } > VECTORS
/* Read-only sections, merged into text segment: */
.interp : { *(.interp) } > RAM

View File

@@ -61,6 +61,7 @@
#include <rtems/asm.h>
#include <rtems/powerpc/powerpc.h>
#include <rtems/powerpc/registers.h>
#define V_TS_SZ_I 0x0290 // V,TS=0(Inst),SIZE=9,TID=0
#define V_TS_SZ_D 0x0390 // V,TS=1(Data),SIZE=9,TID=0
@@ -154,43 +155,44 @@ first: li r0,0 // Clear r0
/*------------------------------------------------------------------
* Set Core Configuration Register 0 as follows:
* sum: 0x00200000
* sum: 0x00206000
* bit 1 off Parity Recovery Enable
* bit 4 off Cache Read Parity Enable
* bit 10 on Disable Store Gathering
* bit 11 off Disable APU Instruction Broadcast
* bit 16 off Disable Trace Broadcast
* bit 17:18 off Specifies behaviour of icbt,dcbt/dcbtst insts
* bit 17:18 on Specifies behaviour of icbt,dcbt/dcbtst insts
* bit 23 off Force Load/Store Alignment
* bit 28:29 off Instruction Cache Speculative Line Count
* bit 30:31 off Instruction Cache Speculative Line Threshold
* NB: UG200/pg 21: Spec. prefetching must be disabled
*------------------------------------------------------------------*/
lis r2,0x0020 // 7. Set CCR0: DSTG
mtccr0 r2 // Configure CCR0
lis r2, 0x00206000@h // 7. Set CCR0: DSTG
ori r2,r2,0x00206000@l // Set CCR0: GDCBT, GICBT
mtccr0 r2 // Configure CCR0
mtspr ccr1,r0 // 8. Clear CCR1
mtspr PPC440_CCR1,r0 // 8. Clear CCR1
/*------------------------------------------------------------------
* 9. Configure cache regions
*------------------------------------------------------------------*/
mtspr inv0,r0
mtspr inv1,r0
mtspr inv2,r0
mtspr inv3,r0
mtspr dnv0,r0
mtspr dnv1,r0
mtspr dnv2,r0
mtspr dnv3,r0
mtspr itv0,r0
mtspr itv1,r0
mtspr itv2,r0
mtspr itv3,r0
mtspr dtv0,r0
mtspr dtv1,r0
mtspr dtv2,r0
mtspr dtv3,r0
mtspr PPC440_INV0,r0
mtspr PPC440_INV1,r0
mtspr PPC440_INV2,r0
mtspr PPC440_INV3,r0
mtspr PPC440_DNV0,r0
mtspr PPC440_DNV1,r0
mtspr PPC440_DNV2,r0
mtspr PPC440_DNV3,r0
mtspr PPC440_ITV0,r0
mtspr PPC440_ITV1,r0
mtspr PPC440_ITV2,r0
mtspr PPC440_ITV3,r0
mtspr PPC440_DTV0,r0
mtspr PPC440_DTV1,r0
mtspr PPC440_DTV2,r0
mtspr PPC440_DTV3,r0
/*------------------------------------------------------------------
* Cache victim limits
@@ -198,8 +200,8 @@ first: li r0,0 // Clear r0
*------------------------------------------------------------------*/
lis r2, 0x0001f800@h
ori r2,r2,0x0001f800@l
mtspr ivlim,r2
mtspr dvlim,r2
mtspr PPC440_IVLIM,r2
mtspr PPC440_DVLIM,r2
/*------------------------------------------------------------------
* Configure instruction and data cache regions:
@@ -241,7 +243,7 @@ first: li r0,0 // Clear r0
* 31 SR 1 1 Supervisor State Read Enable
*------------------------------------------------------------------*/
mtspr mmucr,r0 // 10a. Clear MMUCR
mtspr PPC440_MMUCR,r0 // 10a. Clear MMUCR
li r7,WIMG_U_S_1 // Word 2: Pages are NOT cache inhibited
lis r6, PAGE_SZ@h // Page size constant
ori r6,r6,PAGE_SZ@l
@@ -255,9 +257,9 @@ first: li r0,0 // Clear r0
* Select whether Wait Enable, interrupts/exceptions and which address
* spaces should be enabled when application starts
*------------------------------------------------------------------*/
lis r0, 0x00000000@h // 10d. MSR[IS]=0 MSR[DS]=0
ori r0,r0,0x00000000@l
mtsrr1 r0
lis r3, 0x00000000@h // 10d. MSR[IS]=0 MSR[DS]=0
ori r3,r3,0x00000000@l
mtsrr1 r3
mtsrr0 r28 // Return address
rfi // Context synchronize to invalidate shadow TLB contents
@@ -275,43 +277,43 @@ startupDL:
* 11. Tell the processor where the exception vector table will be
*------------------------------------------------------------------*/
.extern SYM(__vectors)
lis r2, __vectors@h /* set EVPR exc. vector prefix */
mtspr ivpr,r2
lis r1, __vectors@h /* set EVPR exc. vector prefix */
mtspr BOOKE_IVPR,r1
/*------------------------------------------------------------------
* Set up default exception and interrupt vectors
*------------------------------------------------------------------*/
li r1,0x100
li r1,0
mtivor0 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor1 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor2 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor3 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor4 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor5 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor6 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor7 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor8 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor9 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor10 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor11 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor12 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor13 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor14 r1
addi r1,r1,0x100
addi r1,r1,0x10
mtivor15 r1
/*------------------------------------------------------------------
@@ -336,16 +338,15 @@ startupDL:
* 13. Configure timer facilities
*------------------------------------------------------------------*/
mtdec r0 // Clear Decrementer to prevent exception
mttbu r0 // Clear Timebase to prevent Fixed Interval..
mttbl r0 // ..timer and Watchdog Timer exceptions
mttbl r0 // Clear Timebase to prevent Fixed Interval..
mttbu r0 // ..timer and Watchdog Timer exceptions
mtpit r0 // Programmable interval timer
li r1,-1 // -1 to clear TSR
mttsr r1 // Timer status register
li r2,-1 // -1 to clear TSR
mttsr r2 // Timer status register
/*-------------------------------------------------------------------
* Clear out stale values in certain registers to avoid confusion
*------------------------------------------------------------------*/
li r0,0
mtcrf 0xff,r0 // Need for simulation
mtctr r0 // Counter register
mtxer r0 // Fixed-point exception register

View File

@@ -57,7 +57,7 @@ AM_CONDITIONAL(mpc6xx, test "$RTEMS_CPU_MODEL" = "mpc6xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc750" \
|| test "$RTEMS_CPU_MODEL" = "mpc8240" \
|| test "$RTEMS_CPU_MODEL" = "mpc8245" \
|| test "$RTEMS_CPU_MODEL" = "mpc83xx" )
|| test "$RTEMS_CPU_MODEL" = "mpc83xx")
AM_CONDITIONAL(mpc8xx, test "$RTEMS_CPU_MODEL" = "mpc8xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc821" \
|| test "$RTEMS_CPU_MODEL" = "mpc860" )
@@ -65,15 +65,15 @@ AM_CONDITIONAL(mpc8260, test "$RTEMS_CPU_MODEL" = "mpc8260")
AM_CONDITIONAL(mpc83xx, test "$RTEMS_CPU_MODEL" = "mpc83xx")
AM_CONDITIONAL(qoriq, test "$RTEMS_CPU_MODEL" = "qoriq")
# the ppc405 and ppc440 share files with the ppc403
# the ppc405 share files with the ppc403
AM_CONDITIONAL(ppc403, test "$RTEMS_CPU_MODEL" = "ppc403")
AM_CONDITIONAL(ppc405, test "$RTEMS_CPU_MODEL" = "ppc405")
AM_CONDITIONAL(ppc440, test "$RTEMS_CPU_MODEL" = "ppc440")
AM_CONDITIONAL(ppc4xx, test "$RTEMS_CPU_MODEL" = "ppc403" \
|| test "$RTEMS_CPU_MODEL" = "ppc405" \
|| test "$RTEMS_CPU_MODEL" = "ppc440")
|| test "$RTEMS_CPU_MODEL" = "ppc405")
AM_CONDITIONAL(e500, test "$RTEMS_CPU_MODEL" = "e500" \
|| test "$RTEMS_CPU_MODEL" = "ppc440" \
|| test "$RTEMS_CPU_MODEL" = "qoriq" )
RTEMS_CHECK_NETWORKING