source: rtems/cpukit/score/cpu/aarch64/aarch64-exception-default.c @ 080dc5d

Last change on this file since 080dc5d was 080dc5d, checked in by Kinsey Moore <kinsey.moore@…>, on 10/25/22 at 17:41:27

cpukit/aarch64: Emulate FPSR for FENV traps

The AArch64 TRM specifies that when FPCR is set to trap floating point
exceptions, the FPSR exception bits are not set. This ensures that FPSR
is updated as FENV expects even if floating point exception traps are
enabled.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreCPUAArch64
7 *
8 * @brief Implementation of _AArch64_Exception_default
9 *
10 * This file implements _AArch64_Exception_default for use as part of the
11 * default exception handling code which dumps all system registers.
12 */
13
14/*
15 * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
16 * Written by Kinsey Moore <kinsey.moore@oarcorp.com>
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#ifdef HAVE_CONFIG_H
41#include "config.h"
42#endif
43
44#include <rtems/fatal.h>
45#include <rtems/score/aarch64-system-registers.h>
46#include <rtems/score/cpu.h>
47#include <rtems/score/percpu.h>
48
49void _AArch64_Exception_default( CPU_Exception_frame *frame )
50{
51  uint64_t EC = AARCH64_ESR_EL1_EC_GET( frame->register_syndrome );
52
53  /* Emulate FPSR flags for FENV if a FPU exception occurred */
54  if ( EC == 0x2c ) {
55    /*
56     * This must be done because FENV depends on FPSR values, but trapped FPU
57     * exceptions don't set FPSR bits. In the case where a signal is mapped, the
58     * signal code executes after the exception frame is restored and FENV
59     * functions executed in that context will need this information to be
60     * accurate.
61     */
62    uint64_t ISS = AARCH64_ESR_EL1_EC_GET( frame->register_syndrome );
63
64    /* If the exception bits are valid, use them */
65    if ( ( ISS & ( 1 << 23 ) ) != 0 ) {
66      /* The bits of the lower byte match the FPSR exception bits */
67      frame->register_fpsr |= ( ISS & 0xff );
68    }
69  }
70
71  rtems_fatal( RTEMS_FATAL_SOURCE_EXCEPTION, (rtems_fatal_code) frame );
72}
73
74void _CPU_Exception_disable_thread_dispatch( void )
75{
76  Per_CPU_Control *cpu_self = _Per_CPU_Get();
77
78  /* Increment interrupt nest and thread dispatch disable level */
79  ++cpu_self->thread_dispatch_disable_level;
80  ++cpu_self->isr_nest_level;
81}
82
83void _AArch64_Exception_frame_copy(
84  CPU_Exception_frame *new_ef,
85  CPU_Exception_frame *old_ef
86)
87{
88  *new_ef = *old_ef;
89}
90
91int _CPU_Exception_frame_get_signal( CPU_Exception_frame *ef )
92{
93  uint64_t EC = AARCH64_ESR_EL1_EC_GET( ef->register_syndrome );
94
95  switch ( EC ) {
96    case 0x1:  /* WFI */
97    case 0x7:  /* SVE/SIMD/FP */
98    case 0xa:  /* LD64B/ST64B* */
99    case 0x18: /* MSR/MRS/system instruction */
100    case 0x19: /* SVE */
101    case 0x15: /* Supervisor call */
102    case 0x26: /* SP Alignment */
103    case 0x31: /* Breakpoint */
104    case 0x33: /* Step */
105    case 0x35: /* Watchpoint */
106    case 0x3c: /* Break Instruction */
107      return -1;
108    case 0x2c: /* FPU */
109      return SIGFPE;
110    case 0x21: /* Instruction Abort */
111    case 0x25: /* Data Abort */
112      return SIGSEGV;
113    default:
114      return SIGILL;
115  }
116}
117
118void _CPU_Exception_frame_set_resume( CPU_Exception_frame *ef, void *address )
119{
120  ef->register_pc = address;
121}
122
123#define AARCH64_INSTRUCTION_SIZE 4
124void  _CPU_Exception_frame_make_resume_next_instruction( CPU_Exception_frame *ef )
125{
126  ef->register_pc += AARCH64_INSTRUCTION_SIZE;
127}
Note: See TracBrowser for help on using the repository browser.