source: rtems/cpukit/score/cpu/aarch64/cpu.c @ 9aff7e56

Last change on this file since 9aff7e56 was 9aff7e56, checked in by Alex White <alex.white@…>, on 01/11/21 at 16:23:16

score/aarch64: Fix interrupt level reads

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreCPUAArch64
7 *
8 * @brief AArch64 architecture support implementation.
9 */
10
11/*
12 * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
13 * Written by Kinsey Moore <kinsey.moore@oarcorp.com>
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifdef HAVE_CONFIG_H
38#include "config.h"
39#endif
40
41#include <rtems/score/assert.h>
42#include <rtems/score/cpu.h>
43#include <rtems/score/thread.h>
44#include <rtems/score/tls.h>
45
46#ifdef AARCH64_MULTILIB_VFP
47  RTEMS_STATIC_ASSERT(
48    offsetof( Context_Control, register_d8 )
49      == AARCH64_CONTEXT_CONTROL_D8_OFFSET,
50    AARCH64_CONTEXT_CONTROL_D8_OFFSET
51  );
52#endif
53
54  RTEMS_STATIC_ASSERT(
55    offsetof( Context_Control, thread_id )
56      == AARCH64_CONTEXT_CONTROL_THREAD_ID_OFFSET,
57    AARCH64_CONTEXT_CONTROL_THREAD_ID_OFFSET
58  );
59
60  RTEMS_STATIC_ASSERT(
61    offsetof( Context_Control, isr_dispatch_disable )
62      == AARCH64_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE,
63    AARCH64_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE
64  );
65
66#ifdef RTEMS_SMP
67  RTEMS_STATIC_ASSERT(
68    offsetof( Context_Control, is_executing )
69      == AARCH64_CONTEXT_CONTROL_IS_EXECUTING_OFFSET,
70    AARCH64_CONTEXT_CONTROL_IS_EXECUTING_OFFSET
71  );
72#endif
73
74RTEMS_STATIC_ASSERT(
75  sizeof( CPU_Exception_frame ) == AARCH64_EXCEPTION_FRAME_SIZE,
76  AARCH64_EXCEPTION_FRAME_SIZE
77);
78
79RTEMS_STATIC_ASSERT(
80  sizeof( CPU_Exception_frame ) % CPU_STACK_ALIGNMENT == 0,
81  CPU_Exception_frame_alignment
82);
83
84RTEMS_STATIC_ASSERT(
85  offsetof( CPU_Exception_frame, register_sp )
86    == AARCH64_EXCEPTION_FRAME_REGISTER_SP_OFFSET,
87  AARCH64_EXCEPTION_FRAME_REGISTER_SP_OFFSET
88);
89
90RTEMS_STATIC_ASSERT(
91  offsetof( CPU_Exception_frame, register_lr )
92    == AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET,
93  AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET
94);
95
96RTEMS_STATIC_ASSERT(
97  offsetof( CPU_Exception_frame, register_daif )
98    == AARCH64_EXCEPTION_FRAME_REGISTER_DAIF_OFFSET,
99  AARCH64_EXCEPTION_FRAME_REGISTER_DAIF_OFFSET
100);
101
102RTEMS_STATIC_ASSERT(
103  offsetof( CPU_Exception_frame, register_syndrome )
104    == AARCH64_EXCEPTION_FRAME_REGISTER_SYNDROME_OFFSET,
105  AARCH64_EXCEPTION_FRAME_REGISTER_SYNDROME_OFFSET
106);
107
108RTEMS_STATIC_ASSERT(
109  offsetof( CPU_Exception_frame, vector )
110    == AARCH64_EXCEPTION_FRAME_REGISTER_VECTOR_OFFSET,
111  AARCH64_EXCEPTION_FRAME_REGISTER_VECTOR_OFFSET
112);
113
114RTEMS_STATIC_ASSERT(
115  offsetof( CPU_Exception_frame, register_fpsr )
116    == AARCH64_EXCEPTION_FRAME_REGISTER_FPSR_OFFSET,
117  AARCH64_EXCEPTION_FRAME_REGISTER_FPSR_OFFSET
118);
119
120RTEMS_STATIC_ASSERT(
121  offsetof( CPU_Exception_frame, register_q0 )
122    == AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET,
123  AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET
124);
125
126
127void _CPU_Context_Initialize(
128  Context_Control *the_context,
129  void *stack_area_begin,
130  size_t stack_area_size,
131  uint64_t new_level,
132  void (*entry_point)( void ),
133  bool is_fp,
134  void *tls_area
135)
136{
137  (void) new_level;
138
139  the_context->register_sp = (uintptr_t) stack_area_begin + stack_area_size;
140  the_context->register_lr = (uintptr_t) entry_point;
141  the_context->isr_dispatch_disable = 0;
142
143  the_context->thread_id = (uintptr_t) tls_area;
144
145  if ( tls_area != NULL ) {
146    _TLS_TCB_at_area_begin_initialize( tls_area );
147  }
148}
149
150void _CPU_ISR_Set_level( uint64_t level )
151{
152  /* Set the mask bit if interrupts are disabled */
153  level = level ? AARCH64_PSTATE_I : 0;
154  __asm__ volatile (
155    "msr DAIF, %[level]\n"
156    : : [level] "r" (level)
157  );
158}
159
160uint64_t _CPU_ISR_Get_level( void )
161{
162  uint64_t level;
163
164  __asm__ volatile (
165    "mrs %[level], DAIF\n"
166    : [level] "=&r" (level)
167  );
168
169  return ( level & AARCH64_PSTATE_I ) != 0;
170}
171
172void _CPU_ISR_install_vector(
173  uint32_t         vector,
174  CPU_ISR_handler  new_handler,
175  CPU_ISR_handler *old_handler
176)
177{
178  /* Redirection table starts at the end of the vector table */
179  CPU_ISR_handler *table = (CPU_ISR_handler *) (MAX_EXCEPTIONS * 4);
180
181  CPU_ISR_handler current_handler = table [vector];
182
183  /* The current handler is now the old one */
184  if (old_handler != NULL) {
185    *old_handler = current_handler;
186  }
187
188  /* Write only if necessary to avoid writes to a maybe read-only memory */
189  if (current_handler != new_handler) {
190    table [vector] = new_handler;
191  }
192}
193
194void _CPU_Initialize( void )
195{
196  /* Do nothing */
197}
Note: See TracBrowser for help on using the repository browser.