summaryrefslogtreecommitdiff
path: root/nrfdemo/build/tfm/api_ns/platform/include/exception_info.h
blob: 9502008e0b1a9211103b135d9b38d0280bfdcd8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
 * Copyright (c) 2021, Nordic Semiconductor ASA. All rights reserved.
 * Copyright (c) 2023, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef __EXCEPTION_INFO_H__
#define __EXCEPTION_INFO_H__

#include <stdint.h>

#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#define TRUSTZONE_PRESENT
#endif

#if defined(__ARM_ARCH_8_1M_MAIN__) || defined(__ARM_ARCH_8M_MAIN__) \
    || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#define FAULT_STATUS_PRESENT
#endif

/* Exception type number (subtract 16 for IRQn) */
#define EXCEPTION_TYPE_HARDFAULT      3
#define EXCEPTION_TYPE_MEMMANAGEFAULT 4
#define EXCEPTION_TYPE_BUSFAULT       5
#define EXCEPTION_TYPE_USAGEFAULT     6
#define EXCEPTION_TYPE_SECUREFAULT    7

/* Store context for an exception, and print an error message with the context.
 *
 * @param[in]  exception_type  One of the EXCEPTION_TYPE_* values defined above. Any
 *                             other value will result in printing "Unknown".
 */
#ifdef TFM_EXCEPTION_INFO_DUMP

struct exception_info_t {
    uint32_t VECTACTIVE;        /* Active exception number. */
    uint32_t EXC_RETURN;        /* EXC_RETURN value in LR. */
    uint32_t MSP;               /* (Secure) MSP. */
    uint32_t PSP;               /* (Secure) PSP. */
    uint32_t *EXC_FRAME;        /* Exception frame on stack. */
    uint32_t EXC_FRAME_COPY[8]; /* Copy of the basic exception frame. */
    uint32_t CALLEE_SAVED_COPY[8]; /* Copy of the callee saved registers. */
    uint32_t xPSR;              /* Program Status Registers. */

#ifdef FAULT_STATUS_PRESENT
    uint32_t CFSR;              /* Configurable Fault Status Register. */
    uint32_t HFSR;              /* Hard Fault Status Register. */
    uint32_t BFAR;              /* Bus Fault address register. */
    uint32_t BFARVALID;         /* Whether BFAR contains a valid address. */
    uint32_t MMFAR;             /* MemManage Fault address register. */
    uint32_t MMARVALID;         /* Whether MMFAR contains a valid address. */
#ifdef TRUSTZONE_PRESENT
    uint32_t SFSR;              /* SecureFault Status Register. */
    uint32_t SFAR;              /* SecureFault Address Register. */
    uint32_t SFARVALID;         /* Whether SFAR contains a valid address. */
#endif
#endif
};

/**
 * \brief Get a pointer to the current exception_info_t context
 *
 * \return  A pointer to the exception_info_t context or NULL if no context
 *          has been stored
 */
void tfm_exception_info_get_context(struct exception_info_t *ctx);

/* Store context for an exception, then print the info.
 * Call EXCEPTION_INFO() instead of calling this directly.
 */
void store_and_dump_context(uint32_t MSP_in, uint32_t PSP_in, uint32_t LR_in,
                            uint32_t *callee_saved);

/* IAR Specific */
#if defined(__ICCARM__)
#pragma required = store_and_dump_context
#endif

#if defined(__ARM_ARCH_8M_BASE__) || defined(__ARCM_ARCH_V6_M__)
#define EXCEPTION_INFO()                   \
    __ASM volatile(                        \
        "MRS    R0, MSP\n"                 \
        "MRS    R1, PSP\n"                 \
        "MOV    R2, R11\n"                 \
        "MOV    R3, R10\n"                 \
        "PUSH   {R2, R3}\n"                \
        "MOV    R2, R9\n"                  \
        "MOV    R3, R8\n"                  \
        "PUSH   {R2, R3}\n"                \
        "PUSH   {R4-R7}\n"                 \
        "MOV    R3, SP\n"                  \
        "MOV    R2, LR\n"                  \
        "BL     store_and_dump_context\n"  \
        "ADD    SP, #32\n"                 \
    )
#elif defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \
      defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#define EXCEPTION_INFO()                   \
    __ASM volatile(                        \
        "MRS    R0, MSP\n"                 \
        "MRS    R1, PSP\n"                 \
        "PUSH   {R4-R11}\n"                \
        "MOV    R3, SP\n"                  \
        "MOV    R2, LR\n"                  \
        "BL     store_and_dump_context\n"  \
        "ADD    SP, #32\n"                 \
    )
#else
/* Unhandled arch, call store_and_dump_context with callee_saved = NULL */
#define EXCEPTION_INFO()                   \
    __ASM volatile(                        \
        "MRS    R0, MSP\n"                 \
        "MRS    R1, PSP\n"                 \
        "MOV    R2, LR\n"                  \
        "MOV    R3, #0\n"                  \
        "BL     store_and_dump_context\n"  \
    )
#endif

#else /* TFM_EXCEPTION_INFO_DUMP */
#define EXCEPTION_INFO()
#endif /* TFM_EXCEPTION_INFO_DUMP */

#endif /* __EXCEPTION_INFO_H__ */