Skip to content

Commit 62c2431

Browse files
authored
Merge pull request #12824 from kjbracey-arm/faultasm
Optimise fault handler assembly
2 parents aafae5d + b6a7a08 commit 62c2431

File tree

8 files changed

+341
-412
lines changed

8 files changed

+341
-412
lines changed

TESTS/mbed_platform/crash_reporting/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static mbed_error_ctx saved_error_ctx = {0};
3636
void mbed_error_reboot_callback(mbed_error_ctx *error_context)
3737
{
3838

39-
TEST_ASSERT_EQUAL_UINT((uint32_t)error_context, ERROR_CONTEXT_LOCATION);
39+
TEST_ASSERT_EQUAL_PTR(error_context, &MBED_CRASH_DATA);
4040
memcpy(&saved_error_ctx, error_context, sizeof(mbed_error_ctx));
4141
mbed_reset_reboot_error_info();
4242

platform/source/TARGET_CORTEX_M/mbed_fault_handler.h renamed to platform/internal/mbed_fault_handler.h

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@
1818
#ifndef MBED_FAULT_HANDLER_H
1919
#define MBED_FAULT_HANDLER_H
2020

21+
#include "mbed_toolchain.h"
22+
#include "mbed_error.h"
23+
2124
#ifdef __cplusplus
2225
extern "C" {
2326
#endif
2427

2528
//Fault context struct
29+
#ifdef TARGET_CORTEX_M
2630
//WARNING: DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES in except.S files.
2731
//Offset of these registers are used by fault handler in except.S
2832
typedef struct {
@@ -48,24 +52,55 @@ typedef struct {
4852
uint32_t EXC_RETURN;
4953
uint32_t CONTROL;
5054
} mbed_fault_context_t;
55+
#elif defined TARGET_CORTEX_A
56+
// This is not currently used, but would be a plausible implementation
57+
typedef struct {
58+
uint32_t R0_reg;
59+
uint32_t R1_reg;
60+
uint32_t R2_reg;
61+
uint32_t R3_reg;
62+
uint32_t R4_reg;
63+
uint32_t R5_reg;
64+
uint32_t R6_reg;
65+
uint32_t R7_reg;
66+
uint32_t R8_reg;
67+
uint32_t R9_reg;
68+
uint32_t R10_reg;
69+
uint32_t R11_reg;
70+
uint32_t R12_reg;
71+
uint32_t SP_reg;
72+
uint32_t LR_reg;
73+
uint32_t PC_reg;
74+
uint32_t CPSR;
75+
uint32_t SP_usr;
76+
uint32_t LR_usr;
77+
} mbed_fault_context_t;
78+
#else
79+
// Dummy for mbed_crash_data_t
80+
typedef struct {
81+
} mbed_fault_context_t;
82+
#endif
83+
5184

5285
//Fault type definitions
86+
#ifdef TARGET_CORTEX_M
5387
//WARNING: DO NOT CHANGE THESE VALUES WITHOUT MAKING CORRESPONDING CHANGES in except.S files.
5488
#define HARD_FAULT_EXCEPTION (0x10) //Keep some gap between values for any future insertion/expansion
5589
#define MEMMANAGE_FAULT_EXCEPTION (0x20)
5690
#define BUS_FAULT_EXCEPTION (0x30)
5791
#define USAGE_FAULT_EXCEPTION (0x40)
92+
#endif
5893

5994
//This is a handler function called from Fault handler to print the error information out.
6095
//This runs in fault context and uses special functions(defined in mbed_fault_handler.c) to print the information without using C-lib support.
61-
void mbed_fault_handler(uint32_t fault_type, const mbed_fault_context_t *mbed_fault_context_in);
96+
MBED_NORETURN void mbed_fault_handler(uint32_t fault_type, const mbed_fault_context_t *mbed_fault_context_in);
6297

6398
/**
6499
* Call this function to retrieve the fault context after a fatal exception which triggered a system reboot. The function retrieves the fault context stored in crash-report ram area which is preserved over reboot.
65100
* @param fault_context Pointer to mbed_fault_context_t struct allocated by the caller. This is the mbed_fault_context_t info captured as part of the fatal exception which triggered the reboot.
66101
* @return 0 or MBED_SUCCESS on success.
67102
* MBED_ERROR_INVALID_ARGUMENT in case of invalid error_info pointer
68-
* MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by teh system
103+
* MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system
69104
*
70105
*/
71106
mbed_error_status_t mbed_get_reboot_fault_context(mbed_fault_context_t *fault_context);

platform/source/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S

Lines changed: 82 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -22,141 +22,103 @@
2222
; * -----------------------------------------------------------------------------
2323
; */
2424
#ifndef MBED_FAULT_HANDLER_DISABLED
25-
25+
2626
#ifndef DOMAIN_NS
2727
#define DOMAIN_NS 1
2828
#endif
29-
30-
FAULT_TYPE_HARD_FAULT EQU 0x10
31-
FAULT_TYPE_MEMMANAGE_FAULT EQU 0x20
32-
FAULT_TYPE_BUS_FAULT EQU 0x30
33-
FAULT_TYPE_USAGE_FAULT EQU 0x40
3429

35-
PRESERVE8
36-
THUMB
30+
FAULT_TYPE_HARD_FAULT EQU 0x10
31+
FAULT_TYPE_MEMMANAGE_FAULT EQU 0x20
32+
FAULT_TYPE_BUS_FAULT EQU 0x30
33+
FAULT_TYPE_USAGE_FAULT EQU 0x40
34+
35+
PRESERVE8
36+
THUMB
3737

38-
AREA |.text|, CODE, READONLY
38+
AREA |.text|, CODE, READONLY
3939

4040
HardFault_Handler\
41-
PROC
42-
EXPORT HardFault_Handler
43-
LDR R3,=FAULT_TYPE_HARD_FAULT
44-
B Fault_Handler
45-
ENDP
41+
PROC
42+
EXPORT HardFault_Handler
43+
MOVS R3,#FAULT_TYPE_HARD_FAULT
44+
B Fault_Handler
45+
ENDP
4646

4747
MemManage_Handler\
48-
PROC
49-
EXPORT MemManage_Handler
50-
LDR R3,=FAULT_TYPE_MEMMANAGE_FAULT
51-
B Fault_Handler
52-
ENDP
53-
48+
PROC
49+
EXPORT MemManage_Handler
50+
MOVS R3,#FAULT_TYPE_MEMMANAGE_FAULT
51+
B Fault_Handler
52+
ENDP
53+
5454
BusFault_Handler\
55-
PROC
56-
EXPORT BusFault_Handler
57-
LDR R3,=FAULT_TYPE_BUS_FAULT
58-
B Fault_Handler
59-
ENDP
55+
PROC
56+
EXPORT BusFault_Handler
57+
MOVS R3,#FAULT_TYPE_BUS_FAULT
58+
B Fault_Handler
59+
ENDP
6060

6161
UsageFault_Handler\
62-
PROC
63-
EXPORT UsageFault_Handler
64-
LDR R3,=FAULT_TYPE_USAGE_FAULT
65-
B Fault_Handler
66-
ENDP
67-
68-
Fault_Handler PROC
69-
EXPORT Fault_Handler
62+
PROC
63+
EXPORT UsageFault_Handler
64+
MOVS R3,#FAULT_TYPE_USAGE_FAULT
65+
; Fall into Fault_Handler
66+
ENDP
67+
68+
Fault_Handler\
69+
PROC
70+
EXPORT Fault_Handler
7071
#if (DOMAIN_NS == 1)
71-
IMPORT mbed_fault_handler
72-
IMPORT mbed_fault_context
73-
74-
MRS R0,MSP
75-
LDR R1,=0x4
76-
MOV R2,LR
77-
TST R2,R1 ; Check EXC_RETURN for bit 2
78-
BEQ Fault_Handler_Continue
79-
MRS R0,PSP
72+
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
73+
#define mbed_fault_context |Image$$RW_m_crash_data$$ZI$$Base|
74+
#endif
75+
IMPORT mbed_fault_context
76+
IMPORT mbed_fault_handler
77+
78+
MOV R12,R3
79+
PUSH {R4-R7}
80+
ADD R6,SP,#16
81+
MOV R5,LR
82+
LSRS R0,R5,#3 ; Check EXC_RETURN for bit 2
83+
BCC Fault_Handler_Continue
84+
MRS R6,PSP
8085

8186
Fault_Handler_Continue
82-
MOV R12,R3
83-
LDR R3,=mbed_fault_context
84-
LDR R1,[R3]
85-
LDR R2,[R0] ; Capture R0
86-
STR R2,[R1]
87-
ADDS R1,#4
88-
LDR R2,[R0,#4] ; Capture R1
89-
STR R2,[R1]
90-
ADDS R1,#4
91-
LDR R2,[R0,#8] ; Capture R2
92-
STR R2,[R1]
93-
ADDS R1,#4
94-
LDR R2,[R0,#12] ; Capture R3
95-
STR R2,[R1]
96-
ADDS R1,#4
97-
STMIA R1!,{R4-R7} ; Capture R4..R7
98-
MOV R7,R8 ; Capture R8
99-
STR R7,[R1]
100-
ADDS R1,#4
101-
MOV R7,R9 ; Capture R9
102-
STR R7,[R1]
103-
ADDS R1,#4
104-
MOV R7,R10 ; Capture R10
105-
STR R7,[R1]
106-
ADDS R1,#4
107-
MOV R7,R11 ; Capture R11
108-
STR R7,[R1]
109-
ADDS R1,#4
110-
LDR R2,[R0,#16] ; Capture R12
111-
STR R2,[R1]
112-
ADDS R1,#8 ; Add 8 here to capture LR next, we will capture SP later
113-
LDR R2,[R0,#20] ; Capture LR
114-
STR R2,[R1]
115-
ADDS R1,#4
116-
LDR R2,[R0,#24] ; Capture PC
117-
STR R2,[R1]
118-
ADDS R1,#4
119-
LDR R2,[R0,#28] ; Capture xPSR
120-
STR R2,[R1]
121-
ADDS R1,#4
122-
; Adjust stack pointer to its original value and capture it
123-
MOV R3,R0
124-
ADDS R3,#0x20 ; Add 0x20 to get the SP value prior to exception
125-
LDR R6,=0x200
126-
TST R2,R6 ; Check for if STK was aligned by checking bit-9 in xPSR value
127-
BEQ Fault_Handler_Continue1
128-
ADDS R3,#0x4
87+
LDR R7,=mbed_fault_context
88+
LDMIA R6!,{R0-R3}
89+
STMIA R7!,{R0-R3} ; Capture R0..R3
90+
POP {R0-R3}
91+
STMIA R7!,{R0-R3} ; Capture R4..R7
92+
MOV R0,R8
93+
MOV R1,R9
94+
MOV R2,R10
95+
MOV R3,R11
96+
STMIA R7!,{R0-R3} ; Capture R8..R11
97+
LDMIA R6!,{R0,R2-R4} ; Load R12,LR,PC,xPSR
98+
; Adjust stack pointer to its original value
99+
MOVS R1,R6
100+
LSRS R6,R4,#10 ; Check for if STK was aligned by checking bit-9 in xPSR value
101+
BCC Fault_Handler_Continue1
102+
ADDS R1,#0x4
129103

130104
Fault_Handler_Continue1
131-
MOV R5,LR
132-
LDR R6,=0x10 ; Check for bit-4 to see if FP context was saved
133-
TST R5,R6
134-
BNE Fault_Handler_Continue2
135-
ADDS R3,#0x48 ; 16 FP regs + FPCSR + 1 Reserved
136-
137-
Fault_Handler_Continue2
138-
MOV R4,R1
139-
SUBS R4,#0x10 ; Set the location of SP in ctx
140-
STR R3,[R4] ; Capture the adjusted SP
141-
MRS R2,PSP ; Get PSP
142-
STR R2,[R1]
143-
ADDS R1,#4
144-
MRS R2,MSP ; Get MSP
145-
STR R2,[R1]
146-
ADDS R1,#4
147-
MOV R2,LR ; Get current LR(EXC_RETURN)
148-
STR R2,[R1]
149-
ADDS R1,#4
150-
MRS R2,CONTROL ; Get CONTROL Reg
151-
STR R2,[R1]
152-
MOV R0,R12
153-
LDR R3,=mbed_fault_context
154-
LDR R1,[R3]
155-
BL mbed_fault_handler
156-
#endif
157-
B . ; Just in case we come back here
158-
ENDP
159-
105+
LSRS R6,R5,#5 ; Check EXC_RETURN bit-4 to see if FP context was saved
106+
BCS Fault_Handler_Continue2
107+
ADDS R1,#0x48 ; 16 FP regs + FPCSR + 1 Reserved
108+
Fault_Handler_Continue2
109+
STMIA R7!,{R0-R4} ; Capture R12,SP,LR,PC,xPSR
110+
MRS R0,PSP
111+
MOV R1,SP
112+
MRS R6,CONTROL
113+
STMIA R7!,{R0,R1,R5,R6} ; Capture PSP,MSP,EXC_RETURN,CONTROL
114+
MOV R0,R12
115+
LDR R1,=mbed_fault_context
116+
BL mbed_fault_handler ; mbed_fault_handler does not return
117+
#else
118+
B .
160119
#endif
161-
162-
END
120+
ENDP
121+
ALIGN
122+
#endif
123+
124+
END

0 commit comments

Comments
 (0)