2001-10-22 Andy Dachs <a.dachs@sstl.co.uk>

* Added mpc8260 directory.
	* Modified Makefile.am and configure.in to build the contents
	* mpc8260/Makefile.am, mpc8260/README, mpc8260/clock/Makefile.am,
	mpc8260/clock/clock.c, mpc8260/console-generic/Makefile.am,
	mpc8260/console-generic/console-generic.c, mpc8260/cpm/.cvsignore,
	mpc8260/cpm/Makefile.am, mpc8260/cpm/brg.c, mpc8260/cpm/cp.c,
	mpc8260/cpm/dpram.c, mpc8260/exceptions/.cvsignore,
	mpc8260/exceptions/Makefile.am, mpc8260/exceptions/asm_utils.S,
	mpc8260/exceptions/raw_exception.c, mpc8260/exceptions/raw_exception.h,
	mpc8260/include/Makefile.am, mpc8260/include/console.h,
	mpc8260/include/cpm.h, mpc8260/include/mmu.h,
	mpc8260/include/mpc8260.h, mpc8260/mmu/Makefile.am, mpc8260/mmu/mmu.c,
	mpc8260/timer/Makefile.am, mpc8260/timer/timer.c: New files.
This commit is contained in:
Joel Sherrill
2001-10-22 13:42:45 +00:00
parent ac6ddad170
commit 1ec501c567
26 changed files with 4409 additions and 0 deletions

View File

@@ -1,3 +1,19 @@
2001-10-22 Andy Dachs <a.dachs@sstl.co.uk>
* Added mpc8260 directory.
* Modified Makefile.am and configure.in to build the contents
* mpc8260/Makefile.am, mpc8260/README, mpc8260/clock/Makefile.am,
mpc8260/clock/clock.c, mpc8260/console-generic/Makefile.am,
mpc8260/console-generic/console-generic.c, mpc8260/cpm/.cvsignore,
mpc8260/cpm/Makefile.am, mpc8260/cpm/brg.c, mpc8260/cpm/cp.c,
mpc8260/cpm/dpram.c, mpc8260/exceptions/.cvsignore,
mpc8260/exceptions/Makefile.am, mpc8260/exceptions/asm_utils.S,
mpc8260/exceptions/raw_exception.c, mpc8260/exceptions/raw_exception.h,
mpc8260/include/Makefile.am, mpc8260/include/console.h,
mpc8260/include/cpm.h, mpc8260/include/mmu.h,
mpc8260/include/mpc8260.h, mpc8260/mmu/Makefile.am, mpc8260/mmu/mmu.c,
mpc8260/timer/Makefile.am, mpc8260/timer/timer.c: New files.
2001-10-12 Joel Sherrill <joel@OARcorp.com> 2001-10-12 Joel Sherrill <joel@OARcorp.com>
* mpc6xx/clock/c_clock.c, mpc6xx/clock/c_clock.h, mpc8xx/clock/clock.c, * mpc6xx/clock/c_clock.c, mpc6xx/clock/c_clock.h, mpc8xx/clock/clock.c,

View File

@@ -0,0 +1,10 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = include console-generic clock timer exceptions mmu cpm
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,19 @@
#
# $Id$
# Modified from mpc860 version by A. Dachs, 28-4-00
Various non BSP dependant support routines.
clock - Uses the MPC8260 decrementer to
generate RTEMS clock ticks.
console_generic - Uses the MPC8260 SCCs and SMCs to to serial I/O
include - console.h: function declarations for console related functions
timer - Uses the MPC8260 timebase register for timing
tests. It only uses the lower 32 bits
vectors - MPC8260 specific vector entry points.
Includes CPU dependant, application independant
handlers: alignment.

View File

@@ -0,0 +1,29 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/clock.rel
## C sources
C_FILES = clock.c
clock_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/compile.am
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(clock_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,228 @@
/* clock.c
*
* This routine initializes the PIT on the MPC8xx.
* The tick frequency is specified by the bsp.
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* 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.
*
* Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
*
* 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 <clockdrv.h>
#include <rtems/libio.h>
#include <stdlib.h> /* for atexit() */
#include <mpc8260.h>
#include <bsp/irq.h>
volatile rtems_unsigned32 Clock_driver_ticks;
extern int BSP_get_clock_irq_level();
extern int BSP_connect_clock_handler(rtems_isr_entry);
extern int BSP_disconnect_clock_handler();
void Clock_exit( void );
rtems_unsigned32 decrementer_value;
volatile int ClockInitialised = 0;
/*
* These are set by clock driver during its init
*/
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
/*
* ISR Handler
*/
rtems_isr Clock_isr(rtems_vector_number vector)
{
int clicks;
if( ClockInitialised ) {
PPC_Get_decrementer( clicks );
do {
clicks += decrementer_value;
PPC_Set_decrementer( clicks );
Clock_driver_ticks++;
rtems_clock_tick();
} while( clicks < 100 );
}
#if 0
m8260.piscr |= M8260_PISCR_PS;
Clock_driver_ticks++;
rtems_clock_tick();
#endif
}
void clockOn(void* unused)
{
decrementer_value = rtems_configuration_get_microseconds_per_tick() *
rtems_cpu_configuration_get_clicks_per_usec() - 1;
PPC_Set_decrementer( decrementer_value );
Clock_driver_ticks = 0;
ClockInitialised = 1;
#if 0
unsigned desiredLevel;
rtems_unsigned32 pit_value;
pit_value = (rtems_configuration_get_microseconds_per_tick() *
rtems_cpu_configuration_get_clicks_per_usec()) - 1 ;
if (pit_value > 0xffff) { /* pit is only 16 bits long */
rtems_fatal_error_occurred(-1);
}
m8260.sccr &= ~(1<<24);
m8260.pitc = pit_value;
desiredLevel = BSP_get_clock_irq_level();
/* set PIT irq level, enable PIT, PIT interrupts */
/* and clear int. status */
m8260.piscr = /*M8260_PISCR_PIRQ(desiredLevel) |*/
M8260_PISCR_PTE | M8260_PISCR_PS | M8260_PISCR_PIE;
#endif
}
/*
* Called via atexit()
* Remove the clock interrupt handler by setting handler to NULL
*/
void
clockOff(void* unused)
{
#if 0
/* disable PIT and PIT interrupts */
m8260.piscr &= ~(M8260_PISCR_PTE | M8260_PISCR_PIE);
#endif
ClockInitialised = 0;
}
int clockIsOn(void* unused)
{
return ClockInitialised;
#if 0
if (m8260.piscr & M8260_PISCR_PIE) return 1;
return 0;
#endif
}
/*
* Called via atexit()
* Remove the clock interrupt handler by setting handler to NULL
*/
void
Clock_exit(void)
{
(void) BSP_disconnect_clock_handler ();
}
void Install_clock(rtems_isr_entry clock_isr)
{
Clock_driver_ticks = 0;
decrementer_value = rtems_configuration_get_microseconds_per_tick() *
rtems_cpu_configuration_get_clicks_per_usec() - 1;
PPC_Set_decrementer( decrementer_value );
BSP_connect_clock_handler (clock_isr);
ClockInitialised = 1;
atexit(Clock_exit);
}
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
{
BSP_connect_clock_handler (new_clock_isr);
}
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
Install_clock( Clock_isr );
/*
* make major/minor avail to others such as shared memory driver
*/
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
goto done;
/*
* This is hokey, but until we get a defined interface
* to do this, it will just be this simple...
*/
if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
Clock_isr(BSP_PERIODIC_TIMER);
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
ReInstall_clock(args->buffer);
}
done:
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,29 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/console-generic.rel
## C sources
C_FILES = console-generic.c
console_generic_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/compile.am
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(console_generic_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,29 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/cp.rel
## C sources
C_FILES = cp.c dpram.c brg.c
cpm_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/compile.am
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(cpm_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,204 @@
/*
* Baud rate generator management functions.
*
* This file contains routines for allocating baud rate generators
* and clock sources to the SCCs and FCCs on the MPC8260. The
* allocation is a little more complex on this processor because
* there are restrictions on which brgs and clks can be assigned to
* a particular port. Rather than coming up with a fixed assignment
* these routines try to allocate resources sensibly.
*
* *** All attempts to allocate a BRG or CLK line should be made via
* calls to these routines or they simply won't work.
*
* Author: Andy Dachs <a.dachs@sstl.co.uk>
* Copyright Surrey Satellite Technology Limited (SSTL), 2001
*
* Derived in part from work by:
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copyright (C) 1998 by Frasca International, Inc.
* and
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* Saskatoon, Saskatchewan, CANADA
* eric@skatter.usask.ca
*
* 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 <mpc8260.h>
#include <mpc8260/cpm.h>
#include <bspIo.h>
#define NUM_BRGS 8
#define NUM_CLKS 20
/* Used to track the usage of the baud rate generators */
/* (initialised to zeros) */
static unsigned long brg_spd[NUM_BRGS];
static unsigned int brg_use_count[NUM_BRGS];
/* Used to track the usage of the clock inputs */
/* (initialised to zeros) */
static unsigned int clk_use_count[NUM_BRGS];
extern rtems_cpu_table Cpu_table;
/*
* Compute baud-rate-generator configuration register value
*/
int
m8xx_get_brg_cd (int baud)
{
int divisor;
int div16 = 0;
divisor = ((Cpu_table.serial_per_sec) + (baud / 2)) / baud;
if (divisor > 4096) {
div16 = 1;
divisor = (divisor + 8) / 16;
}
return M8260_BRG_EN | M8260_BRG_EXTC_BRGCLK |
((divisor - 1) << 1) | div16;
}
/*
* Allocates an existing brg if one is already programmed for the same
* baud rate. Otherwise a new brg is assigned
* AFD: on the mpc8260 only some combinations of SCC/SMC and BRG are allowed
* so add a mask which specifies which of the BRGs we can choose from
*/
int
m8xx_get_brg(unsigned brgmask, int baud)
{
int i;
/* first try to find a BRG that is already at the right speed */
for ( i = 0; i < NUM_BRGS; i++ ) {
if( (1 << i) & brgmask ) /* is this brg allowed? */
if ( brg_spd[i] == baud ) {
break;
}
}
if ( i == NUM_BRGS ) { /* I guess we didn't find one */
for ( i = 0; i < NUM_BRGS; i++ ) {
if (((1<<i) & brgmask) && (brg_use_count[i] == 0)) {
break;
}
}
}
if (i != NUM_BRGS) {
brg_use_count[i]++;
brg_spd[i]=baud;
switch (i) {
case 0:
m8260.brgc1 = M8260_BRG_RST;
m8260.brgc1 = m8xx_get_brg_cd(baud);
break;
case 1:
m8260.brgc2 = M8260_BRG_RST;
m8260.brgc2 = m8xx_get_brg_cd(baud);
break;
case 2:
m8260.brgc3 = M8260_BRG_RST;
m8260.brgc3 = m8xx_get_brg_cd(baud);
break;
case 3:
m8260.brgc4 = M8260_BRG_RST;
m8260.brgc4 = m8xx_get_brg_cd(baud);
break;
case 4:
m8260.brgc5 = M8260_BRG_RST;
m8260.brgc5 = m8xx_get_brg_cd(baud);
break;
case 5:
m8260.brgc6 = M8260_BRG_RST;
m8260.brgc6 = m8xx_get_brg_cd(baud);
break;
case 6:
m8260.brgc7 = M8260_BRG_RST;
m8260.brgc7 = m8xx_get_brg_cd(baud);
break;
case 7:
m8260.brgc8 = M8260_BRG_RST;
m8260.brgc8 = m8xx_get_brg_cd(baud);
break;
}
return i;
}
else {
printk( "Could not assign a brg for %d\n", baud );
return -1;
}
}
/*
* When the brg is no longer needed call this routine to free the
* resource for re--use.
*/
void
m8xx_free_brg( int brg_num )
{
if( (brg_num>=0) && (brg_num<NUM_BRGS) )
if(brg_use_count[brg_num] > 0 )
brg_use_count[brg_num]--;
}
void m8xx_dump_brgs( void )
{
int i;
for(i=0; i<NUM_BRGS; i++ )
printk( "Brg[%d]: %d %d\n", i, brg_use_count[i], brg_spd[i] );
}
/*
* Reserve one of a range of clock inputs
*/
int
m8xx_get_clk( unsigned clkmask )
{
int i;
for ( i = 0; i < NUM_CLKS; i++ ) {
if (((1<<i) & clkmask) && (clk_use_count[i] == 0)) {
break;
}
}
if (i != NUM_CLKS) {
clk_use_count[i]++;
return i;
} else {
printk( "Could not assign clock in the range %X\n", clkmask );
return -1;
}
}
/*
* When the clock is no longer needed call this routine to free the
* resource for re--use.
*/
void
m8xx_free_clk( int clk_num )
{
if( (clk_num>=0) && (clk_num<NUM_BRGS) )
if(clk_use_count[clk_num] > 0 )
clk_use_count[clk_num]--;
}

View File

@@ -0,0 +1,35 @@
/*
* cp.c
*
* MPC8xx CPM RISC Communication Processor routines.
*
* Based on code (alloc860.c in eth_comm port) by
* Jay Monkman (jmonkman@frasca.com),
* which, in turn, is based on code by
* W. Eric Norum (eric@skatter.usask.ca).
*
* Modifications by Darlene Stewart (Darlene.Stewart@iit.nrc.ca):
* Copyright (c) 1999, National Research Council of Canada
*/
#include <rtems.h>
#include <mpc8260.h>
#include <mpc8260/cpm.h>
/*
* Send a command to the CPM RISC processer
*/
void m8xx_cp_execute_cmd( unsigned32 command )
{
rtems_unsigned16 lvl;
rtems_interrupt_disable(lvl);
while (m8260.cpcr & M8260_CR_FLG) {
continue;
}
m8260.cpcr = command | M8260_CR_FLG;
rtems_interrupt_enable (lvl);
}

View File

@@ -0,0 +1,91 @@
/*
* dpram.c
*
* MPC8260 dual-port RAM allocation routines
*
* Based on code in mpc8xx which is
* Based on code (alloc860.c in eth_comm port) by
* Jay Monkman (jmonkman@frasca.com),
* which, in turn, is based on code by
* W. Eric Norum (eric@skatter.usask.ca).
*
*
* Modifications :
* Copyright (c) 1999, National Research Council of Canada
*
* MPC8260 modifications Andy Dachs, <a.dachs@sstl.co.uk>
* Surrey Satellite Technology Limited, 2001
*/
#include <rtems.h>
#include <mpc8260.h>
#include <mpc8260/cpm.h>
/*
* Allocation order:
* - Dual-Port RAM section 0
* - Dual-Port RAM section 1
* - Dual-Port RAM section 2
* - Dual-Port RAM section 3
*/
static struct {
unsigned8 *base;
unsigned int size;
unsigned int used;
} dpram_regions[] = {
/* { (char *)&m8260.dpram0[0], sizeof m8260.dpram0, 0 },*/
{ (char *)&m8260.dpram1[0], sizeof m8260.dpram1, 0 },
/* { (char *)&m8260.dpram2[0], sizeof m8260.dpram2, 0 },*/
{ (char *)&m8260.dpram3[0], sizeof m8260.dpram3, 0 }
};
#define NUM_DPRAM_REGIONS (sizeof(dpram_regions) / sizeof(dpram_regions[0]))
void *
m8xx_dpram_allocate( unsigned int byte_count )
{
unsigned int i;
ISR_Level level;
void *blockp = NULL;
byte_count = (byte_count + 3) & ~0x3;
/*
* Running with interrupts disabled is usually considered bad
* form, but this routine is probably being run as part of an
* initialization sequence so the effect shouldn't be too severe.
*/
_ISR_Disable (level);
for ( i = 0; i < NUM_DPRAM_REGIONS; i++ ) {
/*
* Verify that the region is available for use.
* This test is necessary because if extra microcode modules
* are installed, some regions are locked and unavailable.
* See MPC860 User's Manual Pages 19-9 to 19-11.
*/
if (dpram_regions[i].used == 0) {
volatile unsigned char *cp = dpram_regions[i].base;
*cp = 0xAA;
if (*cp != 0xAA)
dpram_regions[i].used = dpram_regions[i].size;
else {
*cp = 0x55;
if (*cp != 0x55)
dpram_regions[i].used = dpram_regions[i].size;
}
*cp = 0x0;
}
if (dpram_regions[i].size - dpram_regions[i].used >= byte_count) {
blockp = dpram_regions[i].base + dpram_regions[i].used;
dpram_regions[i].used += byte_count;
break;
}
}
_ISR_Enable(level);
if (blockp == NULL)
rtems_panic("Can't allocate %d bytes of dual-port RAM.\n", byte_count);
return blockp;
}

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,43 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/exceptions.rel
C_FILES = raw_exception.c
S_FILES = asm_utils.S
H_FILES = raw_exception.h
exceptions_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o) \
$(S_FILES:%.S=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/compile.am
include $(top_srcdir)/../../../../../automake/lib.am
$(PROJECT_INCLUDE)/libcpu:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/libcpu/%.h: %.h
$(INSTALL_DATA) $< $@
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(exceptions_rel_OBJECTS)
$(make-rel)
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu \
$(PROJECT_INCLUDE)/libcpu/raw_exception.h
all-local: $(ARCH) $(PREINSTALL_FILES) $(exceptions_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = asm_utils.S raw_exception.c raw_exception.h
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,65 @@
/*
* asm_utils.s
*
* $Id$
*
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
*
* This file contains the low-level support for moving exception
* exception code to appropriate location.
*
*/
#include <libcpu/cpu.h>
#include <libcpu/io.h>
#include <rtems/score/targopts.h>
#include "asm.h"
.globl codemove
codemove:
.type codemove,@function
/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */
cmplw cr1,r3,r4
addi r0,r5,3
srwi. r0,r0,2
beq cr1,4f /* In place copy is not necessary */
beq 7f /* Protect against 0 count */
mtctr r0
bge cr1,2f
la r8,-4(r4)
la r7,-4(r3)
1: lwzu r0,4(r8)
stwu r0,4(r7)
bdnz 1b
b 4f
2: slwi r0,r0,2
add r8,r4,r0
add r7,r3,r0
3: lwzu r0,-4(r8)
stwu r0,-4(r7)
bdnz 3b
/* Now flush the cache: note that we must start from a cache aligned
* address. Otherwise we might miss one cache line.
*/
4: cmpwi r6,0
add r5,r3,r5
beq 7f /* Always flush prefetch queue in any case */
subi r0,r6,1
andc r3,r3,r0
mr r4,r3
5: cmplw r4,r5
dcbst 0,r4
add r4,r4,r6
blt 5b
sync /* Wait for all dcbst to complete on bus */
mr r4,r3
6: cmplw r4,r5
icbi 0,r4
add r4,r4,r6
blt 6b
7: sync /* Wait for all icbi to complete on bus */
isync
blr

View File

@@ -0,0 +1,205 @@
/*
* raw_exception.c - This file contains implementation of C function to
* Instanciate 8xx ppc primary exception entries.
* More detailled information can be found on motorola
* site and more precisely in the following book :
*
* MPC860
* Risc Microporcessor User's Manual
* Motorola REF : MPC860UM/AD
*
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
* Canon Centre Recherche France.
*
* Modified for mpc8260 by Andy Dachs <a.dachs@sstl.co.uk>
* Surrey Satellite Technology Limited (SSTL), 2001
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems/score/targopts.h>
#include <rtems/score/ppc.h>
#include <rtems/system.h>
#include <rtems/score/cpu.h>
#include <libcpu/raw_exception.h>
#include <libcpu/cpu.h>
static rtems_raw_except_connect_data* raw_except_table;
static rtems_raw_except_connect_data default_raw_except_entry;
static rtems_raw_except_global_settings* local_settings;
int mpc8260_vector_is_valid(rtems_vector vector)
{
switch(vector) {
case ASM_RESET_VECTOR: /* fall through */
case ASM_MACH_VECTOR:
case ASM_PROT_VECTOR:
case ASM_ISI_VECTOR:
case ASM_EXT_VECTOR:
case ASM_ALIGN_VECTOR:
case ASM_PROG_VECTOR:
case ASM_FLOAT_VECTOR:
case ASM_DEC_VECTOR:
case ASM_SYS_VECTOR:
case ASM_TRACE_VECTOR:
case ASM_FLOATASSIST_VECTOR:
case ASM_ITLBMISS_VECTOR:
case ASM_DTLBLMISS_VECTOR:
case ASM_DTLBSMISS_VECTOR:
case ASM_IBREAK_VECTOR:
case ASM_SYSMANAGE_VECTOR:
return 1;
default: return 0;
}
}
int mpc8xx_vector_is_valid(rtems_vector vector)
{
switch (current_ppc_cpu) {
case PPC_8260:
if (!mpc8260_vector_is_valid(vector)) {
return 0;
}
break;
default:
printk("Please complete libcpu/powerpc/mpc8xx/exceptions/raw_exception.c\n");
printk("current_ppc_cpu = %x\n", current_ppc_cpu);
return 0;
}
return 1;
}
int mpc8xx_set_exception (const rtems_raw_except_connect_data* except)
{
unsigned int level;
if (!mpc8xx_vector_is_valid(except->exceptIndex)) {
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
* You must first get the current handler via mpc8xx_get_current_exception
* and then disconnect it using mpc8xx_delete_exception.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (memcmp(mpc8xx_get_vector_addr(except->exceptIndex), (void*)default_raw_except_entry.hdl.raw_hdl,default_raw_except_entry.hdl.raw_hdl_size)) {
return 0;
}
_CPU_ISR_Disable(level);
raw_except_table [except->exceptIndex] = *except;
/*
memmove((void*)mpc8xx_get_vector_addr(except->exceptIndex),
except->hdl.raw_hdl,
except->hdl.raw_hdl_size
);
*/
codemove((void*)mpc8xx_get_vector_addr(except->exceptIndex),
except->hdl.raw_hdl,
except->hdl.raw_hdl_size,
PPC_CACHE_ALIGNMENT);
except->on(except);
_CPU_ISR_Enable(level);
return 1;
}
int mpc8xx_get_current_exception (rtems_raw_except_connect_data* except)
{
if (!mpc8xx_vector_is_valid(except->exceptIndex)){
return 0;
}
*except = raw_except_table [except->exceptIndex];
return 1;
}
int mpc8xx_delete_exception (const rtems_raw_except_connect_data* except)
{
unsigned int level;
if (!mpc8xx_vector_is_valid(except->exceptIndex)){
return 0;
}
/*
* Check if handler passed is actually connected. If not issue an error.
* You must first get the current handler via mpc8xx_get_current_exception
* and then disconnect it using mpc8xx_delete_exception.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (memcmp(mpc8xx_get_vector_addr(except->exceptIndex),
(void*)except->hdl.raw_hdl,
except->hdl.raw_hdl_size)) {
return 0;
}
_CPU_ISR_Disable(level);
except->off(except);
codemove((void*)mpc8xx_get_vector_addr(except->exceptIndex),
default_raw_except_entry.hdl.raw_hdl,
default_raw_except_entry.hdl.raw_hdl_size,
PPC_CACHE_ALIGNMENT);
raw_except_table[except->exceptIndex] = default_raw_except_entry;
raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
_CPU_ISR_Enable(level);
return 1;
}
/*
* Exception global init.
*/
int mpc8xx_init_exceptions (rtems_raw_except_global_settings* config)
{
unsigned i;
unsigned int level;
/*
* store various accelerators
*/
raw_except_table = config->rawExceptHdlTbl;
local_settings = config;
default_raw_except_entry = config->defaultRawEntry;
_CPU_ISR_Disable(level);
for (i=0; i <= LAST_VALID_EXC; i++) {
if (!mpc8xx_vector_is_valid(i)){
continue;
}
codemove((void*)mpc8xx_get_vector_addr(i),
raw_except_table[i].hdl.raw_hdl,
raw_except_table[i].hdl.raw_hdl_size,
PPC_CACHE_ALIGNMENT);
if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
raw_except_table[i].on(&raw_except_table[i]);
}
else {
raw_except_table[i].off(&raw_except_table[i]);
}
}
_CPU_ISR_Enable(level);
return 1;
}
int mpc8xx_get_exception_config (rtems_raw_except_global_settings** config)
{
*config = local_settings;
return 1;
}

View File

@@ -0,0 +1,183 @@
/*
* raw_execption.h
*
* This file contains implementation of C function to
* Instanciate 8xx ppc primary exception entries.
* More detailled information can be found on motorola
* site and more precisely in the following book :
*
* MPC860
* Risc Microporcessor User's Manual
* Motorola REF : MPC860UM/AD 07/98 Rev .1
*
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
* Canon Centre Recherche France.
*
* Modified Andy Dachs <a.dachs@sstl.co.uk>
* Surrey Satellite Technology Limited (SSTL), 2001
* for MPC8260
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef _LIBCPU_MPC8XX_EXCEPTION_RAW_EXCEPTION_H
#define _LIBCPU_MPC8XX_EXCEPTION_RAW_EXCEPTION_H
/*
* Exception Vectors as defined in the MCP750 manual
*/
#define ASM_RESET_VECTOR 0x01
#define ASM_MACH_VECTOR 0x02
#define ASM_PROT_VECTOR 0x03
#define ASM_ISI_VECTOR 0x04
#define ASM_EXT_VECTOR 0x05
#define ASM_ALIGN_VECTOR 0x06
#define ASM_PROG_VECTOR 0x07
#define ASM_FLOAT_VECTOR 0x08
#define ASM_DEC_VECTOR 0x09
#define ASM_SYS_VECTOR 0x0C
#define ASM_TRACE_VECTOR 0x0D
#define ASM_FLOATASSIST_VECTOR 0x0E
#define ASM_ITLBMISS_VECTOR 0x10
#define ASM_DTLBLMISS_VECTOR 0x11
#define ASM_DTLBSMISS_VECTOR 0x12
#define ASM_IBREAK_VECTOR 0x13
#define ASM_SYSMANAGE_VECTOR 0x14
#define LAST_VALID_EXC ASM_SYSMANAGE_VECTOR
/*
* Vector offsets as defined in the MPC8260 manual
*/
#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8)
#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8)
#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8)
#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8)
#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8)
#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8)
#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8)
#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8)
#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8)
#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8)
#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8)
#define ASM_FLOATASSIST_VECTOR_OFFSET (ASM_FLOATASSIST_VECTOR << 8)
#define ASM_ITLBMISS_VECTOR_OFFSET (ASM_ITLBMISS_VECTOR << 8)
#define ASM_DTLBLMISS_VECTOR_OFFSET (ASM_DTLBLMISS_VECTOR << 8)
#define ASM_DTLBSMISS_VECTOR_OFFSET (ASM_DTLBSMISS_VECTOR << 8)
#define ASM_IBREAK_VECTOR_OFFSET (ASM_IBREAK_VECTOR << 8)
#define ASM_SYSMANAGE_VECTOR_OFFSET (ASM_SYSMANAGE_VECTOR << 8)
#ifndef ASM
/*
* Type definition for raw exceptions.
*/
typedef unsigned char rtems_vector;
struct __rtems_raw_except_connect_data__;
typedef void (*rtems_raw_except_func) (void);
typedef unsigned char rtems_raw_except_hdl_size;
typedef struct {
rtems_vector vector;
rtems_raw_except_func raw_hdl;
rtems_raw_except_hdl_size raw_hdl_size;
}rtems_raw_except_hdl;
typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*);
typedef void (*rtems_raw_except_disable) (const struct __rtems_raw_except_connect_data__*);
typedef int (*rtems_raw_except_is_enabled) (const struct __rtems_raw_except_connect_data__*);
typedef struct __rtems_raw_except_connect_data__{
/*
* Exception vector (As defined in the manual)
*/
rtems_vector exceptIndex;
/*
* Exception raw handler. See comment on handler properties below in function prototype.
*/
rtems_raw_except_hdl hdl;
/*
* function for enabling raw exceptions. In order to be consistent
* with the fact that the raw connexion can defined in the
* libcpu library, this library should have no knowledge of
* board specific hardware to manage exceptions and thus the
* "on" routine must enable the except at processor level only.
*
*/
rtems_raw_except_enable on;
/*
* function for disabling raw exceptions. In order to be consistent
* with the fact that the raw connexion can defined in the
* libcpu library, this library should have no knowledge of
* board specific hardware to manage exceptions and thus the
* "on" routine must disable the except both at device and PIC level.
*
*/
rtems_raw_except_disable off;
/*
* function enabling to know what exception may currently occur
*/
rtems_raw_except_is_enabled isOn;
}rtems_raw_except_connect_data;
typedef struct {
/*
* size of all the table fields (*Tbl) described below.
*/
unsigned int exceptSize;
/*
* Default handler used when disconnecting exceptions.
*/
rtems_raw_except_connect_data defaultRawEntry;
/*
* Table containing initials/current value.
*/
rtems_raw_except_connect_data* rawExceptHdlTbl;
}rtems_raw_except_global_settings;
/*
* C callable function enabling to set up one raw idt entry
*/
extern int mpc8xx_set_exception (const rtems_raw_except_connect_data*);
/*
* C callable function enabling to get one current raw idt entry
*/
extern int mpc8xx_get_current_exception (rtems_raw_except_connect_data*);
/*
* C callable function enabling to remove one current raw idt entry
*/
extern int mpc8xx_delete_exception (const rtems_raw_except_connect_data*);
/*
* C callable function enabling to check if vector is valid
*/
extern int mpc8xx_vector_is_valid(rtems_vector vector);
inline static void* mpc8xx_get_vector_addr(rtems_vector vector)
{
return ((void*) (((unsigned) vector) << 8));
}
/*
* Exception global init.
*/
extern int mpc8xx_init_exceptions (rtems_raw_except_global_settings* config);
extern int mpc8xx_get_exception_config (rtems_raw_except_global_settings** config);
# endif /* ASM */
#endif

View File

@@ -0,0 +1,27 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = mpc8260.h
MPC8260_H_FILES = console.h mmu.h cpm.h
noinst_HEADERS = $(H_FILES) $(MPC8260_H_FILES)
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc8260 \
$(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h) \
$(MPC8260_H_FILES:%.h=$(PROJECT_INCLUDE)/mpc8260/%.h)
$(PROJECT_INCLUDE)/mpc8260:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/mpc8260/%.h: %.h
$(INSTALL_DATA) $< $@
all-local: $(PREINSTALL_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,65 @@
/*
* $Id$
*/
#ifndef _M8260_CONSOLE_H_
#define _M8260_CONSOLE_H_
#include <rtems/libio.h>
void m8xx_uart_reserve_resources(rtems_configuration_table *configuration);
void m8xx_uart_initialize(void);
void m8xx_uart_interrupts_initialize(void);
void m8xx_uart_scc_initialize (int minor);
void m8xx_uart_smc_initialize (int minor);
/* Termios callbacks */
int m8xx_uart_pollRead(int minor);
int m8xx_uart_pollWrite(int minor, const char* buf, int len);
int m8xx_uart_write(int minor, const char *buf, int len);
int m8xx_uart_setAttributes(int, const struct termios* t);
#if 0
int m8260_smc_set_attributes(int, const struct termios*);
int m8260_scc_set_attributes(int, const struct termios*);
void m8260_scc_initialize(int);
void m8260_smc_initialize(int);
int m8260_char_poll_read(int);
int m8260_char_poll_write(int, const char*, int);
rtems_isr m8260_scc1_console_interrupt_handler(rtems_vector_number);
rtems_isr m8260_scc2_console_interrupt_handler(rtems_vector_number);
rtems_isr m8260_scc3_console_interrupt_handler(rtems_vector_number);
rtems_isr m8260_scc4_console_interrupt_handler(rtems_vector_number);
rtems_isr m8260_smc1_console_interrupt_handler(rtems_vector_number);
rtems_isr m8260_smc2_console_interrupt_handler(rtems_vector_number);
int m8260_buf_poll_read(int, char**);
int m8260_buf_poll_write(int, char*, int);
void m8260_console_initialize(void);
rtems_device_driver m8260_console_read(rtems_device_major_number,
rtems_device_minor_number,
void*);
rtems_device_driver m8260_console_write(rtems_device_major_number,
rtems_device_minor_number,
void*);
typedef struct Buf_t_ {
struct Buf_t_ *next;
volatile char *buf;
volatile int len;
int pos;
} Buf_t;
#endif
#define NUM_PORTS 6
#define SMC1_MINOR 0
#define SMC2_MINOR 1
#define SCC1_MINOR 2
#define SCC2_MINOR 3
#define SCC3_MINOR 4
#define SCC4_MINOR 5
#endif

View File

@@ -0,0 +1,123 @@
/*
* cpm.h
*
* This include file contains definitions pertaining
* to the Communications Processor Module (CPM) on the MPC8xx.
*
* 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.
*/
#ifndef __M8xx_CPM_h
#define __M8xx_CPM_h
#ifdef __cplusplus
extern "C" {
#endif
#define M8xx_BRG_1 (1U << 0)
#define M8xx_BRG_2 (1U << 1)
#define M8xx_BRG_3 (1U << 2)
#define M8xx_BRG_4 (1U << 3)
#define M8xx_BRG_5 (1U << 4)
#define M8xx_BRG_6 (1U << 5)
#define M8xx_BRG_7 (1U << 6)
#define M8xx_BRG_8 (1U << 7)
#define M8260_SCC_BRGS (M8xx_BRG_1 | M8xx_BRG_2 | M8xx_BRG_3 | M8xx_BRG_4)
#define M8260_FCC_BRGS (M8xx_BRG_5 | M8xx_BRG_6 | M8xx_BRG_7 | M8xx_BRG_8)
#define M8260_SMC1_BRGS (M8xx_BRG_1|M8xx_BRG_7)
#define M8260_SMC2_BRGS (M8xx_BRG_2|M8xx_BRG_8)
#define M8xx_CLK_1 (1U << 0)
#define M8xx_CLK_2 (1U << 1)
#define M8xx_CLK_3 (1U << 2)
#define M8xx_CLK_4 (1U << 3)
#define M8xx_CLK_5 (1U << 4)
#define M8xx_CLK_6 (1U << 5)
#define M8xx_CLK_7 (1U << 6)
#define M8xx_CLK_8 (1U << 7)
#define M8xx_CLK_9 (1U << 8)
#define M8xx_CLK_10 (1U << 9)
#define M8xx_CLK_11 (1U << 10)
#define M8xx_CLK_12 (1U << 11)
#define M8xx_CLK_13 (1U << 12)
#define M8xx_CLK_14 (1U << 13)
#define M8xx_CLK_15 (1U << 14)
#define M8xx_CLK_16 (1U << 15)
#define M8xx_CLK_17 (1U << 16)
#define M8xx_CLK_18 (1U << 17)
#define M8xx_CLK_19 (1U << 18)
#define M8xx_CLK_20 (1U << 19)
#define M8260_BRG1_CLKS (M8xx_CLK_3 | M8xx_CLK_5 )
#define M8260_BRG2_CLKS (M8xx_CLK_3 | M8xx_CLK_5 )
#define M8260_BRG3_CLKS (M8xx_CLK_9 | M8xx_CLK_15 )
#define M8260_BRG4_CLKS (M8xx_CLK_9 | M8xx_CLK_15 )
#define M8260_BRG5_CLKS (M8xx_CLK_3 | M8xx_CLK_5 )
#define M8260_BRG6_CLKS (M8xx_CLK_3 | M8xx_CLK_5 )
#define M8260_BRG7_CLKS (M8xx_CLK_9 | M8xx_CLK_15 )
#define M8260_BRG8_CLKS (M8xx_CLK_9 | M8xx_CLK_15 )
#define M8260_SCC1_CLKS (M8xx_CLK_3 | M8xx_CLK_4 | M8xx_CLK_11 | M8xx_CLK_12)
#define M8260_SCC2_CLKS (M8xx_CLK_3 | M8xx_CLK_4 | M8xx_CLK_11 | M8xx_CLK_12)
#define M8260_SCC3_CLKS (M8xx_CLK_5 | M8xx_CLK_6 | M8xx_CLK_7 | M8xx_CLK_8 )
#define M8260_SCC4_CLKS (M8xx_CLK_5 | M8xx_CLK_6 | M8xx_CLK_7 | M8xx_CLK_8 )
#define M8260_FCC1_CLKS (M8xx_CLK_9 | M8xx_CLK_10 | M8xx_CLK_11 | M8xx_CLK_12)
#define M8260_FCC2_CLKS (M8xx_CLK_13 | M8xx_CLK_14 | M8xx_CLK_15 | M8xx_CLK_16)
#define M8260_FCC3_CLKS (M8xx_CLK_13 | M8xx_CLK_14 | M8xx_CLK_15 | M8xx_CLK_16)
#define M8260_TDM_RXA1 (M8xx_CLK_1 | M8xx_CLK_19 )
#define M8260_TDM_RXB1 (M8xx_CLK_3 | M8xx_CLK_9 )
#define M8260_TDM_RXC1 (M8xx_CLK_5 | M8xx_CLK_13 )
#define M8260_TDM_RXD1 (M8xx_CLK_7 | M8xx_CLK_15 )
#define M8260_TDM_TXA1 (M8xx_CLK_2 | M8xx_CLK_20 )
#define M8260_TDM_TXB1 (M8xx_CLK_4 | M8xx_CLK_10 )
#define M8260_TDM_TXC1 (M8xx_CLK_6 | M8xx_CLK_14 )
#define M8260_TDM_TXD1 (M8xx_CLK_8 | M8xx_CLK_16 )
#define M8260_TDM_RXA2 (M8xx_CLK_13 | M8xx_CLK_5 )
#define M8260_TDM_RXB2 (M8xx_CLK_15 | M8xx_CLK_17 )
#define M8260_TDM_RXC2 (M8xx_CLK_3 | M8xx_CLK_17 )
#define M8260_TDM_RXD2 (M8xx_CLK_1 | M8xx_CLK_19 )
#define M8260_TDM_TXA2 (M8xx_CLK_14 | M8xx_CLK_6 )
#define M8260_TDM_TXB2 (M8xx_CLK_16 | M8xx_CLK_18 )
#define M8260_TDM_TXC2 (M8xx_CLK_4 | M8xx_CLK_18 )
#define M8260_TDM_TXD2 (M8xx_CLK_2 | M8xx_CLK_20 )
/* Functions */
void m8xx_cp_execute_cmd( unsigned32 command );
void *m8xx_dpram_allocate( unsigned int byte_count );
#define m8xx_bd_allocate(count) \
m8xx_dpram_allocate( (count) * sizeof(m8260BufferDescriptor_t) )
#define m8xx_RISC_timer_table_allocate(count) \
m8xx_dpram_allocate( (count) * 4 )
int m8xx_get_brg_cd (int baud);
int m8xx_get_brg(unsigned brgmask, int baud);
void m8xx_free_brg(int brg_num);
int m8xx_get_clk( unsigned clkmask );
void m8xx_free_clk( int clk_num );
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,47 @@
/*
* mmu.h
*
* This include file contains definitions pertaining
* to the MMU on the MPC8xx.
*
* 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.
*/
#ifndef __M8260_MMU_h
#define __M8260_MMU_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* The MMU_TLB_table is used to statically initialize the Table Lookaside
* Buffers in the MMU of an MPC8260.
*/
typedef struct {
unsigned32 mmu_epn; /* Effective Page Number */
unsigned32 mmu_twc; /* Tablewalk Control Register */
unsigned32 mmu_rpn; /* Real Page Number */
} MMU_TLB_table_t;
/*
* The MMU_TLB_table and its size, MMU_N_TLB_Table_Entries, must be
* supplied by the BSP.
*/
extern MMU_TLB_table_t MMU_TLB_table[]; /* MMU TLB table supplied by BSP */
extern int MMU_N_TLB_Table_Entries; /* Number of entries in MMU TLB table */
/* Functions */
void mmu_init( void );
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/mmu.rel
## C sources
C_FILES = mmu.c
clock_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/compile.am
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(clock_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,130 @@
/*
* mmu.c
*
* This file contains routines for initializing
* and manipulating the MMU on the MPC8xx.
*
* Copyright (c) 1999, National Research Council of Canada
*
* Trivially modified for mpc8260 21.3.2001
* Andy Dachs <a.dachs@sstl.co.uk>
*
* 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 <rtems.h>
#include <mpc8260.h>
#include <mpc8260/mmu.h>
/*
* mmu_init
*
* This routine sets up the virtual memory maps on an MPC8xx.
* The MPC8xx does not support block address translation (BATs)
* and does not have segment registers. Thus, we must set up page
* translation. However, its MMU supports variable size pages
* (1-, 4-, 16-, 512-Kbyte or 8-Mbyte), which simplifies the task.
*
* The MPC8xx has separate data and instruction 32-entry translation
* lookaside buffers (TLB). By mapping all of DRAM as one huge page,
* we can preload the TLBs and not have to be concerned with taking
* TLB miss exceptions.
*
* We set up the virtual memory map so that virtual address of a
* location is equal to its real address.
*/
void mmu_init( void )
{
#if 0
/* so far we leave mmu uninitialised */
register unsigned32 reg1, i;
/*
* Initialize the TLBs
*
* Instruction address translation and data address translation
* must be disabled during initialization (IR=0, DR=0 in MSR).
* We can assume the MSR has already been set this way.
*/
/*
* Initialize IMMU & DMMU Control Registers (MI_CTR & MD_CTR)
* GPM [0] 0b0 = PowerPC mode
* PPM [1] 0b0 = Page resolution of protection
* CIDEF [2] 0b0/0b1 = Default cache-inhibit attribute =
* NO for IMMU, YES for DMMU!
* reserved/WTDEF [3] 0b0 = Default write-through attribute = not
* RSV4x [4] 0b0 = 4 entries not reserved
* reserved/TWAM [5] 0b0/0b1 = 4-Kbyte page hardware assist
* PPCS [6] 0b0 = Ignore user/supervisor state
* reserved [7-18] 0x00
* xTLB_INDX [19-23] 31 = 0x1F
* reserved [24-31] 0x00
*
* Note: It is important that cache-inhibit be set as the default for the
* data cache when the DMMU is disabled in order to prevent internal memory
* mapped registers from being cached accidentally when address translation
* is turned off at the start of exception processing.
*/
reg1 = M8xx_MI_CTR_ITLB_INDX(31);
_mtspr( M8xx_MI_CTR, reg1 );
reg1 = M8xx_MD_CTR_CIDEF | M8xx_MD_CTR_TWAM | M8xx_MD_CTR_DTLB_INDX(31);
_mtspr( M8xx_MD_CTR, reg1 );
_isync;
/*
* Invalidate all TLB entries in both TLBs.
* Note: We rely on the RSV4 bit in MI_CTR and MD_CTR being 0b0, so
* all 32 entries are invalidated.
*/
__asm__ volatile ("tlbia\n"::);
_isync;
/*
* Set Current Address Space ID Register (M_CASID).
* Supervisor: CASID = 0
*/
reg1 = 0;
_mtspr( M8xx_M_CASID, reg1 );
/*
* Initialize the MMU Access Protection Registers (MI_AP, MD_AP)
* We ignore the Access Protection Group (APG) mechanism globally
* by setting all of the Mx_AP fields to 0b01 : client access
* permission is defined by page protection bits.
*/
reg1 = 0x55555555;
_mtspr( M8xx_MI_AP, reg1 );
_mtspr( M8xx_MD_AP, reg1 );
/*
* Load both 32-entry TLBs with values from the MMU_TLB_table
* which is defined in the BSP.
* Note the _TLB_Table must have at most 32 entries. This code
* makes no effort to enforce this restriction.
*/
for( i = 0; i < MMU_N_TLB_Table_Entries; ++i ) {
reg1 = MMU_TLB_table[i].mmu_epn;
_mtspr( M8xx_MI_EPN, reg1 );
_mtspr( M8xx_MD_EPN, reg1 );
reg1 = MMU_TLB_table[i].mmu_twc;
_mtspr( M8xx_MI_TWC, reg1 );
_mtspr( M8xx_MD_TWC, reg1 );
reg1 = MMU_TLB_table[i].mmu_rpn; /* RPN must be written last! */
_mtspr( M8xx_MI_RPN, reg1 );
_mtspr( M8xx_MD_RPN, reg1 );
}
/*
* Turn on address translation by setting MSR[IR] and MSR[DR].
*/
_CPU_MSR_Value( reg1 );
reg1 |= PPC_MSR_IR | PPC_MSR_DR;
_CPU_MSR_SET( reg1 );
#endif
}

View File

@@ -0,0 +1,29 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/timer.rel
## C sources
C_FILES = timer.c
timer_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/compile.am
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(timer_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,116 @@
/* timer.c
*
* This file manages the interval timer on the PowerPC MPC860.
* NOTE: This is not the PIT, but rather the RTEMS interval
* timer
* We shall use the bottom 32 bits of the timebase register,
*
* The following was in the 403 version of this file. I don't
* know what it means. JTM 5/19/98
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* Author: Andy Dachs <a.dachs@sstl.co.uk>
* Surrey Satellite Technlogy Limited
* Modified for MPC8260
* Derived from c/src/lib/libcpu/powerpc/mpc860/timer/timer.c:
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copywright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/timer/timer.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* 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.
*
* Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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 <mpc8260.h>
static volatile rtems_unsigned32 Timer_starting;
static rtems_boolean Timer_driver_Find_average_overhead;
extern rtems_cpu_table Cpu_table;
#define rtems_cpu_configuration_get_timer_average_overhead() \
(Cpu_table.timer_average_overhead)
#define rtems_cpu_configuration_get_timer_least_valid() \
(Cpu_table.timer_least_valid)
/*
* This is so small that this code will be reproduced where needed.
*/
static inline rtems_unsigned32 get_itimer(void)
{
rtems_unsigned32 ret;
asm volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
return ret;
}
void Timer_initialize(void)
{
/* set interrupt level and enable timebase. This should never */
/* generate an interrupt however. */
/*
m860.tbscr |= M860_TBSCR_TBIRQ(4) | M860_TBSCR_TBE;
*/
Timer_starting = get_itimer();
}
int Read_timer(void)
{
rtems_unsigned32 clicks;
rtems_unsigned32 total;
clicks = get_itimer();
total = clicks - Timer_starting;
if ( Timer_driver_Find_average_overhead == 1 )
return total; /* in XXX microsecond units */
else {
if ( total < rtems_cpu_configuration_get_timer_least_valid() ) {
return 0; /* below timer resolution */
}
return (total - rtems_cpu_configuration_get_timer_average_overhead());
}
}
rtems_status_code Empty_function(void)
{
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
}