2001-03-30 Eric Valette <valette@crf.canon.fr>

* mpc8xx/exceptions/.cvsignore, mpc8xx/exceptions/Makefile.am,
	mpc8xx/exceptions/asm_utils.S, mpc8xx/exceptions/raw_exception.c,
	mpc8xx/exceptions/raw_exception.h: New files.
	* configure.in, mpc6xx/mmu/bat.h, mpc8xx/Makefile.am,
	mpc8xx/clock/clock.c,
	mpc8xx/console-generic/console-generic.c,
	mpc8xx/include/mpc8xx.h, mpc8xx/mmu/mmu.c,
	new_exception_processing/cpu.h, shared/include/byteorder.h,
	wrapup/Makefile.am:  This is conversion of the
	mpc8xx CPU to the "new exception processing model."
This commit is contained in:
Joel Sherrill
2001-04-06 15:54:20 +00:00
parent 35bb69b1cd
commit 37731c2bd8
17 changed files with 734 additions and 140 deletions

View File

@@ -440,6 +440,20 @@ typedef struct {
unsigned32 clicks_per_usec; /* Timer clicks per microsecond */
boolean exceptions_in_RAM; /* TRUE if in RAM */
#if (defined(ppc403) || defined(mpc860) || defined(mpc821))
unsigned32 serial_per_sec; /* Serial clocks per second */
boolean serial_external_clock;
boolean serial_xon_xoff;
boolean serial_cts_rts;
unsigned32 serial_rate;
unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */
unsigned32 timer_least_valid; /* Least valid number from timer */
boolean timer_internal_clock; /* TRUE, when timer runs with CPU clk */
#endif
#if (defined(mpc860) || defined(mpc821))
unsigned32 clock_speed; /* Speed of CPU in Hz */
#endif
} rtems_cpu_table;
/*

View File

@@ -1,3 +1,16 @@
2001-03-30 Eric Valette <valette@crf.canon.fr>
* mpc8xx/exceptions/.cvsignore, mpc8xx/exceptions/Makefile.am,
mpc8xx/exceptions/asm_utils.S, mpc8xx/exceptions/raw_exception.c,
mpc8xx/exceptions/raw_exception.h: New files.
* configure.in, mpc6xx/mmu/bat.h, mpc8xx/Makefile.am,
mpc8xx/clock/clock.c,
mpc8xx/console-generic/console-generic.c,
mpc8xx/include/mpc8xx.h, mpc8xx/mmu/mmu.c,
new_exception_processing/cpu.h, shared/include/byteorder.h,
wrapup/Makefile.am: This is conversion of the
mpc8xx CPU to the "new exception processing model."
2001-02-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* mpc505/ictrl/Makefile.am, mpc6xx/clock/Makefile.am,

View File

@@ -37,7 +37,9 @@ AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "mpc750" \
## there are no 601 or 602 BSPs currently. The 505 BSPs are in user land.
AM_CONDITIONAL(new_exception_processing, \
test "$RTEMS_CPU_MODEL" = "mpc750" || \
test "$RTEMS_CPU_MODEL" = "mpc604")
test "$RTEMS_CPU_MODEL" = "mpc604" || \
test "$RTEMS_CPU_MODEL" = "mpc8xx" || \
test "$RTEMS_CPU_MODEL" = "mpc860")
## The goal is to get rid of the old exception processing code but
## but all BSPs in the distribution must be migrated to the new model
@@ -45,8 +47,7 @@ test "$RTEMS_CPU_MODEL" = "mpc604")
AM_CONDITIONAL(old_exception_processing, \
test "$RTEMS_CPU_MODEL" = "ppc403" || \
test "$RTEMS_CPU_MODEL" = "mpc505" || \
test "$RTEMS_CPU_MODEL" = "ppc603e" || \
test "$RTEMS_CPU_MODEL" = "mpc8xx" \
test "$RTEMS_CPU_MODEL" = "ppc603e" \
)
## test on CPU type
@@ -70,10 +71,10 @@ mpc8xx/Makefile
mpc8xx/clock/Makefile
mpc8xx/console-generic/Makefile
mpc8xx/cpm/Makefile
mpc8xx/exceptions/Makefile
mpc8xx/include/Makefile
mpc8xx/mmu/Makefile
mpc8xx/timer/Makefile
mpc8xx/vectors/Makefile
ppc403/Makefile
ppc403/clock/Makefile
ppc403/console/Makefile

View File

@@ -25,7 +25,7 @@
#include <libcpu/mmu.h>
#include <libcpu/pgtable.h>
#include <bsp/consoleIo.h>
#include <bspIo.h>
#define IO_PAGE (_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW)

View File

@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = include console-generic clock timer vectors cpm mmu
SUBDIRS = include console-generic clock timer cpm mmu exceptions
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -45,9 +45,12 @@
volatile rtems_unsigned32 Clock_driver_ticks;
extern volatile m8xx_t m8xx;
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 );
/*
* These are set by clock driver during its init
*/
@@ -65,62 +68,42 @@ rtems_isr Clock_isr(rtems_vector_number vector)
rtems_clock_tick();
}
void Install_clock(rtems_isr_entry clock_isr)
void clockOn(void* unused)
{
#ifdef EPPCBUG_SMC1
extern unsigned32 simask_copy;
#endif /* EPPCBUG_SMC1 */
rtems_isr_entry previous_isr;
unsigned desiredLevel;
rtems_unsigned32 pit_value;
Clock_driver_ticks = 0;
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);
}
/*
* initialize the interval here
* First tick is set to right amount of time in the future
* Future ticks will be incremented over last value set
* in order to provide consistent clicks in the face of
* interrupt overhead
*/
rtems_interrupt_catch(clock_isr, PPC_IRQ_LVL0, &previous_isr);
}
m8xx.sccr &= ~(1<<24);
m8xx.pitc = pit_value;
desiredLevel = BSP_get_clock_irq_level();
/* set PIT irq level, enable PIT, PIT interrupts */
/* and clear int. status */
m8xx.piscr = M8xx_PISCR_PIRQ(0) |
M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE;
#ifdef EPPCBUG_SMC1
simask_copy = m8xx.simask | M8xx_SIMASK_LVM0;
#endif /* EPPCBUG_SMC1 */
m8xx.simask |= M8xx_SIMASK_LVM0;
atexit(Clock_exit);
m8xx.piscr = M8xx_PISCR_PIRQ(desiredLevel) |
M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE;
}
/*
* Called via atexit()
* Remove the clock interrupt handler by setting handler to NULL
*/
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
clockOff(void* unused)
{
rtems_isr_entry previous_isr;
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable(isrlevel);
rtems_interrupt_catch(new_clock_isr, PPC_IRQ_LVL0, &previous_isr);
rtems_interrupt_enable(isrlevel);
/* disable PIT and PIT interrupts */
m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE);
}
int clockIsOn(void* unused)
{
if (m8xx.piscr & M8xx_PISCR_PIE) return 1;
return 0;
}
/*
* Called via atexit()
@@ -129,12 +112,24 @@ ReInstall_clock(rtems_isr_entry new_clock_isr)
void
Clock_exit(void)
{
/* disable PIT and PIT interrupts */
m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE);
(void) set_vector(0, PPC_IRQ_LVL0, 1);
(void) BSP_disconnect_clock_handler ();
}
void Install_clock(rtems_isr_entry clock_isr)
{
Clock_driver_ticks = 0;
BSP_connect_clock_handler (clock_isr);
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,
@@ -142,7 +137,7 @@ rtems_device_driver Clock_initialize(
)
{
Install_clock( Clock_isr );
/*
* make major/minor avail to others such as shared memory driver
*/

View File

@@ -53,16 +53,14 @@
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <bsp/irq.h>
#include <bspIo.h> /* for printk */
extern rtems_cpu_table Cpu_table;
/* BSP supplied routine */
extern int mbx8xx_console_get_configuration();
#ifdef EPPCBUG_SMC1
extern unsigned32 simask_copy;
#endif
/*
* Interrupt-driven input buffer
*/
@@ -88,9 +86,6 @@ static char brg_used[4];
/* Used to track termios private data for callbacks */
struct rtems_termios_tty *ttyp[NUM_PORTS];
/* Used to record previous ISR */
static rtems_isr_entry old_handler[NUM_PORTS];
/*
* Device-specific routines
*/
@@ -99,12 +94,12 @@ static unsigned char m8xx_get_brg_clk(int);
void m8xx_console_reserve_resources(rtems_configuration_table *);
static int m8xx_smc_set_attributes(int, const struct termios*);
static int m8xx_scc_set_attributes(int, const struct termios*);
static rtems_isr m8xx_smc1_interrupt_handler(rtems_vector_number);
static rtems_isr m8xx_smc2_interrupt_handler(rtems_vector_number);
static rtems_isr m8xx_scc2_interrupt_handler(rtems_vector_number);
static void m8xx_smc1_interrupt_handler(void);
static void m8xx_smc2_interrupt_handler(void);
static void m8xx_scc2_interrupt_handler(void);
#if defined(mpc860)
static rtems_isr m8xx_scc3_interrupt_handler(rtems_vector_number);
static rtems_isr m8xx_scc4_interrupt_handler(rtems_vector_number);
static void m8xx_scc3_interrupt_handler(void);
static void m8xx_scc4_interrupt_handler(void);
#endif
/*
@@ -387,8 +382,7 @@ m8xx_uart_setAttributes(
/*
* Interrupt handlers
*/
static rtems_isr
m8xx_scc2_interrupt_handler (rtems_vector_number v)
static void m8xx_scc2_interrupt_handler ()
{
int nb_overflow;
@@ -425,13 +419,12 @@ m8xx_scc2_interrupt_handler (rtems_vector_number v)
(void *)ttyp[SCC2_MINOR],
(int)TxBd[SCC2_MINOR]->length);
}
m8xx.cisr = 1UL << 29; /* Clear SCC2 interrupt-in-service bit */
}
#ifdef mpc860
static rtems_isr
m8xx_scc3_interrupt_handler (rtems_vector_number v)
static void
m8xx_scc3_interrupt_handler (void)
{
int nb_overflow;
@@ -468,12 +461,11 @@ m8xx_scc3_interrupt_handler (rtems_vector_number v)
(void *)ttyp[SCC3_MINOR],
(int)TxBd[SCC3_MINOR]->length);
}
m8xx.cisr = 1UL << 28; /* Clear SCC3 interrupt-in-service bit */
}
static rtems_isr
m8xx_scc4_interrupt_handler (rtems_vector_number v)
static void
m8xx_scc4_interrupt_handler (void)
{
int nb_overflow;
@@ -510,12 +502,11 @@ m8xx_scc4_interrupt_handler (rtems_vector_number v)
(void *)ttyp[SCC4_MINOR],
(int)TxBd[SCC4_MINOR]->length);
}
m8xx.cisr = 1UL << 27; /* Clear SCC4 interrupt-in-service bit */
}
#endif
static rtems_isr
m8xx_smc1_interrupt_handler (rtems_vector_number v)
static void
m8xx_smc1_interrupt_handler (void)
{
int nb_overflow;
@@ -552,12 +543,11 @@ m8xx_smc1_interrupt_handler (rtems_vector_number v)
(void *)ttyp[SMC1_MINOR],
(int)TxBd[SMC1_MINOR]->length);
}
m8xx.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */
}
static rtems_isr
m8xx_smc2_interrupt_handler (rtems_vector_number v)
static void
m8xx_smc2_interrupt_handler (void)
{
int nb_overflow;
@@ -594,16 +584,77 @@ m8xx_smc2_interrupt_handler (rtems_vector_number v)
(void *)ttyp[SMC2_MINOR],
(int)TxBd[SMC2_MINOR]->length);
}
m8xx.cisr = 1UL << 3; /* Clear SMC2 interrupt-in-service bit */
}
void m8xx_scc_enable(const rtems_irq_connect_data* ptr)
{
volatile m8xxSCCRegisters_t *sccregs = 0;
switch (ptr->name) {
#if defined(mpc860)
case BSP_CPM_IRQ_SCC4 :
sccregs = &m8xx.scc4;
break;
case BSP_CPM_IRQ_SCC3 :
sccregs = &m8xx.scc3;
break;
#endif
case BSP_CPM_IRQ_SCC2 :
sccregs = &m8xx.scc2;
break;
case BSP_CPM_IRQ_SCC1 :
sccregs = &m8xx.scc1;
break;
default:
break;
}
sccregs->sccm = 3;
}
void m8xx_scc_disable(const rtems_irq_connect_data* ptr)
{
volatile m8xxSCCRegisters_t *sccregs = 0;
switch (ptr->name) {
#if defined(mpc860)
case BSP_CPM_IRQ_SCC4 :
sccregs = &m8xx.scc4;
break;
case BSP_CPM_IRQ_SCC3 :
sccregs = &m8xx.scc3;
break;
#endif
case BSP_CPM_IRQ_SCC2 :
sccregs = &m8xx.scc2;
break;
case BSP_CPM_IRQ_SCC1 :
sccregs = &m8xx.scc1;
break;
default:
break;
}
sccregs->sccm &= (~3);
}
int m8xx_scc_isOn(const rtems_irq_connect_data* ptr)
{
return BSP_irq_enabled_at_cpm (ptr->name);
}
static rtems_irq_connect_data consoleIrqData =
{
BSP_CPM_IRQ_SCC2,
(rtems_irq_hdl)m8xx_scc2_interrupt_handler,
(rtems_irq_enable) m8xx_scc_enable,
(rtems_irq_disable) m8xx_scc_disable,
(rtems_irq_is_enabled) m8xx_scc_isOn
};
void
m8xx_uart_scc_initialize (int minor)
{
unsigned char brg;
volatile m8xxSCCparms_t *sccparms = 0;
volatile m8xxSCCRegisters_t *sccregs = 0;
int res;
/*
* Check that minor number is valid
@@ -777,37 +828,63 @@ m8xx_uart_scc_initialize (int minor)
if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
switch (minor) {
case SCC2_MINOR:
rtems_interrupt_catch (m8xx_scc2_interrupt_handler,
PPC_IRQ_CPM_SCC2,
&old_handler[minor]);
sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */
m8xx.cimr |= 1UL << 29; /* Enable SCC2 interrupts */
break;
#ifdef mpc860
case SCC3_MINOR:
rtems_interrupt_catch (m8xx_scc3_interrupt_handler,
PPC_IRQ_CPM_SCC3,
&old_handler[minor]);
sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */
m8xx.cimr |= 1UL << 28; /* Enable SCC2 interrupts */
break;
case SCC3_MINOR:
consoleIrqData.name = BSP_CPM_IRQ_SCC3;
consoleIrqData.hdl = m8xx_scc3_interrupt_handler;
break;
case SCC4_MINOR:
rtems_interrupt_catch (m8xx_scc4_interrupt_handler,
PPC_IRQ_CPM_SCC4,
&old_handler[minor]);
sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */
m8xx.cimr |= 1UL << 27; /* Enable SCC2 interrupts */
break;
case SCC4_MINOR:
consoleIrqData.name = BSP_CPM_IRQ_SCC4;
consoleIrqData.hdl = m8xx_scc4_interrupt_handler;
break;
#endif /* mpc860 */
}
if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
printk("Unable to connect SCC Irq handler\n");
rtems_fatal_error_occurred(1);
}
}
}
void m8xx_smc_enable(const rtems_irq_connect_data* ptr)
{
volatile m8xxSMCRegisters_t *smcregs = 0;
switch (ptr->name) {
case BSP_CPM_IRQ_SMC1 :
smcregs = &m8xx.smc1;
break;
case BSP_CPM_IRQ_SMC2_OR_PIP :
smcregs = &m8xx.smc2;
break;
default:
break;
}
smcregs->smcm = 3;
}
void m8xx_smc_disable(const rtems_irq_connect_data* ptr)
{
volatile m8xxSMCRegisters_t *smcregs = 0;
switch (ptr->name) {
case BSP_CPM_IRQ_SMC1 :
smcregs = &m8xx.smc1;
break;
case BSP_CPM_IRQ_SMC2_OR_PIP :
smcregs = &m8xx.smc2;
break;
default:
break;
}
smcregs->smcm &= (~3);
}
int m8xx_smc_isOn(const rtems_irq_connect_data* ptr)
{
return BSP_irq_enabled_at_cpm (ptr->name);
}
void
m8xx_uart_smc_initialize (int minor)
@@ -923,24 +1000,23 @@ m8xx_uart_smc_initialize (int minor)
*/
smcregs->smcmr |= M8xx_SMCMR_TEN | M8xx_SMCMR_REN;
if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
consoleIrqData.on = m8xx_smc_enable;
consoleIrqData.off = m8xx_smc_disable;
consoleIrqData.isOn = m8xx_smc_isOn;
switch (minor) {
case SMC1_MINOR:
rtems_interrupt_catch (m8xx_smc1_interrupt_handler,
PPC_IRQ_CPM_SMC1,
&old_handler[minor]);
smcregs->smcm = 3; /* Enable SMC1 Rx & Tx interrupts */
m8xx.cimr |= 1UL << 4; /* Enable SMC1 interrupts */
break;
case SMC1_MINOR:
consoleIrqData.name = BSP_CPM_IRQ_SMC1;
consoleIrqData.hdl = m8xx_smc1_interrupt_handler;
break;
case SMC2_MINOR:
rtems_interrupt_catch (m8xx_smc2_interrupt_handler,
PPC_IRQ_CPM_SMC2,
&old_handler[minor]);
smcregs->smcm = 3; /* Enable SMC2 Rx & Tx interrupts */
m8xx.cimr |= 1UL << 3; /* Enable SMC2 interrupts */
break;
case SMC2_MINOR:
consoleIrqData.name = BSP_CPM_IRQ_SMC2_OR_PIP;
consoleIrqData.hdl = m8xx_smc2_interrupt_handler;
break;
}
if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
printk("Unable to connect SMC Irq handler\n");
rtems_fatal_error_occurred(1);
}
}
}
@@ -957,21 +1033,6 @@ m8xx_uart_initialize(void)
}
void
m8xx_uart_interrupts_initialize(void)
{
#ifdef mpc860
m8xx.cicr = 0x00E43F80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
SCdP=SCC4, IRL=1, HP=PC15, IEN=1 */
#else
m8xx.cicr = 0x00043F80; /* SCaP=SCC1, SCbP=SCC2, IRL=1, HP=PC15, IEN=1 */
#endif
m8xx.simask |= M8xx_SIMASK_LVM1; /* Enable level interrupts */
#ifdef EPPCBUG_SMC1
simask_copy = m8xx.simask;
#endif
}
int
m8xx_uart_pollRead(

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,199 @@
/*
* 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.
*
* 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 mpc860_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_SOFTEMUL_VECTOR:
case ASM_ITLBMISS_VECTOR:
case ASM_DTLBMISS_VECTOR:
case ASM_ITLBERROR_VECTOR:
case ASM_DTLBERROR_VECTOR:
case ASM_DBREAK_VECTOR:
case ASM_IBREAK_VECTOR:
case ASM_PERIFBREAK_VECTOR:
case ASM_DEVPORT_VECTOR:
return 1;
default: return 0;
}
}
int mpc8xx_vector_is_valid(rtems_vector vector)
{
switch (current_ppc_cpu) {
case PPC_860:
if (!mpc860_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;
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,188 @@
/*
* 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.
*
* 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_SOFTEMUL_VECTOR 0x10
#define ASM_ITLBMISS_VECTOR 0x11
#define ASM_DTLBMISS_VECTOR 0x12
#define ASM_ITLBERROR_VECTOR 0x13
#define ASM_DTLBERROR_VECTOR 0x14
#define ASM_DBREAK_VECTOR 0x1C
#define ASM_IBREAK_VECTOR 0x1D
#define ASM_PERIFBREAK_VECTOR 0x1E
#define ASM_DEVPORT_VECTOR 0x1F
#define LAST_VALID_EXC ASM_DEVPORT_VECTOR
/*
* Vector offsets as defined in the MPC860 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_SOFTEMUL_VECTOR_OFFSET (ASM_SOFTEMUL_VECTOR << 8)
#define ASM_ITLBMISS_VECTOR_OFFSET (ASM_ITLBMISS_VECTOR << 8)
#define ASM_DTLBMISS_VECTOR_OFFSET (ASM_DTLBMISS_VECTOR << 8)
#define ASM_ITLBERROR_VECTOR_OFFSET (ASM_ITLBERROR_VECTOR << 8)
#define ASM_DTLBERROR_VECTOR_OFFSET (ASM_DTLBERROR_VECTOR << 8)
#define ASM_DBREAK_VECTOR_OFFSET (ASM_DBREAK_VECTOR << 8)
#define ASM_IBREAK_VECTOR_OFFSET (ASM_IBREAK_VECTOR << 8)
#define ASM_PERIFBREAK_VECTOR_OFFSET (ASM_PERIFBREAK_VECTOR << 8)
#define ASM_DEVPORT_VECTOR_OFFSET (ASM_DEVPORT_VECTOR_OFFSET << 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

@@ -649,9 +649,9 @@ typedef struct m8xxSPIparms_ {
*************************************************************************
*/
typedef struct m8xxBufferDescriptor_ {
rtems_unsigned16 status;
rtems_unsigned16 length;
volatile void *buffer;
volatile rtems_unsigned16 status;
rtems_unsigned16 length;
volatile void *buffer;
} m8xxBufferDescriptor_t;
/*

View File

@@ -115,7 +115,7 @@ void mmu_init( void )
/*
* Turn on address translation by setting MSR[IR] and MSR[DR].
*/
_CPU_MSR_Value( reg1 );
_CPU_MSR_GET( reg1 );
reg1 |= PPC_MSR_IR | PPC_MSR_DR;
_CPU_MSR_SET( reg1 );
}

View File

@@ -440,6 +440,20 @@ typedef struct {
unsigned32 clicks_per_usec; /* Timer clicks per microsecond */
boolean exceptions_in_RAM; /* TRUE if in RAM */
#if (defined(ppc403) || defined(mpc860) || defined(mpc821))
unsigned32 serial_per_sec; /* Serial clocks per second */
boolean serial_external_clock;
boolean serial_xon_xoff;
boolean serial_cts_rts;
unsigned32 serial_rate;
unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */
unsigned32 timer_least_valid; /* Least valid number from timer */
boolean timer_internal_clock; /* TRUE, when timer runs with CPU clk */
#endif
#if (defined(mpc860) || defined(mpc821))
unsigned32 clock_speed; /* Speed of CPU in Hz */
#endif
} rtems_cpu_table;
/*

View File

@@ -19,10 +19,6 @@
#ifndef _PPC_BYTEORDER_H
#define _PPC_BYTEORDER_H
/*
* $Id$
*/
#ifdef __GNUC__
extern __inline__ unsigned ld_le16(volatile unsigned short *addr)

View File

@@ -10,7 +10,10 @@ GENERIC_FILES = shared
# So far FAMILY_OBJS is empty and ar dislike it...
CPU_SPECIFIC_OBJS = $(wildcard ../$(RTEMS_CPU_MODEL)/*/$(ARCH)/*.o)
FAMILY_OBJS = \
$(wildcard ../shared/$(ARCH)/*.o ../shared/*/$(ARCH)/*.o ../old_exception_processing/*/$(ARCH)/*.o ../new_exception_processing/*/$(ARCH)/*.o ../mpc6xx/*/$(ARCH)/*.o)
$(wildcard ../shared/$(ARCH)/*.o ../shared/*/$(ARCH)/*.o \
../old_exception_processing/*/$(ARCH)/*.o \
../new_exception_processing/*/$(ARCH)/*.o \
../mpc6xx/*/$(ARCH)/*.o)
LIB = $(ARCH)/libcpu.a