summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c')
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c181
1 files changed, 0 insertions, 181 deletions
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c
deleted file mode 100644
index 09307cd944..0000000000
--- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
- * @file
- *
- * @ingroup ppc_exc
- *
- * @brief PowerPC Exceptions implementation.
- */
-
-/*
- * Copyright (C) 2007 Till Straumann <strauman@slac.stanford.edu>
- *
- * Copyright (C) 2009-2012 embedded brains GmbH.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <string.h>
-
-#include <bsp/vectors.h>
-
-/* Offset into minimal prolog where vector number is hardcoded */
-#define PPC_EXC_PROLOG_VEC_OFFSET 2
-
-/* Symbols are defined by the linker */
-extern const char ppc_exc_min_prolog_size [];
-extern const char ppc_exc_tgpr_clr_prolog_size [];
-
-/* Special prologue for handling register shadowing on 603-style CPUs */
-extern const uint32_t ppc_exc_tgpr_clr_prolog [];
-
-/*
- * Classic prologue which determines the vector dynamically from the offset
- * address. This must only be used for classic, synchronous exceptions with a
- * vector offset aligned on a 256-byte boundary.
- */
-extern const uint32_t ppc_exc_min_prolog_auto [];
-
-/* Minimal prologue templates */
-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_async_tmpl_p405_crit [];
-extern const uint32_t ppc_exc_min_prolog_sync_tmpl_p405_crit [];
-extern const uint32_t ppc_exc_min_prolog_async_tmpl_bookE_crit [];
-extern const uint32_t ppc_exc_min_prolog_sync_tmpl_bookE_crit [];
-extern const uint32_t ppc_exc_min_prolog_sync_tmpl_e500_mchk [];
-extern const uint32_t ppc_exc_min_prolog_async_tmpl_e500_mchk [];
-extern const uint32_t ppc_exc_min_prolog_tmpl_naked [];
-extern const uint32_t ppc_exc_min_prolog_async_tmpl_normal [];
-
-static const uint32_t *const ppc_exc_prologue_templates [] = {
- [PPC_EXC_CLASSIC] = ppc_exc_min_prolog_sync_tmpl_std,
- [PPC_EXC_CLASSIC_ASYNC] = ppc_exc_min_prolog_async_tmpl_std,
- [PPC_EXC_405_CRITICAL] = ppc_exc_min_prolog_sync_tmpl_p405_crit,
- [PPC_EXC_405_CRITICAL_ASYNC] = ppc_exc_min_prolog_async_tmpl_p405_crit,
- [PPC_EXC_BOOKE_CRITICAL] = ppc_exc_min_prolog_sync_tmpl_bookE_crit,
- [PPC_EXC_BOOKE_CRITICAL_ASYNC] = ppc_exc_min_prolog_async_tmpl_bookE_crit,
- [PPC_EXC_E500_MACHCHK] = ppc_exc_min_prolog_sync_tmpl_e500_mchk,
- [PPC_EXC_E500_MACHCHK_ASYNC] = ppc_exc_min_prolog_async_tmpl_e500_mchk,
- [PPC_EXC_NAKED] = ppc_exc_min_prolog_tmpl_naked
-};
-
-static bool ppc_exc_create_branch_op(
- unsigned vector,
- void *vector_base,
- uint32_t *prologue,
- size_t prologue_size
-)
-{
- static const uintptr_t BRANCH_OP_CODE = 18 << 26;
-/* static const uintptr_t BRANCH_OP_LINK = 0x1; */
- static const uintptr_t BRANCH_OP_ABS = 0x2;
- static const uintptr_t BRANCH_OP_MSK = 0x3ffffff;
- size_t branch_op_index = prologue_size / 4 - 1;
- uintptr_t vector_address =
- (uintptr_t) ppc_exc_vector_address(vector, vector_base);
- uintptr_t branch_op_address = vector_address + 4 * branch_op_index;
-
- /* This value may have BRANCH_OP_LINK set */
- uintptr_t target_address = prologue [branch_op_index];
-
- uintptr_t branch_target_address = target_address - branch_op_address;
-
- /*
- * We prefer to use a relative branch. This has the benefit that custom
- * minimal prologues in a read-only area are relocatable.
- */
- if ((branch_target_address & ~BRANCH_OP_MSK) != 0) {
- /* Target to far for relative branch (PC ± 32M) */
- if (target_address >= 0xfe000001 || target_address < 0x01fffffd) {
- /* Can use an absolute branch */
- branch_target_address = (target_address | BRANCH_OP_ABS) & BRANCH_OP_MSK;
- } else {
- return false;
- }
- }
-
- prologue [branch_op_index] = BRANCH_OP_CODE | branch_target_address;
-
- return true;
-}
-
-rtems_status_code ppc_exc_make_prologue(
- unsigned vector,
- void *vector_base,
- ppc_exc_category category,
- uint32_t *prologue,
- size_t *prologue_size
-)
-{
- const uint32_t *prologue_template = NULL;
- size_t prologue_template_size = 0;
- bool fixup_vector = false;
-
- if (!ppc_exc_is_valid_category(category)) {
- return RTEMS_INVALID_NUMBER;
- }
-
- if (
- ppc_cpu_has_shadowed_gprs()
- && (vector == ASM_60X_IMISS_VECTOR
- || vector == ASM_60X_DLMISS_VECTOR
- || vector == ASM_60X_DSMISS_VECTOR)
- ) {
- prologue_template = ppc_exc_tgpr_clr_prolog;
- prologue_template_size = (size_t) ppc_exc_tgpr_clr_prolog_size;
- } else if (
- category == PPC_EXC_CLASSIC
- && ppc_cpu_is_bookE() != PPC_BOOKE_STD
- && ppc_cpu_is_bookE() != PPC_BOOKE_E500
- ) {
- prologue_template = ppc_exc_min_prolog_auto;
- prologue_template_size = (size_t) ppc_exc_min_prolog_size;
-#ifdef PPC_EXC_CONFIG_USE_FIXED_HANDLER
- } else if (
- category == PPC_EXC_CLASSIC_ASYNC
- && ppc_cpu_is_bookE() == PPC_BOOKE_E500
- && (ppc_interrupt_get_disable_mask() & MSR_CE) == 0
- ) {
- prologue_template = ppc_exc_min_prolog_async_tmpl_normal;
- prologue_template_size = 16;
- fixup_vector = true;
-#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
- } else {
- prologue_template = ppc_exc_prologue_templates [category];
- prologue_template_size = (size_t) ppc_exc_min_prolog_size;
- fixup_vector = true;
- }
-
- if (prologue_template_size <= *prologue_size) {
- *prologue_size = prologue_template_size;
-
- memcpy(prologue, prologue_template, prologue_template_size);
-
- if (
- !ppc_exc_create_branch_op(
- vector,
- vector_base,
- prologue,
- prologue_template_size
- )
- ) {
- return RTEMS_INVALID_ADDRESS;
- }
-
- if (fixup_vector) {
- if (vector <= 0x7fffU) {
- prologue [PPC_EXC_PROLOG_VEC_OFFSET] =
- (prologue [PPC_EXC_PROLOG_VEC_OFFSET] & 0xffff8000U)
- | (vector & 0x7fffU);
- } else {
- return RTEMS_INVALID_ID;
- }
- }
- } else {
- return RTEMS_INVALID_SIZE;
- }
-
- return RTEMS_SUCCESSFUL;
-}