remove depratated powerpc exception API

This commit is contained in:
Thomas Doerfler
2009-10-30 13:52:34 +00:00
parent 5075ec98c7
commit f7ac681b51
32 changed files with 29 additions and 5669 deletions

View File

@@ -1,3 +1,13 @@
2009-10-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
* new-exceptions/e500_raw_exc_init.c, new-exceptions/raw_exception.c,
new-exceptions/raw_exception.h,
new-exceptions/bspsupport/vectors_init.c,
mpc8xx/exceptions/asm_utils.S, mpc8xx/exceptions/raw_exception.c,
mpc8xx/exceptions/raw_exception.h, mpc8260/asm_utils.S,
mpc8260/raw_exception.c, mpc8260/raw_exception.h: Removed files.
* Makefile.am: Update for removed files.
2009-10-22 Sebastian Huber <sebastian.huber@embedded-brains.de>
* new-exceptions/bspsupport/ppc-code-copy.c,

View File

@@ -1,64 +0,0 @@
/*
* 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 <rtems/asm.h>
#include <rtems/score/cpu.h>
#include <libcpu/io.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

@@ -1,207 +0,0 @@
/*
* 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.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <string.h> /* memcmp */
#include <rtems/system.h>
#include <rtems/score/powerpc.h>
#include <rtems/bspIo.h>
#include <libcpu/raw_exception.h>
#include <libcpu/cpuIdent.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;
void * codemove(void *, const void *, unsigned int, unsigned long);
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)
{
rtems_interrupt_level 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;
}
rtems_interrupt_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);
rtems_interrupt_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)
{
rtems_interrupt_level 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;
}
rtems_interrupt_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;
rtems_interrupt_enable(level);
return 1;
}
/*
* Exception global init.
*/
int mpc8xx_init_exceptions (rtems_raw_except_global_settings* config)
{
int i;
rtems_interrupt_level level;
/*
* store various accelerators
*/
raw_except_table = config->rawExceptHdlTbl;
local_settings = config;
default_raw_except_entry = config->defaultRawEntry;
rtems_interrupt_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]);
}
}
rtems_interrupt_enable(level);
return 1;
}
int mpc8xx_get_exception_config (rtems_raw_except_global_settings** config)
{
*config = local_settings;
return 1;
}

View File

@@ -1,182 +0,0 @@
/*
* 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.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _LIBCPU_RAW_EXCEPTION_H
#define _LIBCPU_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

@@ -1,64 +0,0 @@
/*
* 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 <rtems/asm.h>
#include <rtems/score/cpu.h>
#include <libcpu/io.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

@@ -1,202 +0,0 @@
/*
* 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.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/score/cpu.h>
#include <rtems/score/powerpc.h>
#include <libcpu/raw_exception.h>
#include <libcpu/cpuIdent.h>
#include <rtems/bspIo.h> /* for printk */
#include <string.h>
void * codemove(void *, const void *, unsigned int, unsigned long);
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)
{
rtems_interrupt_level 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;
}
rtems_interrupt_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);
rtems_interrupt_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)
{
rtems_interrupt_level 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;
}
rtems_interrupt_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;
rtems_interrupt_enable(level);
return 1;
}
/*
* Exception global init.
*/
int mpc8xx_init_exceptions (rtems_raw_except_global_settings* config)
{
int i;
rtems_interrupt_level level;
/*
* store various accelerators
*/
raw_except_table = config->rawExceptHdlTbl;
local_settings = config;
default_raw_except_entry = config->defaultRawEntry;
rtems_interrupt_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]);
}
}
rtems_interrupt_enable(level);
return 1;
}
int mpc8xx_get_exception_config (rtems_raw_except_global_settings** config)
{
*config = local_settings;
return 1;
}

View File

@@ -1,187 +0,0 @@
/*
* 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.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _LIBCPU_RAW_EXCEPTION_H
#define _LIBCPU_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

@@ -1,482 +0,0 @@
/*
* vectors_init.c Exception hanlding initialisation (and generic handler).
*
* This include file describe the data structure and the functions implemented
* by rtems to handle exceptions.
*
* Copyright (C) 1999 valette@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems.h>
#include <rtems/bspIo.h>
#include <rtems/error.h>
#include <libcpu/raw_exception.h>
#include <libcpu/spr.h>
#include <libcpu/cpuIdent.h>
#include "vectors.h"
#include "ppc_exc_bspsupp.h"
static rtems_raw_except_global_settings exception_config;
static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1];
uint32_t ppc_exc_cache_wb_check = 1;
#if 0
typedef struct ppc_exc_connect_data_ {
rtems_raw_except_connect_data raw;
ppc_exc_handler_t c_hdl;
} ppc_exc_connect_data;
#endif
exception_handler_t globalExceptHdl;
/* T. Straumann: provide a stack trace
* <strauman@slac.stanford.edu>, 6/26/2001
*/
typedef struct LRFrameRec_ {
struct LRFrameRec_ *frameLink;
unsigned long *lr;
} LRFrameRec, *LRFrame;
#define STACK_CLAMP 50 /* in case we have a corrupted bottom */
SPR_RW(SPRG1)
SPR_RW(SPRG2)
SPR_RO(LR)
SPR_RO(DAR)
SPR_RO(DEAR_BOOKE)
SPR_RO(DEAR_405)
uint32_t ppc_exc_get_DAR_dflt(void)
{
if ( ppc_cpu_is_60x() )
return _read_DAR();
else switch ( ppc_cpu_is_bookE() ) {
default: break;
case PPC_BOOKE_STD:
case PPC_BOOKE_E500:
return _read_DEAR_BOOKE();
case PPC_BOOKE_405:
return _read_DEAR_405();
}
return 0xdeadbeef;
}
uint32_t (*ppc_exc_get_DAR)(void) = ppc_exc_get_DAR_dflt;
void
BSP_printStackTrace(BSP_Exception_frame* excPtr)
{
LRFrame f;
int i;
LRFrame sp;
void *lr;
printk("Stack Trace: \n ");
if (excPtr) {
printk("IP: 0x%08x, ",excPtr->EXC_SRR0);
sp=(LRFrame)excPtr->GPR1;
lr=(void*)excPtr->EXC_LR;
} else {
/* there's no macro for this */
__asm__ __volatile__("mr %0, 1":"=r"(sp));
lr=(LRFrame)_read_LR();
}
printk("LR: 0x%08x\n",lr);
for (f=(LRFrame)sp, i=0; f->frameLink && i<STACK_CLAMP; f=f->frameLink) {
printk("--^ 0x%08x", (long)(f->frameLink->lr));
if (!(++i%5))
printk("\n");
}
if (i>=STACK_CLAMP) {
printk("Too many stack frames (stack possibly corrupted), giving up...\n");
} else {
if (i%5)
printk("\n");
}
}
void C_exception_handler(BSP_Exception_frame* excPtr)
{
static int nest = 0;
int recoverable = 0;
rtems_id id = 0;
int synch;
unsigned n;
rtems_status_code sc;
/* Catch recursion */
nest++;
if ( nest > 2 ) {
/* maybe printk() or dereferencing excPtr caused an exception;
* die silently...
*/
while (1)
;
}
synch = (int)excPtr->_EXC_number >= 0 ;
n = excPtr->_EXC_number & 0x7fff;
printk("Exception handler called for exception %d (0x%x)\n", n, n);
printk("\t Next PC or Address of fault = %08x\n", excPtr->EXC_SRR0);
printk("\t Saved MSR = %08x\n", excPtr->EXC_SRR1);
if ( nest > 1 ) {
printk("Recursion in the exception handler detected; I'll spin now...\n");
while ( 1 )
;
}
/* Try to find out more about the context where this happened */
printk("\t Context: ");
if ( rtems_interrupt_is_in_progress() ) {
printk("ISR");
} else if ( !_Thread_Executing ) {
printk("Initialization (_Thread_Executing not available yet)");
} else {
if ( RTEMS_SUCCESSFUL != (sc=rtems_task_ident(RTEMS_SELF, RTEMS_LOCAL, &id)) ) {
printk("Unable to determine faulting task; rtems_task_ident() returned %u", sc);
id = 0;
} else {
printk("Task ID 0x%08x", id);
}
}
printk("\n");
/* Dump registers */
printk("\t R0 = %08x", excPtr->GPR0);
if ( synch ) {
printk(" R1 = %08x", excPtr->GPR1);
printk(" R2 = %08x", excPtr->GPR2);
} else {
printk(" ");
printk(" ");
}
printk(" R3 = %08x\n", excPtr->GPR3);
printk("\t R4 = %08x", excPtr->GPR4);
printk(" R5 = %08x", excPtr->GPR5);
printk(" R6 = %08x", excPtr->GPR6);
printk(" R7 = %08x\n", excPtr->GPR7);
printk("\t R8 = %08x", excPtr->GPR8);
printk(" R9 = %08x", excPtr->GPR9);
printk(" R10 = %08x", excPtr->GPR10);
printk(" R11 = %08x\n", excPtr->GPR11);
printk("\t R12 = %08x", excPtr->GPR12);
if ( synch ) {
printk(" R13 = %08x", excPtr->GPR13);
printk(" R14 = %08x", excPtr->GPR14);
printk(" R15 = %08x\n", excPtr->GPR15);
printk("\t R16 = %08x", excPtr->GPR16);
printk(" R17 = %08x", excPtr->GPR17);
printk(" R18 = %08x", excPtr->GPR18);
printk(" R19 = %08x\n", excPtr->GPR19);
printk("\t R20 = %08x", excPtr->GPR20);
printk(" R21 = %08x", excPtr->GPR21);
printk(" R22 = %08x", excPtr->GPR22);
printk(" R23 = %08x\n", excPtr->GPR23);
printk("\t R24 = %08x", excPtr->GPR24);
printk(" R25 = %08x", excPtr->GPR25);
printk(" R26 = %08x", excPtr->GPR26);
printk(" R27 = %08x\n", excPtr->GPR27);
printk("\t R28 = %08x", excPtr->GPR28);
printk(" R29 = %08x", excPtr->GPR29);
printk(" R30 = %08x", excPtr->GPR30);
printk(" R31 = %08x\n", excPtr->GPR31);
} else {
printk("\n");
}
printk("\t CR = %08x\n", excPtr->EXC_CR);
printk("\t CTR = %08x\n", excPtr->EXC_CTR);
printk("\t XER = %08x\n", excPtr->EXC_XER);
printk("\t LR = %08x\n", excPtr->EXC_LR);
/* Would be great to print DAR but unfortunately,
* that is not portable across different CPUs.
* AFAIK on classic PPC DAR is SPR 19, on the
* 405 we have DEAR = SPR 0x3d5 and booE says
* DEAR = SPR 61 :-(
*/
if ( ppc_exc_get_DAR ) {
printk("\t DAR = %08x\n", ppc_exc_get_DAR());
}
BSP_printStackTrace(excPtr);
if (excPtr->_EXC_number == ASM_DEC_VECTOR)
recoverable = 1;
if (excPtr->_EXC_number == ASM_SYS_VECTOR)
#ifdef TEST_RAW_EXCEPTION_CODE
recoverable = 1;
#else
recoverable = 0;
#endif
if (!recoverable) {
if ( id ) {
printk("Suspending faulting task (0x%08x)\n", id);
/* Unnest here because rtems_task_suspend() never returns */
nest--;
rtems_task_suspend(id);
} else {
printk("unrecoverable exception!!! Push reset button\n");
while(1);
}
} else {
nest--;
}
}
/***********************************************************
* dummy functions for on/off/isOn calls
* these functions just do nothing fulfill the semantic
* requirements to enable/disable a certain exception
*/
void exception_nop_enable(const rtems_raw_except_connect_data* ptr)
{
}
int exception_always_enabled(const rtems_raw_except_connect_data* ptr)
{
return 1;
}
/* Raw exception framework wants to keep a pointer to
* the prologue so we must keep the ones we generate
* from templates around...
*/
#define NUM_PROLOG 8 /* just a reasonable limit */
static int n_prolog = 0;
static ppc_exc_min_prolog_t prologues[NUM_PROLOG];
static ppc_exc_min_prolog_template_t prolog_templates[][2] = {
[ PPC_EXC_CLASSIC ] =
{
ppc_exc_min_prolog_sync_tmpl_std,
ppc_exc_min_prolog_async_tmpl_std,
},
[ PPC_EXC_405_CRITICAL ] =
{
ppc_exc_min_prolog_sync_tmpl_p405_crit,
ppc_exc_min_prolog_async_tmpl_p405_crit,
},
[ PPC_EXC_BOOKE_CRITICAL ] =
{
ppc_exc_min_prolog_sync_tmpl_bookE_crit,
ppc_exc_min_prolog_async_tmpl_bookE_crit,
},
[ PPC_EXC_E500_MACHCHK ] =
{
ppc_exc_min_prolog_sync_tmpl_e500_mchk,
ppc_exc_min_prolog_async_tmpl_e500_mchk,
},
};
static rtems_raw_except_func
make_prologue(int vector, ppc_raw_exception_category cat)
{
int async = (cat & PPC_EXC_ASYNC) ? 1 : 0 ;
ppc_exc_min_prolog_template_t tmpl;
cat &= ~PPC_EXC_ASYNC;
if ( n_prolog >= NUM_PROLOG ) {
rtems_panic("Not enough exception prologue slots; increase NUM_PROLOG (%s)\n",__FILE__);
}
if ( ! (tmpl = prolog_templates[cat][async]) ) {
rtems_panic("No exception prologue template for category 0x%02x found\n", cat);
}
ppc_exc_min_prolog_expand(prologues[n_prolog], tmpl, vector);
return (rtems_raw_except_func)prologues[n_prolog++];
}
void ppc_exc_table_init(
rtems_raw_except_connect_data *exception_table,
int nEntries)
{
unsigned i,v;
ppc_raw_exception_category cat;
uintptr_t vaddr;
/*
* Initialize pointer used by low level execption handling
*/
globalExceptHdl = C_exception_handler;
/*
* Put default_exception_vector_code_prolog at relevant exception
* code entry addresses
*/
exception_config.exceptSize = nEntries;
exception_config.rawExceptHdlTbl = exception_table;
exception_config.defaultRawEntry.exceptIndex = 0;
exception_config.defaultRawEntry.hdl.vector = 0;
if (ppc_cpu_has_ivpr_and_ivor()) {
/* Use packed version with 16-byte boundaries for CPUs with IVPR and IVOR registers */
exception_config.defaultRawEntry.hdl.raw_hdl = ppc_exc_min_prolog_auto_packed;
} else {
/* Note that the 'auto' handler cannot be used for everything; in particular,
* it assumes classic exceptions with a vector offset aligned on a 256-byte
* boundary.
*/
exception_config.defaultRawEntry.hdl.raw_hdl = ppc_exc_min_prolog_auto;
}
/*
* Note that the cast of an array address to an unsigned
* is not a bug as it is defined by a .set directly in asm...
*/
exception_config.defaultRawEntry.hdl.raw_hdl_size = (unsigned)ppc_exc_min_prolog_size;
for (i=0; i < exception_config.exceptSize; i++) {
if ( PPC_EXC_INVALID == (cat = ppc_vector_is_valid ((v=exception_table[i].hdl.vector))) ) {
continue;
}
exception_table[i].exceptIndex = i;
exception_table[v].hdl.raw_hdl_size = (unsigned)ppc_exc_min_prolog_size;
/* special cases */
if ( ppc_cpu_has_shadowed_gprs()
&& ( ASM_60X_IMISS_VECTOR == v
|| ASM_60X_DLMISS_VECTOR == v
|| ASM_60X_DSMISS_VECTOR == v ) ) {
exception_table[i].hdl.raw_hdl = ppc_exc_tgpr_clr_prolog;
exception_table[i].hdl.raw_hdl_size = (unsigned)ppc_exc_tgpr_clr_prolog_size;
} else {
vaddr = (uintptr_t)ppc_get_vector_addr( v );
/*
* default prolog can handle classic, synchronous exceptions
* with a vector offset aligned on a 256-byte boundary.
*/
if (cat == PPC_EXC_CLASSIC && ((vaddr & 0xff) == 0 || (ppc_cpu_has_ivpr_and_ivor() && (vaddr & 0xf) == 0))) {
exception_table[i].hdl.raw_hdl_size = exception_config.defaultRawEntry.hdl.raw_hdl_size;
exception_table[i].hdl.raw_hdl = exception_config.defaultRawEntry.hdl.raw_hdl;
} else {
exception_table[i].hdl.raw_hdl_size = (unsigned)ppc_exc_min_prolog_size;
exception_table[i].hdl.raw_hdl = make_prologue( v, cat );
}
}
exception_table[i].on = exception_nop_enable;
exception_table[i].off = exception_nop_enable;
exception_table[i].isOn = exception_always_enabled;
}
if (!ppc_init_exceptions(&exception_config)) {
BSP_panic("Exception handling initialization failed\n");
}
#ifdef RTEMS_DEBUG
else {
printk("Exception handling initialization done\n");
}
#endif
}
void ppc_exc_initialize(
uint32_t interrupt_disable_mask,
uint32_t interrupt_stack_start,
uint32_t interrupt_stack_size
)
{
int i;
int n = sizeof(exception_table)/sizeof(exception_table[0]);
uint32_t interrupt_stack_end = 0;
uint32_t interrupt_stack_pointer = 0;
uint32_t *p = NULL;
uint32_t r13, sda_base;
/* Assembly code needs SDA_BASE in r13 (SVR4 or EABI). Make sure
* early init code put it there.
*/
asm volatile(
" lis %0, _SDA_BASE_@h \n"
" ori %0, %0, _SDA_BASE_@l \n"
" mr %1, 13 \n"
:"=r"(sda_base),"=r"(r13)
);
if ( sda_base != r13 ) {
printk("ppc_exc_initialize(): INTERNAL ERROR\n");
printk(" your BSP seems to not have loaded _SDA_BASE_\n");
printk(" into R13 as required by SVR4/EABI. Check early init code...\n");
printk(" _SDA_BASE_: 0x%08x, R13: 0x%08x\n", sda_base, r13);
while (1)
;
}
/* Interrupt stack end and pointer */
interrupt_stack_end = interrupt_stack_start + interrupt_stack_size;
interrupt_stack_pointer = interrupt_stack_end - PPC_MINIMUM_STACK_FRAME_SIZE;
/* Ensure proper interrupt stack alignment */
interrupt_stack_pointer &= ~(CPU_STACK_ALIGNMENT - 1);
/* Tag interrupt stack bottom */
p = (uint32_t *) interrupt_stack_pointer;
*p = 0;
/* Move interrupt stack values to special purpose registers */
_write_SPRG1( interrupt_stack_pointer);
_write_SPRG2( interrupt_stack_start);
/* Interrupt disable mask */
ppc_interrupt_set_disable_mask( interrupt_disable_mask);
/* Use current MMU / RI settings when running C exception handlers */
ppc_exc_msr_bits = _read_MSR() & ( MSR_DR | MSR_IR | MSR_RI );
for ( i=0; i<n; i++ )
exception_table[i].hdl.vector = i;
ppc_exc_table_init(exception_table, n);
/* If we are on a classic PPC with MSR_DR enabled then
* assert that the mapping for at least this task's
* stack is write-back-caching enabled (see README/CAVEATS)
* Do this only if the cache is physically enabled.
* Since it is not easy to figure that out in a
* generic way we need help from the BSP: BSPs
* which run entirely w/o the cache may set
* ppc_exc_cache_wb_check to zero prior to calling
* this routine.
*
* We run this check only after exception handling is
* initialized so that we have some chance to get
* information printed if it fails.
*
* Note that it is unsafe to ignore this issue; if
* the check fails, do NOT disable it unless caches
* are always physically disabled.
*/
if ( ppc_exc_cache_wb_check && (MSR_DR & ppc_exc_msr_bits) ) {
/* The size of 63 assumes cache lines are at most 32 bytes */
uint8_t dummy[63];
uintptr_t p = (uintptr_t)dummy;
/* If the dcbz instruction raises an alignment exception
* then the stack is mapped as write-thru or caching-disabled.
* The low-level code is not capable of dealing with this
* ATM.
*/
p = (p + 31) & ~31;
asm volatile("dcbz 0, %0"::"b"(p));
/* If we make it thru here then things seem to be OK */
}
}

View File

@@ -1,70 +0,0 @@
#include <libcpu/cpuIdent.h>
#include <libcpu/raw_exception.h>
#define MTIVPR(prefix) asm volatile("mtivpr %0"::"r"(prefix));
#define MTIVOR(x, vec) asm volatile("mtivor"#x" %0"::"r"(vec));
/* Use during early init for initializing the e500 IVOR/IVPR registers */
void
e500_setup_raw_exceptions(void)
{
unsigned c;
if ( ! (c = ppc_cpu_is_bookE()) || PPC_BOOKE_405 == c )
return;
/* Set interupt vector prefix register */
MTIVPR( ppc_exc_vector_base);
/* setup vectors to be compatible with classic PPC */
MTIVOR(0, ppc_get_vector_addr(ASM_BOOKE_CRIT_VECTOR)); /* Critical input not (yet) supported; use reset vector */
MTIVOR(1, ppc_get_vector_addr(ASM_MACH_VECTOR));
MTIVOR(2, ppc_get_vector_addr(ASM_PROT_VECTOR));
MTIVOR(3, ppc_get_vector_addr(ASM_ISI_VECTOR));
MTIVOR(4, ppc_get_vector_addr(ASM_EXT_VECTOR));
MTIVOR(5, ppc_get_vector_addr(ASM_ALIGN_VECTOR));
MTIVOR(6, ppc_get_vector_addr(ASM_PROG_VECTOR));
MTIVOR(7, ppc_get_vector_addr(ASM_FLOAT_VECTOR));
MTIVOR(8, ppc_get_vector_addr(ASM_SYS_VECTOR));
MTIVOR(9, ppc_get_vector_addr(0x0b));
MTIVOR(10, ppc_get_vector_addr(ASM_BOOKE_DEC_VECTOR));
MTIVOR(11, ppc_get_vector_addr(ASM_BOOKE_FIT_VECTOR));
MTIVOR(12, ppc_get_vector_addr(ASM_BOOKE_WDOG_VECTOR));
MTIVOR(13, ppc_get_vector_addr(ASM_60X_DSMISS_VECTOR));
MTIVOR(14, ppc_get_vector_addr(ASM_60X_DLMISS_VECTOR));
MTIVOR(15, ppc_get_vector_addr(ASM_TRACE_VECTOR));
MTIVOR(32, ppc_get_vector_addr(ASM_60X_VEC_VECTOR));
MTIVOR(33, ppc_get_vector_addr(0x16));
MTIVOR(34, ppc_get_vector_addr(0x15));
MTIVOR(35, ppc_get_vector_addr(ASM_60X_PERFMON_VECTOR));
}
void e200_setup_raw_exceptions(void)
{
if (current_ppc_cpu != PPC_e200z6) {
return;
}
/* Interupt vector prefix register */
MTIVPR( ppc_exc_vector_base);
/* Interupt vector offset register */
MTIVOR( 0, 0); /* Critical input */
MTIVOR( 1, ppc_get_vector_addr( ASM_MACH_VECTOR));
MTIVOR( 2, ppc_get_vector_addr( ASM_PROT_VECTOR));
MTIVOR( 3, ppc_get_vector_addr( ASM_ISI_VECTOR));
MTIVOR( 4, ppc_get_vector_addr( ASM_EXT_VECTOR));
MTIVOR( 5, ppc_get_vector_addr( ASM_ALIGN_VECTOR));
MTIVOR( 6, ppc_get_vector_addr( ASM_PROG_VECTOR));
MTIVOR( 7, ppc_get_vector_addr( ASM_FLOAT_VECTOR));
MTIVOR( 8, ppc_get_vector_addr( ASM_SYS_VECTOR));
MTIVOR( 9, 0); /* APU unavailable */
MTIVOR( 10, ppc_get_vector_addr( ASM_BOOKE_DEC_VECTOR));
MTIVOR( 11, ppc_get_vector_addr( ASM_BOOKE_FIT_VECTOR));
MTIVOR( 12, ppc_get_vector_addr( ASM_BOOKE_WDOG_VECTOR));
MTIVOR( 13, ppc_get_vector_addr( ASM_BOOKE_ITLBMISS_VECTOR));
MTIVOR( 14, ppc_get_vector_addr( ASM_BOOKE_DTLBMISS_VECTOR));
MTIVOR( 15, ppc_get_vector_addr( ASM_TRACE_VECTOR));
MTIVOR( 32, ppc_get_vector_addr( ASM_E200_SPE_UNAVAILABLE_VECTOR));
MTIVOR( 33, ppc_get_vector_addr( ASM_E200_SPE_DATA_VECTOR));
MTIVOR( 34, ppc_get_vector_addr( ASM_E200_SPE_ROUND_VECTOR));
}

View File

@@ -1,569 +0,0 @@
/*
* raw_exception.c - This file contains implementation of C function to
* Instantiate 60x ppc primary exception entries.
* More detailed information can be found on motorola
* site and more precisely in the following book :
*
* MPC750
* Risc Microporcessor User's Manual
* Motorola REF : MPC750UM/AD 8/97
*
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
* Canon Centre Recherche France.
*
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
* to support 603, 603e, 604, 604e exceptions
*
* moved to "libcpu/powerpc/new-exceptions and consolidated
* by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
* to be common for all PPCs with new excpetions
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems.h>
#include <rtems/system.h>
#include <rtems/score/powerpc.h>
#include <rtems/score/isr.h>
#include <rtems/bspIo.h>
#include <libcpu/raw_exception.h>
#include <libcpu/cpuIdent.h>
#include <string.h>
/* DO NOT INTRODUCE #ifdef <cpu_flavor> in this file */
/* enum ppc_raw_exception_category should fit into this type;
* we are setting up arrays of these for all known CPUs
* hence the attempt to save a few bytes.
*/
typedef uint8_t cat_ini_t;
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;
void * codemove(void *, const void *, unsigned int, unsigned long);
bool bsp_exceptions_in_RAM = true;
/* DEPRECATED VARIABLE; we need this to support
* libbsp/powerpc/shared/vectors/vectors.S;
* new BSPs should NOT use this.
*/
uint32_t bsp_raw_vector_is_405_critical = 0;
uint32_t ppc_exc_vector_base = 0;
void* ppc_get_vector_addr(rtems_vector vector)
{
unsigned vaddr;
vaddr = ((unsigned)vector) << 8;
switch(vector) {
/*
* some vectors are located at odd addresses and only available
* on some CPU derivates. this construct will handle them
* if available
*/
/* Special case; altivec unavailable doesn't fit :-( */
case ASM_60X_VEC_VECTOR:
#ifndef ASM_60X_VEC_VECTOR_OFFSET
#define ASM_60X_VEC_VECTOR_OFFSET 0xf20
#endif
if ( ppc_cpu_has_altivec() )
vaddr = ASM_60X_VEC_VECTOR_OFFSET;
break;
default:
break;
}
if ( PPC_405 == current_ppc_cpu ) {
switch ( vector ) {
case ASM_BOOKE_FIT_VECTOR:
#ifndef ASM_PPC405_FIT_VECTOR_OFFSET
#define ASM_PPC405_FIT_VECTOR_OFFSET 0x1010
#endif
vaddr = ASM_PPC405_FIT_VECTOR_OFFSET;
break;
case ASM_BOOKE_WDOG_VECTOR:
#ifndef ASM_PPC405_WDOG_VECTOR_OFFSET
#define ASM_PPC405_WDOG_VECTOR_OFFSET 0x1020
#endif
vaddr = ASM_PPC405_WDOG_VECTOR_OFFSET;
break;
case ASM_TRACE_VECTOR:
#ifndef ASM_PPC405_TRACE_VECTOR_OFFSET
#define ASM_PPC405_TRACE_VECTOR_OFFSET 0x2000
#endif
vaddr = ASM_PPC405_TRACE_VECTOR_OFFSET;
break;
case ASM_PPC405_APU_UNAVAIL_VECTOR:
vaddr = ASM_60X_VEC_VECTOR_OFFSET;
default:
break;
}
}
if (bsp_exceptions_in_RAM) {
if (ppc_cpu_has_ivpr_and_ivor()) {
return ((void*) ((vaddr >> 4) + ppc_exc_vector_base));
} else {
return ((void*) (vaddr + ppc_exc_vector_base));
}
}
return ((void*) (vaddr + 0xfff00000));
}
static const cat_ini_t mpc_860_vector_categories[LAST_VALID_EXC + 1] = {
[ ASM_RESET_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_MACH_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PROT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_ISI_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_EXT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_ALIGN_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PROG_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_FLOAT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_SYS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_TRACE_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_FLOATASSIST_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_SOFTEMUL_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_ITLBMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_DTLBMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_ITLBERROR_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_DTLBERROR_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_DBREAK_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_IBREAK_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_PERIFBREAK_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_8XX_DEVPORT_VECTOR ] = PPC_EXC_CLASSIC,
};
static const cat_ini_t mpc_5xx_vector_categories[LAST_VALID_EXC + 1] = {
[ ASM_RESET_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_MACH_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_EXT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_ALIGN_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PROG_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_FLOAT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_SYS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_TRACE_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_FLOATASSIST_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_SOFTEMUL_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_IPROT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_DPROT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_DBREAK_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_IBREAK_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_MEBREAK_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_5XX_NMEBREAK_VECTOR ] = PPC_EXC_CLASSIC,
};
static const cat_ini_t ppc_405_vector_categories[LAST_VALID_EXC + 1] = {
[ ASM_BOOKE_CRIT_VECTOR ] = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC,
[ ASM_MACH_VECTOR ] = PPC_EXC_405_CRITICAL,
[ ASM_PROT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_ISI_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_EXT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_ALIGN_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PROG_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_FLOAT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PPC405_APU_UNAVAIL_VECTOR] = PPC_EXC_CLASSIC,
[ ASM_SYS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_BOOKE_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, /* PIT */
[ ASM_BOOKE_FIT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, /* FIT */
[ ASM_BOOKE_WDOG_VECTOR ] = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC,
[ ASM_BOOKE_DTLBMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_BOOKE_ITLBMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_TRACE_VECTOR ] = PPC_EXC_405_CRITICAL,
};
#define PPC_BASIC_VECS \
[ ASM_RESET_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_MACH_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_PROT_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_ISI_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_EXT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, \
[ ASM_ALIGN_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_PROG_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_FLOAT_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, \
[ ASM_SYS_VECTOR ] = PPC_EXC_CLASSIC, \
[ ASM_TRACE_VECTOR ] = PPC_EXC_CLASSIC
static ppc_raw_exception_category altivec_vector_is_valid(rtems_vector vector)
{
if ( ppc_cpu_has_altivec() ) {
switch(vector) {
case ASM_60X_VEC_VECTOR:
case ASM_60X_VEC_ASSIST_VECTOR:
return PPC_EXC_CLASSIC;
default:
break;
}
}
return PPC_EXC_INVALID;
}
static const cat_ini_t mpc_750_vector_categories[LAST_VALID_EXC + 1] = {
PPC_BASIC_VECS,
[ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_60X_ADDR_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_ITM_VECTOR ] = PPC_EXC_CLASSIC,
};
static const cat_ini_t psim_vector_categories[LAST_VALID_EXC + 1] = {
[ ASM_RESET_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_MACH_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PROT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_ISI_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_EXT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_ALIGN_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PROG_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_FLOAT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_SYS_VECTOR ] = PPC_EXC_INVALID,
[ ASM_TRACE_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_INVALID,
[ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_60X_IMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_DLMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_DSMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_ADDR_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_ITM_VECTOR ] = PPC_EXC_INVALID,
};
static const cat_ini_t mpc_603_vector_categories[LAST_VALID_EXC + 1] = {
PPC_BASIC_VECS,
[ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_INVALID,
[ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_60X_IMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_DLMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_DSMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_ADDR_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_ITM_VECTOR ] = PPC_EXC_INVALID,
};
static const cat_ini_t mpc_604_vector_categories[LAST_VALID_EXC + 1] = {
PPC_BASIC_VECS,
[ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_IMISS_VECTOR ] = PPC_EXC_INVALID,
[ ASM_60X_DLMISS_VECTOR ] = PPC_EXC_INVALID,
[ ASM_60X_DSMISS_VECTOR ] = PPC_EXC_INVALID,
[ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_60X_ADDR_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_ITM_VECTOR ] = PPC_EXC_INVALID,
};
static const cat_ini_t e200_vector_categories [LAST_VALID_EXC + 1] = {
[ASM_MACH_VECTOR] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
[ASM_PROT_VECTOR] = PPC_EXC_CLASSIC,
[ASM_ISI_VECTOR] = PPC_EXC_CLASSIC,
[ASM_EXT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ASM_ALIGN_VECTOR] = PPC_EXC_CLASSIC,
[ASM_PROG_VECTOR] = PPC_EXC_CLASSIC,
[ASM_FLOAT_VECTOR] = PPC_EXC_CLASSIC,
[ASM_SYS_VECTOR] = PPC_EXC_CLASSIC,
[ASM_BOOKE_DEC_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ASM_BOOKE_FIT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ASM_BOOKE_WDOG_VECTOR] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
[ASM_BOOKE_ITLBMISS_VECTOR] = PPC_EXC_CLASSIC,
[ASM_BOOKE_DTLBMISS_VECTOR] = PPC_EXC_CLASSIC,
/* FIXME: Depending on HDI0[DAPUEN] this is a critical or debug exception */
[ASM_TRACE_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_BOOKE_CRITICAL,
[ASM_E200_SPE_UNAVAILABLE_VECTOR] = PPC_EXC_CLASSIC,
[ASM_E200_SPE_DATA_VECTOR] = PPC_EXC_CLASSIC,
[ASM_E200_SPE_ROUND_VECTOR] = PPC_EXC_CLASSIC,
};
static const cat_ini_t e300_vector_categories [LAST_VALID_EXC + 1] = {
PPC_BASIC_VECS,
[ASM_E300_CRIT_VECTOR] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
[ASM_E300_PERFMON_VECTOR] = PPC_EXC_CLASSIC,
[ASM_E300_IMISS_VECTOR] = PPC_EXC_CLASSIC,
[ASM_E300_DLMISS_VECTOR] = PPC_EXC_CLASSIC,
[ASM_E300_DSMISS_VECTOR] = PPC_EXC_CLASSIC,
[ASM_E300_ADDR_VECTOR] = PPC_EXC_CLASSIC,
[ASM_E300_SYSMGMT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
};
static const cat_ini_t e500_vector_categories[LAST_VALID_EXC + 1] = {
[ ASM_MACH_VECTOR ] = PPC_EXC_E500_MACHCHK,
[ ASM_BOOKE_CRIT_VECTOR ] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
[ ASM_BOOKE_WDOG_VECTOR ] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
[ ASM_TRACE_VECTOR ] = PPC_EXC_BOOKE_CRITICAL,
[ ASM_EXT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_BOOKE_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_BOOKE_FIT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_PROT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_ISI_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_ALIGN_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_PROG_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_FLOAT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_SYS_VECTOR ] = PPC_EXC_CLASSIC,
[ /* APU unavailable */ 0x0b ] = PPC_EXC_CLASSIC,
[ ASM_60X_DLMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_DSMISS_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_VEC_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_CLASSIC,
[ /* emb FP data */ 0x15 ] = PPC_EXC_CLASSIC,
[ /* emb FP round */ 0x16 ] = PPC_EXC_CLASSIC,
};
ppc_raw_exception_category ppc_vector_is_valid(rtems_vector vector)
{
ppc_raw_exception_category rval = PPC_EXC_INVALID;
if ( vector > LAST_VALID_EXC )
return PPC_EXC_INVALID;
switch (current_ppc_cpu) {
case PPC_7400:
if ( ( rval = altivec_vector_is_valid(vector)) )
return rval;
/* else fall thru */
case PPC_750:
rval = mpc_750_vector_categories[vector];
break;
case PPC_7455: /* Kate Feng */
case PPC_7457:
if ( ( rval = altivec_vector_is_valid(vector) ) )
return rval;
/* else fall thru */
case PPC_604:
case PPC_604e:
case PPC_604r:
rval = mpc_604_vector_categories[vector];
break;
case PPC_603:
case PPC_603e:
case PPC_603le:
case PPC_603ev:
case PPC_8260:
/* case PPC_8240: -- same value as 8260 */
case PPC_8245:
rval = mpc_603_vector_categories[vector];
break;
case PPC_e300c1:
case PPC_e300c2:
case PPC_e300c3:
rval = e300_vector_categories[vector];
break;
case PPC_PSIM:
rval = psim_vector_categories[vector];
break;
case PPC_8540:
rval = e500_vector_categories[vector];
break;
case PPC_e200z6:
rval = e200_vector_categories[vector];
break;
case PPC_5XX:
rval = mpc_5xx_vector_categories[vector];
break;
case PPC_860:
rval = mpc_860_vector_categories[vector];
break;
case PPC_405:
case PPC_405GP:
case PPC_405EX:
rval = ppc_405_vector_categories[vector];
break;
default:
printk("Please complete "
"libcpu/powerpc/new-exceptions/raw_exception.c\n"
"current_ppc_cpu = %x\n", current_ppc_cpu);
return PPC_EXC_INVALID;
}
return rval;
}
int ppc_set_exception (const rtems_raw_except_connect_data* except)
{
rtems_interrupt_level k;
if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
printk("ppc_set_exception: vector %d is not valid\n",
except->hdl.vector);
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
* You must first get the current handler via mpc60x_get_current_exception
* and then disconnect it using mpc60x_delete_exception.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (memcmp(ppc_get_vector_addr(except->hdl.vector),
(void*)default_raw_except_entry.hdl.raw_hdl,
default_raw_except_entry.hdl.raw_hdl_size)) {
printk("ppc_set_exception: raw vector not installed\n");
return 0;
}
rtems_interrupt_disable(k);
raw_except_table [except->exceptIndex] = *except;
codemove(ppc_get_vector_addr(except->hdl.vector),
except->hdl.raw_hdl,
except->hdl.raw_hdl_size,
PPC_CACHE_ALIGNMENT);
if (except->on)
except->on(except);
rtems_interrupt_enable(k);
return 1;
}
int ppc_get_current_exception (rtems_raw_except_connect_data* except)
{
rtems_interrupt_level k;
int i;
if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
return 0;
}
for (i=0; i < local_settings->exceptSize; i++) {
if ( raw_except_table[i].hdl.vector == except->hdl.vector ) {
rtems_interrupt_disable(k);
if ( raw_except_table[i].hdl.vector == except->hdl.vector ) {
*except = raw_except_table[i];
rtems_interrupt_enable(k);
return 1;
}
rtems_interrupt_enable(k);
}
}
return 0;
}
int ppc_delete_exception (const rtems_raw_except_connect_data* except)
{
rtems_interrupt_level k;
if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
return 0;
}
/*
* Check if handler passed is actually connected. If not issue an error.
* You must first get the current handler via ppc_get_current_exception
* and then disconnect it using ppc_delete_exception.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (memcmp(ppc_get_vector_addr(except->hdl.vector),
(void*)except->hdl.raw_hdl,
except->hdl.raw_hdl_size)) {
return 0;
}
rtems_interrupt_disable(k);
if (except->off)
except->off(except);
codemove(ppc_get_vector_addr(except->hdl.vector),
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;
raw_except_table[except->exceptIndex].hdl.vector = except->hdl.vector;
rtems_interrupt_enable(k);
return 1;
}
/*
* Exception global init.
*/
int ppc_init_exceptions (rtems_raw_except_global_settings* config)
{
rtems_interrupt_level k;
int i;
unsigned c;
/*
* store various accelerators
*/
raw_except_table = config->rawExceptHdlTbl;
local_settings = config;
default_raw_except_entry = config->defaultRawEntry;
rtems_interrupt_disable(k);
/* FIXME special case selection method */
if (current_ppc_cpu == PPC_e200z6) {
e200_setup_raw_exceptions();
} else if ( (c = ppc_cpu_is_bookE()) && PPC_BOOKE_405 != c ) {
e500_setup_raw_exceptions();
}
/* Need to support libbsp/powerpc/shared/vectors.S
* (hopefully this can go away some day)
* We also rely on LAST_VALID_EXC < 32
*/
for ( i=0; i <= LAST_VALID_EXC; i++ ) {
if ( PPC_EXC_405_CRITICAL == (ppc_vector_is_valid( i ) & ~PPC_EXC_ASYNC) )
bsp_raw_vector_is_405_critical |= (1<<i);
}
for (i=0; i < config->exceptSize; i++) {
if ( PPC_EXC_INVALID == ppc_vector_is_valid(raw_except_table[i].hdl.vector) ) {
continue;
}
codemove(ppc_get_vector_addr(raw_except_table[i].hdl.vector),
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) {
if (raw_except_table[i].on)
raw_except_table[i].on(&raw_except_table[i]);
}
else {
if (raw_except_table[i].off)
raw_except_table[i].off(&raw_except_table[i]);
}
}
rtems_interrupt_enable(k);
return 1;
}
int ppc_get_exception_config (rtems_raw_except_global_settings** config)
{
*config = local_settings;
return 1;
}

View File

@@ -1,259 +0,0 @@
/*
* raw_execption.h
*
* This file contains implementation of C function to
* Instantiate 60x ppc primary exception entries.
* More detailed information can be found on motorola
* site and more precisely in the following book :
*
* MPC750
* Risc Microporcessor User's Manual
* Mtorola REF : MPC750UM/AD 8/97
*
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
* Canon Centre Recherche France.
*
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
* to support 603, 603e, 604, 604e exceptions
*
* moved to "libcpu/powerpc/new-exceptions and consolidated
* by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
* to be common for all PPCs with new excpetions
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _LIBCPU_RAW_EXCEPTION_H
#define _LIBCPU_RAW_EXCEPTION_H
#include <rtems/powerpc/powerpc.h>
/* DO NOT INTRODUCE #ifdef <cpu_flavor> in this file */
#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_BOOKE_CRIT_VECTOR 0x01
/* We could use the std. decrementer vector # on bookE, too,
* but the bookE decrementer has slightly different semantics
* so we use a different vector (which happens to be
* the PIT vector on the 405 which is like the booke decrementer)
*/
#define ASM_BOOKE_DEC_VECTOR 0x10
#define ASM_BOOKE_ITLBMISS_VECTOR 0x11
#define ASM_BOOKE_DTLBMISS_VECTOR 0x12
#define ASM_BOOKE_FIT_VECTOR 0x13
#define ASM_BOOKE_WDOG_VECTOR 0x14
#define ASM_PPC405_APU_UNAVAIL_VECTOR ASM_60X_VEC_ASSIST_VECTOR
#define ASM_8XX_FLOATASSIST_VECTOR 0x0E
#define ASM_8XX_SOFTEMUL_VECTOR 0x10
#define ASM_8XX_ITLBMISS_VECTOR 0x11
#define ASM_8XX_DTLBMISS_VECTOR 0x12
#define ASM_8XX_ITLBERROR_VECTOR 0x13
#define ASM_8XX_DTLBERROR_VECTOR 0x14
#define ASM_8XX_DBREAK_VECTOR 0x1C
#define ASM_8XX_IBREAK_VECTOR 0x1D
#define ASM_8XX_PERIFBREAK_VECTOR 0x1E
#define ASM_8XX_DEVPORT_VECTOR 0x1F
#define ASM_5XX_FLOATASSIST_VECTOR 0x0E
#define ASM_5XX_SOFTEMUL_VECTOR 0x10
#define ASM_5XX_IPROT_VECTOR 0x13
#define ASM_5XX_DPROT_VECTOR 0x14
#define ASM_5XX_DBREAK_VECTOR 0x1C
#define ASM_5XX_IBREAK_VECTOR 0x1D
#define ASM_5XX_MEBREAK_VECTOR 0x1E
#define ASM_5XX_NMEBREAK_VECTOR 0x1F
#define ASM_60X_VEC_VECTOR 0x0A
#define ASM_60X_PERFMON_VECTOR 0x0F
#define ASM_60X_IMISS_VECTOR 0x10
#define ASM_60X_DLMISS_VECTOR 0x11
#define ASM_60X_DSMISS_VECTOR 0x12
#define ASM_60X_ADDR_VECTOR 0x13
#define ASM_60X_SYSMGMT_VECTOR 0x14
#define ASM_60X_VEC_ASSIST_VECTOR 0x16
#define ASM_60X_ITM_VECTOR 0x17
/* e200 */
#define ASM_E200_SPE_UNAVAILABLE_VECTOR 0x15
#define ASM_E200_SPE_DATA_VECTOR 0x16
#define ASM_E200_SPE_ROUND_VECTOR 0x17
/* e300 */
#define ASM_E300_CRIT_VECTOR 0x0A
#define ASM_E300_PERFMON_VECTOR 0x0F
#define ASM_E300_IMISS_VECTOR ASM_60X_IMISS_VECTOR /* Special case: Shadowed GPRs */
#define ASM_E300_DLMISS_VECTOR ASM_60X_DLMISS_VECTOR /* Special case: Shadowed GPRs */
#define ASM_E300_DSMISS_VECTOR ASM_60X_DSMISS_VECTOR /* Special case: Shadowed GPRs */
#define ASM_E300_ADDR_VECTOR 0x13
#define ASM_E300_SYSMGMT_VECTOR 0x14
/*
* If you change that number make sure to adjust the wrapper code in ppc_exc.S
* and that ppc_exc_handler_table will be correctly initialized.
*/
#define LAST_VALID_EXC 0x1F
/* DO NOT USE -- this symbol is DEPRECATED
* (only used by libbsp/shared/vectors/vectors.S
* which should not be used by new BSPs).
*/
#define ASM_60X_VEC_VECTOR_OFFSET 0xf20
#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 long 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;
/*
* Exceptions of different categories use different SRR registers
* to save machine state (:-()
*
* For now, the CPU descriptions assume this fits into 8 bits.
*/
typedef enum {
PPC_EXC_INVALID = 0,
PPC_EXC_CLASSIC = 1,
PPC_EXC_405_CRITICAL = 2,
PPC_EXC_BOOKE_CRITICAL = 3,
PPC_EXC_E500_MACHCHK = 4,
PPC_EXC_ASYNC = 0x80,
} ppc_raw_exception_category;
/*
* C callable function enabling to set up one raw idt entry
*/
extern int ppc_set_exception (const rtems_raw_except_connect_data*);
/*
* C callable function enabling to get one current raw idt entry
*/
extern int ppc_get_current_exception (rtems_raw_except_connect_data*);
/*
* C callable function enabling to remove one current raw idt entry
*/
extern int ppc_delete_exception (const rtems_raw_except_connect_data*);
/*
* C callable function enabling to check if vector is valid
* and returns category.
*/
extern ppc_raw_exception_category ppc_vector_is_valid(rtems_vector vector);
/*
* Exception global init.
*/
extern int ppc_init_exceptions (rtems_raw_except_global_settings* config);
extern int ppc_get_exception_config (rtems_raw_except_global_settings** config);
void* ppc_get_vector_addr(rtems_vector vector);
int ppc_is_e500();
void e200_setup_raw_exceptions(void);
void e500_setup_raw_exceptions(void);
/* This variable is initialized to 'TRUE' by default;
* BSPs which have their vectors in ROM should set it
* to FALSE prior to initializing raw exceptions.
*
* I suspect the only candidate is the simulator.
* After all, the value of this variable is used to
* determine where to install the prologue code and
* installing to ROM on anyting that's real ROM
* will fail anyways.
*
* This should probably go away... (T.S. 2007/11/30)
*/
extern bool bsp_exceptions_in_RAM;
/**
* @brief Vector base address for CPUs (for example e200 and e500) with IVPR
* and IVOR registers.
*/
extern uint32_t ppc_exc_vector_base;
# endif /* ASM */
#endif