1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "riscv/rvruntime-frames.h"
16 #include "esp_private/panic_internal.h"
17 
18 #define MCAUSE_ILLEGAL_INSTRUCTION  2
19 
20 extern void esp_panic_handler(panic_info_t *info);
21 volatile bool g_override_illegal_instruction = false;
22 
23 void __real_esp_panic_handler(panic_info_t *info);
24 
25 void return_from_panic_handler(RvExcFrame *frm) __attribute__((noreturn));
26 
27 /* Memprot test specific IllegalInstruction exception handler:
28  * when testing the protection against a code execution, sample code
29  * is being injected into various memory regions which produces
30  * Illegal instruction on execution attempt. Such a result is expected
31  * but it causes system reboot in the standard panic handler.
32  * The following variant of panic handling simply returns back to the
33  * next instruction and continues normal execution.
34  *
35  * NOTE: if Illegal instruction comes from a different source than the testing code
36  * the behavior is undefined
37  * */
__wrap_esp_panic_handler(panic_info_t * info)38 void __wrap_esp_panic_handler(panic_info_t *info)
39 {
40     RvExcFrame *frm = (RvExcFrame *)info->frame;
41     if ( frm->mcause == MCAUSE_ILLEGAL_INSTRUCTION && g_override_illegal_instruction == true ) {
42         /* Return from exception to the return address that called the faulting function.
43         */
44         frm->mepc = frm->ra;
45 
46         /* Restore the CPU state and return from the exception.
47         */
48         return_from_panic_handler(frm);
49     } else {
50         __real_esp_panic_handler(info);
51     }
52 }
53