mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-11-09 08:37:58 +08:00
cpukit/aarch64: Refactor exception handling
This refactors the AArch64 exception handling to remove the mutable code sections that are generally flagged as a bad idea by code analysis tools. This also removes any casting between data pointers and function pointers to avoid the need to use pragmas to disable warnings about such casting.
This commit is contained in:
1 parent
ad5a2be4c1
commit
dc0d3149e5
5 files changed
+199
-165
No files matched your search
@@ -117,13 +117,9 @@ typedef struct {
|
||||
.end = (uintptr_t) bsp_translation_table_end, \
|
||||
.flags = AARCH64_MMU_DATA_RW_CACHED \
|
||||
}, { \
|
||||
/*
|
||||
* The vector table must be in writable and executable memory as it stores both
|
||||
* exception code and the mutable pointer to which it jumps
|
||||
*/ \
|
||||
.begin = (uintptr_t) bsp_start_vector_table_begin, \
|
||||
.end = (uintptr_t) bsp_start_vector_table_end, \
|
||||
.flags = AARCH64_MMU_CODE_RW_CACHED \
|
||||
.flags = AARCH64_MMU_CODE_CACHED \
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSScoreCPUAArch64
|
||||
*
|
||||
* @brief This source file contains the jump targets for AArch64 exceptions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 On-Line Applications Research Corporation (OAR)
|
||||
* Written by Kinsey Moore <kinsey.moore@oarcorp.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
void aarch64_exception_dump_sp0(void);
|
||||
void aarch64_exception_dump_spx(void);
|
||||
|
||||
AArch64_Exception_Handler aarch64_exception_sp0_synchronous =
|
||||
(AArch64_Exception_Handler) &_AArch64_Exception_default;
|
||||
AArch64_Exception_Handler aarch64_exception_sp0_irq =
|
||||
&aarch64_exception_dump_sp0;
|
||||
AArch64_Exception_Handler aarch64_exception_sp0_fiq =
|
||||
&aarch64_exception_dump_sp0;
|
||||
AArch64_Exception_Handler aarch64_exception_sp0_serror =
|
||||
&aarch64_exception_dump_sp0;
|
||||
AArch64_Exception_Handler aarch64_exception_spx_synchronous =
|
||||
(AArch64_Exception_Handler) &_AArch64_Exception_default;
|
||||
AArch64_Exception_Handler aarch64_exception_spx_irq =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_spx_fiq =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_spx_serror =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel64_synchronous =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel64_irq =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel64_fiq =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel64_serror =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel32_synchronous =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel32_irq =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel32_fiq =
|
||||
&aarch64_exception_dump_spx;
|
||||
AArch64_Exception_Handler aarch64_exception_lel32_serror =
|
||||
&aarch64_exception_dump_spx;
|
||||
@@ -407,40 +407,94 @@ typedef enum {
|
||||
AARCH64_EXCEPTION_MAKE_ENUM_64_BIT = INT_MAX
|
||||
} AArch64_symbolic_exception_name;
|
||||
|
||||
typedef void(*AArch64_Exception_Handler)(void);
|
||||
extern AArch64_Exception_Handler aarch64_exception_sp0_synchronous;
|
||||
extern AArch64_Exception_Handler aarch64_exception_sp0_irq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_sp0_fiq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_sp0_serror;
|
||||
extern AArch64_Exception_Handler aarch64_exception_spx_synchronous;
|
||||
extern AArch64_Exception_Handler aarch64_exception_spx_irq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_spx_fiq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_spx_serror;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel64_synchronous;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel64_irq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel64_fiq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel64_serror;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel32_synchronous;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel32_irq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel32_fiq;
|
||||
extern AArch64_Exception_Handler aarch64_exception_lel32_serror;
|
||||
|
||||
#define VECTOR_POINTER_OFFSET 0x78
|
||||
#define VECTOR_ENTRY_SIZE 0x80
|
||||
void _AArch64_Exception_interrupt_no_nest( void );
|
||||
void _AArch64_Exception_interrupt_nest( void );
|
||||
static inline void* AArch64_set_exception_handler(
|
||||
static inline AArch64_Exception_Handler AArch64_set_exception_handler(
|
||||
AArch64_symbolic_exception_name exception,
|
||||
void (*handler)(void)
|
||||
AArch64_Exception_Handler handler
|
||||
)
|
||||
{
|
||||
/* get current table address */
|
||||
char *vbar = (char*)AArch64_get_vector_base_address();
|
||||
AArch64_Exception_Handler *target_address;
|
||||
switch (exception) {
|
||||
case AARCH64_EXCEPTION_SP0_SYNCHRONOUS:
|
||||
target_address = &aarch64_exception_sp0_synchronous;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_SP0_IRQ:
|
||||
target_address = &aarch64_exception_sp0_irq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_SP0_FIQ:
|
||||
target_address = &aarch64_exception_sp0_fiq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_SP0_SERROR:
|
||||
target_address = &aarch64_exception_sp0_serror;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_SPx_SYNCHRONOUS:
|
||||
target_address = &aarch64_exception_spx_synchronous;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_SPx_IRQ:
|
||||
target_address = &aarch64_exception_spx_irq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_SPx_FIQ:
|
||||
target_address = &aarch64_exception_spx_fiq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_SPx_SERROR:
|
||||
target_address = &aarch64_exception_spx_serror;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL64_SYNCHRONOUS:
|
||||
target_address = &aarch64_exception_lel64_synchronous;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL64_IRQ:
|
||||
target_address = &aarch64_exception_lel64_irq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL64_FIQ:
|
||||
target_address = &aarch64_exception_lel64_fiq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL64_SERROR:
|
||||
target_address = &aarch64_exception_lel64_serror;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL32_SYNCHRONOUS:
|
||||
target_address = &aarch64_exception_lel32_synchronous;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL32_IRQ:
|
||||
target_address = &aarch64_exception_lel32_irq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL32_FIQ:
|
||||
target_address = &aarch64_exception_lel32_fiq;
|
||||
break;
|
||||
case AARCH64_EXCEPTION_LEL32_SERROR:
|
||||
target_address = &aarch64_exception_lel32_serror;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* calculate address of vector to be replaced */
|
||||
char *cvector_address = vbar + VECTOR_ENTRY_SIZE * exception
|
||||
+ VECTOR_POINTER_OFFSET;
|
||||
|
||||
/* get current vector pointer */
|
||||
void (**vector_address)(void) = (void(**)(void))cvector_address;
|
||||
void (*current_vector_pointer)(void);
|
||||
current_vector_pointer = *vector_address;
|
||||
AArch64_Exception_Handler current_vector_pointer = *target_address;
|
||||
|
||||
/* replace vector pointer */
|
||||
*vector_address = handler;
|
||||
*target_address = handler;
|
||||
|
||||
/* return now-previous vector pointer */
|
||||
|
||||
/*
|
||||
* This was put in to fix the following warning:
|
||||
* warning: ISO C forbids conversion of function pointer to object pointer type.
|
||||
*/
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
return (void*)current_vector_pointer;
|
||||
#pragma GCC diagnostic pop
|
||||
return current_vector_pointer;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -37,6 +37,7 @@ source:
|
||||
- cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
|
||||
- cpukit/score/cpu/aarch64/aarch64-exception-interrupt.S
|
||||
- cpukit/score/cpu/aarch64/aarch64-exception-resume.S
|
||||
- cpukit/score/cpu/aarch64/aarch64-exception-targets.c
|
||||
- cpukit/score/cpu/aarch64/aarch64-thread-idle.c
|
||||
- cpukit/score/cpu/aarch64/cpu.c
|
||||
- cpukit/score/cpu/aarch64/cpu_asm.S
|
||||
|
||||
Reference in new issue
Block a user