forked from Imagelibrary/rtems
2010-12-29 Sebastian Huber <sebastian.huber@embedded-brains.de>
* shared/include/cpuIdent.c, shared/include/cpuIdent.h: Added support for e500v2. Removed IVPR/IVOR/HWIVOR features since they are included in Book E. * new-exceptions/bspsupport/vectors.h, new-exceptions/bspsupport/ppc_exc.S, new-exceptions/bspsupport/ppc_exc_address.c, new-exceptions/bspsupport/ppc_exc_categories.c, new-exceptions/bspsupport/ppc_exc_initialize.c, new-exceptions/bspsupport/ppc_exc_prologue.c: Added support for e500v2. Added exception vector defines for Book E types. Removed e200 exception vector defines. Added e500 exception vector defines. Unified IVOR calculation for e200 and e500 (e200z1 has hard wired IVOR values).
This commit is contained in:
@@ -1,3 +1,19 @@
|
|||||||
|
2010-12-29 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* shared/include/cpuIdent.c, shared/include/cpuIdent.h: Added support
|
||||||
|
for e500v2. Removed IVPR/IVOR/HWIVOR features since they are included
|
||||||
|
in Book E.
|
||||||
|
* new-exceptions/bspsupport/vectors.h,
|
||||||
|
new-exceptions/bspsupport/ppc_exc.S,
|
||||||
|
new-exceptions/bspsupport/ppc_exc_address.c,
|
||||||
|
new-exceptions/bspsupport/ppc_exc_categories.c,
|
||||||
|
new-exceptions/bspsupport/ppc_exc_initialize.c,
|
||||||
|
new-exceptions/bspsupport/ppc_exc_prologue.c: Added support for
|
||||||
|
e500v2. Added exception vector defines for Book E types. Removed
|
||||||
|
e200 exception vector defines. Added e500 exception vector defines.
|
||||||
|
Unified IVOR calculation for e200 and e500 (e200z1 has hard wired
|
||||||
|
IVOR values).
|
||||||
|
|
||||||
2010-12-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
2010-12-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
* mpc83xx/i2c/mpc83xx_i2cdrv.c: Fixed interrupt flag clearing for
|
* mpc83xx/i2c/mpc83xx_i2cdrv.c: Fixed interrupt flag clearing for
|
||||||
|
|||||||
@@ -71,24 +71,6 @@ ppc_exc_min_prolog_auto:
|
|||||||
.global ppc_exc_tgpr_clr_prolog_size
|
.global ppc_exc_tgpr_clr_prolog_size
|
||||||
ppc_exc_tgpr_clr_prolog_size = . - ppc_exc_tgpr_clr_prolog
|
ppc_exc_tgpr_clr_prolog_size = . - ppc_exc_tgpr_clr_prolog
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Use vector offsets with 16 byte boundaries.
|
|
||||||
*
|
|
||||||
* This prologue is intended for cores with IVPR/IVOR registers. The e200z1
|
|
||||||
* core has hard wired values for the IVOR, thus all values are calculated to
|
|
||||||
* match its constraints. The link register will point to the next prologue.
|
|
||||||
* This is all right for the vector number calculation due the IVOR offset
|
|
||||||
* values.
|
|
||||||
*
|
|
||||||
* @see ppc_exc_min_prolog_auto();
|
|
||||||
*/
|
|
||||||
.global ppc_exc_min_prolog_auto_packed
|
|
||||||
ppc_exc_min_prolog_auto_packed:
|
|
||||||
stwu r1, -EXCEPTION_FRAME_END(r1)
|
|
||||||
stw VECTOR_REGISTER, VECTOR_OFFSET(r1)
|
|
||||||
mflr VECTOR_REGISTER
|
|
||||||
bla wrap_auto_packed
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Automatic vector, asynchronous exception; however,
|
* Automatic vector, asynchronous exception; however,
|
||||||
* automatic vector calculation is less efficient than
|
* automatic vector calculation is less efficient than
|
||||||
@@ -156,14 +138,6 @@ wrap_auto:
|
|||||||
*/
|
*/
|
||||||
b wrap_no_save_frame_register_std
|
b wrap_no_save_frame_register_std
|
||||||
|
|
||||||
/* See: wrap_auto */
|
|
||||||
wrap_auto_packed:
|
|
||||||
stw FRAME_REGISTER, FRAME_OFFSET(r1)
|
|
||||||
mflr FRAME_REGISTER
|
|
||||||
mtlr VECTOR_REGISTER
|
|
||||||
rlwinm VECTOR_REGISTER, FRAME_REGISTER, 28, 26, 31
|
|
||||||
b wrap_no_save_frame_register_std
|
|
||||||
|
|
||||||
wrap_auto_async:
|
wrap_auto_async:
|
||||||
stwu r1, -EXCEPTION_FRAME_END(r1)
|
stwu r1, -EXCEPTION_FRAME_END(r1)
|
||||||
stw FRAME_REGISTER, FRAME_OFFSET(r1)
|
stw FRAME_REGISTER, FRAME_OFFSET(r1)
|
||||||
|
|||||||
@@ -36,6 +36,33 @@ bool bsp_exceptions_in_RAM = true;
|
|||||||
|
|
||||||
uint32_t ppc_exc_vector_base = 0;
|
uint32_t ppc_exc_vector_base = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: These values are choosen to directly generate the vector offsets for an
|
||||||
|
* e200z1 which has hard wired IVORs (IVOR0=0x00, IVOR1=0x10, IVOR2=0x20, ...).
|
||||||
|
*/
|
||||||
|
static const uint8_t ivor_values [] = {
|
||||||
|
[ASM_BOOKE_CRIT_VECTOR] = 0,
|
||||||
|
[ASM_MACH_VECTOR] = 1,
|
||||||
|
[ASM_PROT_VECTOR] = 2,
|
||||||
|
[ASM_ISI_VECTOR] = 3,
|
||||||
|
[ASM_EXT_VECTOR] = 4,
|
||||||
|
[ASM_ALIGN_VECTOR] = 5,
|
||||||
|
[ASM_PROG_VECTOR] = 6,
|
||||||
|
[ASM_FLOAT_VECTOR] = 7,
|
||||||
|
[ASM_SYS_VECTOR] = 8,
|
||||||
|
[ASM_BOOKE_APU_VECTOR] = 9,
|
||||||
|
[ASM_BOOKE_DEC_VECTOR] = 10,
|
||||||
|
[ASM_BOOKE_FIT_VECTOR] = 11,
|
||||||
|
[ASM_BOOKE_WDOG_VECTOR] = 12,
|
||||||
|
[ASM_BOOKE_DTLBMISS_VECTOR] = 13,
|
||||||
|
[ASM_BOOKE_ITLBMISS_VECTOR] = 14,
|
||||||
|
[ASM_BOOKE_DEBUG_VECTOR] = 15,
|
||||||
|
[ASM_E500_SPE_UNAVAILABLE_VECTOR] = 32,
|
||||||
|
[ASM_E500_EMB_FP_DATA_VECTOR] = 33,
|
||||||
|
[ASM_E500_EMB_FP_ROUND_VECTOR] = 34,
|
||||||
|
[ASM_E500_PERFMON_VECTOR] = 35
|
||||||
|
};
|
||||||
|
|
||||||
void *ppc_exc_vector_address(unsigned vector)
|
void *ppc_exc_vector_address(unsigned vector)
|
||||||
{
|
{
|
||||||
uintptr_t vector_base = 0xfff00000;
|
uintptr_t vector_base = 0xfff00000;
|
||||||
@@ -65,12 +92,15 @@ void *ppc_exc_vector_address(unsigned vector)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ppc_cpu_has_ivpr_and_ivor()) {
|
if (
|
||||||
/*
|
ppc_cpu_is_bookE() == PPC_BOOKE_STD
|
||||||
* XXX: this directly matches the vector offsets in a e200z1,
|
|| ppc_cpu_is_bookE() == PPC_BOOKE_E500
|
||||||
* which has hardwired IVORs (IVOR0=0,IVOR1=0x10,IVOR2=0x20...)
|
) {
|
||||||
*/
|
if (vector < sizeof(ivor_values) / sizeof(ivor_values [0])) {
|
||||||
vector_offset = (vector - 1) << 4;
|
vector_offset = ((uintptr_t) ivor_values [vector]) << 4;
|
||||||
|
} else {
|
||||||
|
vector_offset = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bsp_exceptions_in_RAM) {
|
if (bsp_exceptions_in_RAM) {
|
||||||
|
|||||||
@@ -150,29 +150,6 @@ static const ppc_exc_categories mpc_860_category_table = {
|
|||||||
[ASM_8XX_DEVPORT_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_8XX_DEVPORT_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ppc_exc_categories e200_category_table = {
|
|
||||||
[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 ppc_exc_categories e300_category_table = {
|
static const ppc_exc_categories e300_category_table = {
|
||||||
[ASM_RESET_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_RESET_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ASM_MACH_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_MACH_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
@@ -195,32 +172,49 @@ static const ppc_exc_categories e300_category_table = {
|
|||||||
[ASM_E300_SYSMGMT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
|
[ASM_E300_SYSMGMT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ppc_exc_categories e500_category_table = {
|
static const ppc_exc_categories e200_category_table = {
|
||||||
[ASM_MACH_VECTOR] = PPC_EXC_E500_MACHCHK,
|
|
||||||
|
|
||||||
[ASM_BOOKE_CRIT_VECTOR] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
|
[ASM_BOOKE_CRIT_VECTOR] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
|
||||||
[ASM_BOOKE_WDOG_VECTOR] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
|
[ASM_MACH_VECTOR] = PPC_EXC_E500_MACHCHK,
|
||||||
[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_PROT_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ASM_ISI_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_ALIGN_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ASM_PROG_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_PROG_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ASM_FLOAT_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_FLOAT_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ASM_SYS_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_SYS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ /* APU unavailable */ 0x0b] = 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_DTLBMISS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
[ASM_BOOKE_ITLBMISS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
|
||||||
[ASM_60X_DLMISS_VECTOR] = PPC_EXC_CLASSIC,
|
/* FIXME: Depending on HDI0 [DAPUEN] this is a critical or debug exception */
|
||||||
[ASM_60X_DSMISS_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_BOOKE_DEBUG_VECTOR] = PPC_EXC_BOOKE_CRITICAL,
|
||||||
[ASM_60X_VEC_VECTOR] = PPC_EXC_CLASSIC,
|
|
||||||
[ASM_60X_PERFMON_VECTOR] = PPC_EXC_CLASSIC,
|
|
||||||
|
|
||||||
[ /* emb FP data */ 0x15] = PPC_EXC_CLASSIC,
|
[ASM_E500_SPE_UNAVAILABLE_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ /* emb FP round */ 0x16] = PPC_EXC_CLASSIC,
|
[ASM_E500_EMB_FP_DATA_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
[ASM_E500_EMB_FP_ROUND_VECTOR] = PPC_EXC_CLASSIC
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ppc_exc_categories e500_category_table = {
|
||||||
|
[ASM_MACH_VECTOR] = PPC_EXC_E500_MACHCHK,
|
||||||
|
[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_DTLBMISS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
[ASM_BOOKE_ITLBMISS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
[ASM_BOOKE_DEBUG_VECTOR] = PPC_EXC_BOOKE_CRITICAL,
|
||||||
|
[ASM_E500_SPE_UNAVAILABLE_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
[ASM_E500_EMB_FP_DATA_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
[ASM_E500_EMB_FP_ROUND_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
[ASM_E500_PERFMON_VECTOR] = PPC_EXC_CLASSIC
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ppc_exc_categories psim_category_table = {
|
static const ppc_exc_categories psim_category_table = {
|
||||||
@@ -274,6 +268,7 @@ const ppc_exc_categories *ppc_exc_categories_for_cpu(ppc_cpu_id_t cpu)
|
|||||||
case PPC_PSIM:
|
case PPC_PSIM:
|
||||||
return &psim_category_table;
|
return &psim_category_table;
|
||||||
case PPC_8540:
|
case PPC_8540:
|
||||||
|
case PPC_e500v2:
|
||||||
return &e500_category_table;
|
return &e500_category_table;
|
||||||
case PPC_e200z0:
|
case PPC_e200z0:
|
||||||
case PPC_e200z1:
|
case PPC_e200z1:
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ uint32_t ppc_exc_cache_wb_check = 1;
|
|||||||
#define MTIVPR(prefix) asm volatile ("mtivpr %0" : : "r" (prefix))
|
#define MTIVPR(prefix) asm volatile ("mtivpr %0" : : "r" (prefix))
|
||||||
#define MTIVOR(x, vec) asm volatile ("mtivor"#x" %0" : : "r" (vec))
|
#define MTIVOR(x, vec) asm volatile ("mtivor"#x" %0" : : "r" (vec))
|
||||||
|
|
||||||
static void ppc_exc_initialize_e500(void)
|
static void ppc_exc_initialize_booke(void)
|
||||||
{
|
{
|
||||||
/* Interupt vector prefix register */
|
/* Interupt vector prefix register */
|
||||||
MTIVPR(ppc_exc_vector_base);
|
MTIVPR(ppc_exc_vector_base);
|
||||||
|
|
||||||
/* Interupt vector offset register */
|
/* Interupt vector offset registers */
|
||||||
MTIVOR(0, ppc_exc_vector_address(ASM_BOOKE_CRIT_VECTOR)); /* Critical input not (yet) supported; use reset vector */
|
MTIVOR(0, ppc_exc_vector_address(ASM_BOOKE_CRIT_VECTOR));
|
||||||
MTIVOR(1, ppc_exc_vector_address(ASM_MACH_VECTOR));
|
MTIVOR(1, ppc_exc_vector_address(ASM_MACH_VECTOR));
|
||||||
MTIVOR(2, ppc_exc_vector_address(ASM_PROT_VECTOR));
|
MTIVOR(2, ppc_exc_vector_address(ASM_PROT_VECTOR));
|
||||||
MTIVOR(3, ppc_exc_vector_address(ASM_ISI_VECTOR));
|
MTIVOR(3, ppc_exc_vector_address(ASM_ISI_VECTOR));
|
||||||
@@ -48,45 +48,20 @@ static void ppc_exc_initialize_e500(void)
|
|||||||
MTIVOR(6, ppc_exc_vector_address(ASM_PROG_VECTOR));
|
MTIVOR(6, ppc_exc_vector_address(ASM_PROG_VECTOR));
|
||||||
MTIVOR(7, ppc_exc_vector_address(ASM_FLOAT_VECTOR));
|
MTIVOR(7, ppc_exc_vector_address(ASM_FLOAT_VECTOR));
|
||||||
MTIVOR(8, ppc_exc_vector_address(ASM_SYS_VECTOR));
|
MTIVOR(8, ppc_exc_vector_address(ASM_SYS_VECTOR));
|
||||||
MTIVOR(9, ppc_exc_vector_address(0x0b));
|
MTIVOR(9, ppc_exc_vector_address(ASM_BOOKE_APU_VECTOR));
|
||||||
MTIVOR(10, ppc_exc_vector_address(ASM_BOOKE_DEC_VECTOR));
|
MTIVOR(10, ppc_exc_vector_address(ASM_BOOKE_DEC_VECTOR));
|
||||||
MTIVOR(11, ppc_exc_vector_address(ASM_BOOKE_FIT_VECTOR));
|
MTIVOR(11, ppc_exc_vector_address(ASM_BOOKE_FIT_VECTOR));
|
||||||
MTIVOR(12, ppc_exc_vector_address(ASM_BOOKE_WDOG_VECTOR));
|
MTIVOR(12, ppc_exc_vector_address(ASM_BOOKE_WDOG_VECTOR));
|
||||||
MTIVOR(13, ppc_exc_vector_address(ASM_60X_DSMISS_VECTOR));
|
MTIVOR(13, ppc_exc_vector_address(ASM_BOOKE_DTLBMISS_VECTOR));
|
||||||
MTIVOR(14, ppc_exc_vector_address(ASM_60X_DLMISS_VECTOR));
|
MTIVOR(14, ppc_exc_vector_address(ASM_BOOKE_ITLBMISS_VECTOR));
|
||||||
MTIVOR(15, ppc_exc_vector_address(ASM_TRACE_VECTOR));
|
MTIVOR(15, ppc_exc_vector_address(ASM_BOOKE_DEBUG_VECTOR));
|
||||||
MTIVOR(32, ppc_exc_vector_address(ASM_60X_VEC_VECTOR));
|
if (ppc_cpu_is_e200() || ppc_cpu_is_e500()) {
|
||||||
MTIVOR(33, ppc_exc_vector_address(0x16));
|
MTIVOR(32, ppc_exc_vector_address(ASM_E500_SPE_UNAVAILABLE_VECTOR));
|
||||||
MTIVOR(34, ppc_exc_vector_address(0x15));
|
MTIVOR(33, ppc_exc_vector_address(ASM_E500_EMB_FP_DATA_VECTOR));
|
||||||
MTIVOR(35, ppc_exc_vector_address(ASM_60X_PERFMON_VECTOR));
|
MTIVOR(34, ppc_exc_vector_address(ASM_E500_EMB_FP_ROUND_VECTOR));
|
||||||
}
|
}
|
||||||
|
if (ppc_cpu_is_e500()) {
|
||||||
static void ppc_exc_initialize_e200(void)
|
MTIVOR(35, ppc_exc_vector_address(ASM_E500_PERFMON_VECTOR));
|
||||||
{
|
|
||||||
/* Interupt vector prefix register */
|
|
||||||
MTIVPR(ppc_exc_vector_base);
|
|
||||||
|
|
||||||
if (ppc_cpu_has_ivor()) {
|
|
||||||
/* Interupt vector offset register */
|
|
||||||
MTIVOR(0, 0); /* Critical input */
|
|
||||||
MTIVOR(1, ppc_exc_vector_address( ASM_MACH_VECTOR));
|
|
||||||
MTIVOR(2, ppc_exc_vector_address( ASM_PROT_VECTOR));
|
|
||||||
MTIVOR(3, ppc_exc_vector_address( ASM_ISI_VECTOR));
|
|
||||||
MTIVOR(4, ppc_exc_vector_address( ASM_EXT_VECTOR));
|
|
||||||
MTIVOR(5, ppc_exc_vector_address( ASM_ALIGN_VECTOR));
|
|
||||||
MTIVOR(6, ppc_exc_vector_address( ASM_PROG_VECTOR));
|
|
||||||
MTIVOR(7, ppc_exc_vector_address( ASM_FLOAT_VECTOR));
|
|
||||||
MTIVOR(8, ppc_exc_vector_address( ASM_SYS_VECTOR));
|
|
||||||
MTIVOR(9, 0); /* APU unavailable */
|
|
||||||
MTIVOR(10, ppc_exc_vector_address( ASM_BOOKE_DEC_VECTOR));
|
|
||||||
MTIVOR(11, ppc_exc_vector_address( ASM_BOOKE_FIT_VECTOR));
|
|
||||||
MTIVOR(12, ppc_exc_vector_address( ASM_BOOKE_WDOG_VECTOR));
|
|
||||||
MTIVOR(13, ppc_exc_vector_address( ASM_BOOKE_ITLBMISS_VECTOR));
|
|
||||||
MTIVOR(14, ppc_exc_vector_address( ASM_BOOKE_DTLBMISS_VECTOR));
|
|
||||||
MTIVOR(15, ppc_exc_vector_address( ASM_TRACE_VECTOR));
|
|
||||||
MTIVOR(32, ppc_exc_vector_address( ASM_E200_SPE_UNAVAILABLE_VECTOR));
|
|
||||||
MTIVOR(33, ppc_exc_vector_address( ASM_E200_SPE_DATA_VECTOR));
|
|
||||||
MTIVOR(34, ppc_exc_vector_address( ASM_E200_SPE_ROUND_VECTOR));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +98,7 @@ rtems_status_code ppc_exc_initialize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure proper interrupt stack alignment */
|
/* Ensure proper interrupt stack alignment */
|
||||||
interrupt_stack_pointer &= ~((uint32_t) CPU_STACK_ALIGNMENT - 1);
|
interrupt_stack_pointer &= ~((uintptr_t) CPU_STACK_ALIGNMENT - 1);
|
||||||
|
|
||||||
/* Tag interrupt stack bottom */
|
/* Tag interrupt stack bottom */
|
||||||
*(uint32_t *) interrupt_stack_pointer = 0;
|
*(uint32_t *) interrupt_stack_pointer = 0;
|
||||||
@@ -142,11 +117,8 @@ rtems_status_code ppc_exc_initialize(
|
|||||||
ppc_exc_msr_bits |= MSR_VE;
|
ppc_exc_msr_bits |= MSR_VE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ppc_cpu_is(PPC_e200z1) ||
|
if (ppc_cpu_is_bookE() == PPC_BOOKE_STD || ppc_cpu_is_bookE() == PPC_BOOKE_E500) {
|
||||||
ppc_cpu_is(PPC_e200z6)) {
|
ppc_exc_initialize_booke();
|
||||||
ppc_exc_initialize_e200();
|
|
||||||
} else if (ppc_cpu_is_bookE() == PPC_BOOKE_STD || ppc_cpu_is_bookE() == PPC_BOOKE_E500) {
|
|
||||||
ppc_exc_initialize_e500();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vector = 0; vector <= LAST_VALID_EXC; ++vector) {
|
for (vector = 0; vector <= LAST_VALID_EXC; ++vector) {
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ extern const uint32_t ppc_exc_tgpr_clr_prolog [];
|
|||||||
*/
|
*/
|
||||||
extern const uint32_t ppc_exc_min_prolog_auto [];
|
extern const uint32_t ppc_exc_min_prolog_auto [];
|
||||||
|
|
||||||
extern const uint32_t ppc_exc_min_prolog_auto_packed [];
|
|
||||||
|
|
||||||
/* Minimal prologue templates */
|
/* Minimal prologue templates */
|
||||||
extern const uint32_t ppc_exc_min_prolog_async_tmpl_std [];
|
extern const uint32_t ppc_exc_min_prolog_async_tmpl_std [];
|
||||||
extern const uint32_t ppc_exc_min_prolog_sync_tmpl_std [];
|
extern const uint32_t ppc_exc_min_prolog_sync_tmpl_std [];
|
||||||
@@ -90,14 +88,10 @@ rtems_status_code ppc_exc_make_prologue(
|
|||||||
prologue_template_size = (size_t) ppc_exc_tgpr_clr_prolog_size;
|
prologue_template_size = (size_t) ppc_exc_tgpr_clr_prolog_size;
|
||||||
} else if (
|
} else if (
|
||||||
category == PPC_EXC_CLASSIC
|
category == PPC_EXC_CLASSIC
|
||||||
&& ((vector_address & 0xffU) == 0
|
&& ppc_cpu_is_bookE() != PPC_BOOKE_STD
|
||||||
|| (ppc_cpu_has_ivpr_and_ivor() && (vector_address & 0xfU) == 0))
|
&& ppc_cpu_is_bookE() != PPC_BOOKE_E500
|
||||||
) {
|
) {
|
||||||
if (ppc_cpu_has_ivpr_and_ivor()) {
|
prologue_template = ppc_exc_min_prolog_auto;
|
||||||
prologue_template = ppc_exc_min_prolog_auto_packed;
|
|
||||||
} else {
|
|
||||||
prologue_template = ppc_exc_min_prolog_auto;
|
|
||||||
}
|
|
||||||
prologue_template_size = (size_t) ppc_exc_min_prolog_size;
|
prologue_template_size = (size_t) ppc_exc_min_prolog_size;
|
||||||
} else {
|
} else {
|
||||||
prologue_template = ppc_exc_prologue_templates [category];
|
prologue_template = ppc_exc_prologue_templates [category];
|
||||||
|
|||||||
@@ -59,18 +59,6 @@
|
|||||||
#define ASM_SYS_VECTOR 0x0C
|
#define ASM_SYS_VECTOR 0x0C
|
||||||
#define ASM_TRACE_VECTOR 0x0D
|
#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_PPC405_APU_UNAVAIL_VECTOR ASM_60X_VEC_ASSIST_VECTOR
|
||||||
|
|
||||||
#define ASM_8XX_FLOATASSIST_VECTOR 0x0E
|
#define ASM_8XX_FLOATASSIST_VECTOR 0x0E
|
||||||
@@ -103,19 +91,35 @@
|
|||||||
#define ASM_60X_VEC_ASSIST_VECTOR 0x16
|
#define ASM_60X_VEC_ASSIST_VECTOR 0x16
|
||||||
#define ASM_60X_ITM_VECTOR 0x17
|
#define ASM_60X_ITM_VECTOR 0x17
|
||||||
|
|
||||||
/* e200 */
|
/* Book E */
|
||||||
#define ASM_E200_SPE_UNAVAILABLE_VECTOR 0x15
|
#define ASM_BOOKE_CRIT_VECTOR 0x01
|
||||||
#define ASM_E200_SPE_DATA_VECTOR 0x16
|
/* We could use the std. decrementer vector # on bookE, too,
|
||||||
#define ASM_E200_SPE_ROUND_VECTOR 0x17
|
* 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_BOOKE_APU_VECTOR 0x18
|
||||||
|
#define ASM_BOOKE_DEBUG_VECTOR ASM_TRACE_VECTOR
|
||||||
|
|
||||||
|
/* e200 and e500 */
|
||||||
|
#define ASM_E500_SPE_UNAVAILABLE_VECTOR ASM_60X_VEC_VECTOR
|
||||||
|
#define ASM_E500_EMB_FP_DATA_VECTOR 0x19
|
||||||
|
#define ASM_E500_EMB_FP_ROUND_VECTOR 0x1A
|
||||||
|
#define ASM_E500_PERFMON_VECTOR ASM_60X_PERFMON_VECTOR
|
||||||
|
|
||||||
/* e300 */
|
/* e300 */
|
||||||
#define ASM_E300_CRIT_VECTOR 0x0A
|
#define ASM_E300_CRIT_VECTOR 0x0A
|
||||||
#define ASM_E300_PERFMON_VECTOR 0x0F
|
#define ASM_E300_PERFMON_VECTOR ASM_60X_PERFMON_VECTOR
|
||||||
#define ASM_E300_IMISS_VECTOR ASM_60X_IMISS_VECTOR /* Special case: Shadowed GPRs */
|
#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_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_DSMISS_VECTOR ASM_60X_DSMISS_VECTOR /* Special case: Shadowed GPRs */
|
||||||
#define ASM_E300_ADDR_VECTOR 0x13
|
#define ASM_E300_ADDR_VECTOR ASM_60X_ADDR_VECTOR
|
||||||
#define ASM_E300_SYSMGMT_VECTOR 0x14
|
#define ASM_E300_SYSMGMT_VECTOR ASM_60X_SYSMGMT_VECTOR
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you change that number make sure to adjust the wrapper code in ppc_exc.S
|
* If you change that number make sure to adjust the wrapper code in ppc_exc.S
|
||||||
|
|||||||
@@ -25,19 +25,7 @@ SPR_RO(PVR)
|
|||||||
|
|
||||||
ppc_cpu_id_t current_ppc_cpu = PPC_UNKNOWN;
|
ppc_cpu_id_t current_ppc_cpu = PPC_UNKNOWN;
|
||||||
ppc_cpu_revision_t current_ppc_revision = 0xff;
|
ppc_cpu_revision_t current_ppc_revision = 0xff;
|
||||||
ppc_feature_t current_ppc_features = {
|
ppc_feature_t current_ppc_features;
|
||||||
.has_altivec = 0,
|
|
||||||
.has_fpu = 0,
|
|
||||||
.has_hw_ptbl_lkup = 0,
|
|
||||||
.is_bookE = 0,
|
|
||||||
.has_16byte_clne = 0,
|
|
||||||
.is_60x = 0,
|
|
||||||
.has_8_bats = 0,
|
|
||||||
.has_epic = 0,
|
|
||||||
.has_shadowed_gprs = 0,
|
|
||||||
.has_ivpr = 0,
|
|
||||||
.has_ivor = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu)
|
char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu)
|
||||||
{
|
{
|
||||||
@@ -66,6 +54,7 @@ char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu)
|
|||||||
case PPC_e200z0: return "e200z0";
|
case PPC_e200z0: return "e200z0";
|
||||||
case PPC_e200z1: return "e200z1";
|
case PPC_e200z1: return "e200z1";
|
||||||
case PPC_e200z6: return "e200z6";
|
case PPC_e200z6: return "e200z6";
|
||||||
|
case PPC_e500v2: return "e500v2";
|
||||||
default:
|
default:
|
||||||
printk("Unknown CPU value of 0x%x. Please add it to "
|
printk("Unknown CPU value of 0x%x. Please add it to "
|
||||||
"<libcpu/powerpc/shared/include/cpuIdent.c>\n", cpu );
|
"<libcpu/powerpc/shared/include/cpuIdent.c>\n", cpu );
|
||||||
@@ -134,6 +123,7 @@ ppc_cpu_id_t get_ppc_cpu_type(void)
|
|||||||
case PPC_e300c1:
|
case PPC_e300c1:
|
||||||
case PPC_e300c2:
|
case PPC_e300c2:
|
||||||
case PPC_e300c3:
|
case PPC_e300c3:
|
||||||
|
case PPC_e500v2:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("Unknown PVR value of 0x%x. Please add it to "
|
printk("Unknown PVR value of 0x%x. Please add it to "
|
||||||
@@ -189,6 +179,7 @@ ppc_cpu_id_t get_ppc_cpu_type(void)
|
|||||||
case PPC_e200z0:
|
case PPC_e200z0:
|
||||||
case PPC_e200z1:
|
case PPC_e200z1:
|
||||||
case PPC_e200z6:
|
case PPC_e200z6:
|
||||||
|
case PPC_e500v2:
|
||||||
current_ppc_features.is_bookE = PPC_BOOKE_E500;
|
current_ppc_features.is_bookE = PPC_BOOKE_E500;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -214,20 +205,6 @@ ppc_cpu_id_t get_ppc_cpu_type(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (current_ppc_cpu) {
|
|
||||||
case PPC_e200z0:
|
|
||||||
case PPC_e200z1:
|
|
||||||
current_ppc_features.has_ivpr = 1;
|
|
||||||
current_ppc_features.has_hwivor = 1;
|
|
||||||
break;
|
|
||||||
case PPC_e200z6:
|
|
||||||
current_ppc_features.has_ivpr = 1;
|
|
||||||
current_ppc_features.has_ivor = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return current_ppc_cpu;
|
return current_ppc_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ typedef enum
|
|||||||
PPC_8240 = PPC_8260,
|
PPC_8240 = PPC_8260,
|
||||||
PPC_8245 = 0x8081,
|
PPC_8245 = 0x8081,
|
||||||
PPC_8540 = 0x8020,
|
PPC_8540 = 0x8020,
|
||||||
|
PPC_e500v2 = 0x8021,
|
||||||
PPC_603le = 0x8082, /* 603le core, in MGT5100 and MPC5200 */
|
PPC_603le = 0x8082, /* 603le core, in MGT5100 and MPC5200 */
|
||||||
PPC_e300c1 = 0x8083, /* e300c1 core, in MPC83xx*/
|
PPC_e300c1 = 0x8083, /* e300c1 core, in MPC83xx*/
|
||||||
PPC_e300c2 = 0x8084, /* e300c2 core */
|
PPC_e300c2 = 0x8084, /* e300c2 core */
|
||||||
@@ -82,9 +83,6 @@ typedef struct {
|
|||||||
unsigned has_8_bats : 1;
|
unsigned has_8_bats : 1;
|
||||||
unsigned has_epic : 1;
|
unsigned has_epic : 1;
|
||||||
unsigned has_shadowed_gprs : 1;
|
unsigned has_shadowed_gprs : 1;
|
||||||
unsigned has_ivpr : 1;
|
|
||||||
unsigned has_ivor : 1;
|
|
||||||
unsigned has_hwivor : 1;
|
|
||||||
} ppc_feature_t;
|
} ppc_feature_t;
|
||||||
|
|
||||||
extern ppc_feature_t current_ppc_features;
|
extern ppc_feature_t current_ppc_features;
|
||||||
@@ -113,32 +111,34 @@ _PPC_FEAT_DECL(is_60x)
|
|||||||
_PPC_FEAT_DECL(has_8_bats)
|
_PPC_FEAT_DECL(has_8_bats)
|
||||||
_PPC_FEAT_DECL(has_epic)
|
_PPC_FEAT_DECL(has_epic)
|
||||||
_PPC_FEAT_DECL(has_shadowed_gprs)
|
_PPC_FEAT_DECL(has_shadowed_gprs)
|
||||||
_PPC_FEAT_DECL(has_ivpr)
|
|
||||||
_PPC_FEAT_DECL(has_ivor)
|
|
||||||
_PPC_FEAT_DECL(has_hwivor)
|
|
||||||
|
|
||||||
#undef _PPC_FEAT_DECL
|
#undef _PPC_FEAT_DECL
|
||||||
|
|
||||||
static inline unsigned ppc_cpu_has_ivpr_and_ivor() { \
|
|
||||||
return ppc_cpu_has_ivpr()
|
|
||||||
&& (ppc_cpu_has_ivor() || ppc_cpu_has_hwivor());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline ppc_cpu_id_t ppc_cpu_current(void)
|
static inline ppc_cpu_id_t ppc_cpu_current(void)
|
||||||
{
|
{
|
||||||
return current_ppc_cpu;
|
return current_ppc_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool ppc_cpu_is_e200()
|
||||||
|
{
|
||||||
|
return ppc_cpu_current() == PPC_e200z0
|
||||||
|
|| ppc_cpu_current() == PPC_e200z1
|
||||||
|
|| ppc_cpu_current() == PPC_e200z6;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool ppc_cpu_is_e300()
|
static inline bool ppc_cpu_is_e300()
|
||||||
{
|
{
|
||||||
if (ppc_cpu_current() == PPC_UNKNOWN) {
|
|
||||||
get_ppc_cpu_type();
|
|
||||||
}
|
|
||||||
return ppc_cpu_current() == PPC_e300c1
|
return ppc_cpu_current() == PPC_e300c1
|
||||||
|| ppc_cpu_current() == PPC_e300c2
|
|| ppc_cpu_current() == PPC_e300c2
|
||||||
|| ppc_cpu_current() == PPC_e300c3;
|
|| ppc_cpu_current() == PPC_e300c3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool ppc_cpu_is_e500()
|
||||||
|
{
|
||||||
|
return ppc_cpu_current() == PPC_8540
|
||||||
|
|| ppc_cpu_current() == PPC_e500v2;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool ppc_cpu_is(ppc_cpu_id_t cpu)
|
static inline bool ppc_cpu_is(ppc_cpu_id_t cpu)
|
||||||
{
|
{
|
||||||
return ppc_cpu_current() == cpu;
|
return ppc_cpu_current() == cpu;
|
||||||
|
|||||||
Reference in New Issue
Block a user