source: rtems/cpukit/score/cpu/arm/armv7m-exception-default.c @ 68e1ccc4

5
Last change on this file since 68e1ccc4 was f52885b, checked in by Martin Galvan <martin.galvan@…>, on 09/18/15 at 21:53:31

ARMv7M: Improve exception handler routine and add comments on SP selection

This patch adds a brief description of how context state is saved into the
SP on exception entry, and makes a few changes to _ARMV7M_Exception_default
in order to make it a bit more efficient. I also removed the unused 'v7mfsz'
input parameter.

This should apply over Sudarshan's patch.

  • Property mode set to 100644
File size: 3.0 KB
Line 
1/*
2 * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/score/armv7m.h>
20
21#ifdef ARM_MULTILIB_ARCH_V7M
22
23void __attribute__((naked)) _ARMV7M_Exception_default( void )
24{
25    /* On exception entry, ARMv7M saves context state onto a stack pointed to
26     * by either MSP or PSP. The value stored in LR indicates whether we were
27     * in Thread or Handler mode, whether we were using the FPU (if any),
28     * and which stack pointer we were using.
29     * In particular, bit 2 of LR will be 0 if we were using MSP.
30     *
31     * For a more detailed explanation, see the Exception Entry Behavior
32     * section of the ARMv7M Architecture Reference Manual.
33     */
34
35    /* As we're in Handler mode here, we'll always operate on MSP.
36     * However, we need to store the right SP in our CPU_Exception_frame.
37     */
38  __asm__ volatile (
39    "sub sp, %[cpufsz]\n"   /* Allocate space for a CPU_Exception_frame. */
40    "stm sp, {r0-r12}\n"
41    "tst lr, #4\n"          /* Check if bit 2 of LR is zero. If so, PSR.Z = 1 */
42    "itte eq\n"             /* IF bit 2 of LR is zero... (PSR.Z == 1) */
43    "mrseq r0, msp\n"       /* THEN we were using MSP. */
44    "addeq r0, %[cpufsz]\n" /* THEN, set r0 = old MSP value. */
45    "mrsne r0, psp\n"       /* ELSE it's not zero; we were using PSP. */
46    "add r2, r0, %[v7mlroff]\n"
47    "add r1, sp, %[cpulroff]\n"
48    "ldm r2, {r3-r5}\n"     /* Grab LR, PC and PSR from the stack.. */
49    "stm r1, {r3-r5}\n"     /* ..and store them in our CPU_Exception_frame. */
50    "mrs r1, ipsr\n"
51    "str r1, [sp, %[cpuvecoff]]\n"
52
53    /* Argument for high level handler */
54    "mov r0, sp\n"
55
56    /* Clear VFP context pointer */
57    "add r3, sp, %[cpuvfpoff]\n"
58    "mov r1, #0\n"
59    "str r1, [r3]\n"
60
61#ifdef ARM_MULTILIB_VFP
62    /* Ensure that the FPU is enabled */
63    "ldr r4, =%[cpacr]\n"
64    "tst r4, #(0xf << 20)\n"
65    "bne 1f\n"
66
67    /* Save VFP context */
68    "sub sp, %[vfpsz]\n"
69    "add r4, sp, #4\n"
70    "bic r4, r4, #7\n"
71    "str r4, [r3]\n"
72    "vmrs r2, FPSCR\n"
73    "stmia r4!, {r1-r2}\n"
74    "vstmia r4!, {d0-d15}\n"
75    "mov r1, #0\n"
76    "mov r2, #0\n"
77    "adds r3, r4, #128\n"
78    "2:\n"
79    "stmia r4!, {r1-r2}\n"
80    "cmp r4, r3\n"
81    "bne 2b\n"
82    "1:\n"
83#endif
84
85    "b _ARM_Exception_default\n"
86    :
87    : [cpufsz] "i" (sizeof(CPU_Exception_frame)),
88      [cpulroff] "i" (offsetof(CPU_Exception_frame, register_lr)),
89      [v7mlroff] "i" (offsetof(ARMV7M_Exception_frame, register_lr)),
90      [cpuvecoff] "J" (offsetof(CPU_Exception_frame, vector)),
91      [cpuvfpoff] "i" (ARM_EXCEPTION_FRAME_VFP_CONTEXT_OFFSET),
92      [cpacr] "i" (ARMV7M_CPACR),
93      [vfpsz] "i" (ARM_VFP_CONTEXT_SIZE)
94  );
95}
96
97#endif /* ARM_MULTILIB_ARCH_V7M */
Note: See TracBrowser for help on using the repository browser.