1 /* 2 * Copyright (c) 2016 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_ARCH_X86_INCLUDE_IA32_EXCEPTION_H_ 8 #define ZEPHYR_ARCH_X86_INCLUDE_IA32_EXCEPTION_H_ 9 10 #ifndef _ASMLANGUAGE 11 12 #include <toolchain/common.h> 13 14 #define _EXCEPTION_INTLIST(vector, dpl) \ 15 ".pushsection .gnu.linkonce.intList.exc_" #vector "\n\t" \ 16 ".long 1f\n\t" /* ISR_LIST.fnc */ \ 17 ".long -1\n\t" /* ISR_LIST.irq */ \ 18 ".long -1\n\t" /* ISR_LIST.priority */ \ 19 ".long " STRINGIFY(vector) "\n\t" /* ISR_LIST.vec */ \ 20 ".long " STRINGIFY(dpl) "\n\t" /* ISR_LIST.dpl */ \ 21 ".long 0\n\t" /* ISR_LIST.tss */ \ 22 ".popsection\n\t" \ 23 24 /* Extra preprocessor indirection to ensure arguments get expanded before 25 * concatenation takes place 26 */ 27 #define __EXCEPTION_STUB_NAME(handler, vec) \ 28 _ ## handler ## _vector_ ## vec ## _stub 29 30 #define _EXCEPTION_STUB_NAME(handler, vec) \ 31 __EXCEPTION_STUB_NAME(handler, vec) \ 32 33 /* Unfortunately, GCC extended asm doesn't work at toplevel so we need 34 * to stringify stuff. 35 * 36 * What we are doing here is generating entires in the .intList section 37 * and also the assembly language stubs for the exception. We use 38 * .gnu.linkonce section prefix so that the linker only includes the 39 * first one of these it encounters for a particular vector. In this 40 * way it's easy for applications or drivers to install custom exception 41 * handlers without having to #ifdef out previous instances such as in 42 * arch/x86/core/fatal.c 43 */ 44 #define __EXCEPTION_CONNECT(handler, vector, dpl, codepush) \ 45 __asm__ ( \ 46 _EXCEPTION_INTLIST(vector, dpl) \ 47 ".pushsection .gnu.linkonce.t.exc_" STRINGIFY(vector) \ 48 "_stub, \"ax\"\n\t" \ 49 ".global " STRINGIFY(_EXCEPTION_STUB_NAME(handler, vector)) "\n\t" \ 50 STRINGIFY(_EXCEPTION_STUB_NAME(handler, vector)) ":\n\t" \ 51 "1:\n\t" \ 52 codepush \ 53 "push $" STRINGIFY(handler) "\n\t" \ 54 "jmp _exception_enter\n\t" \ 55 ".popsection\n\t" \ 56 ) 57 58 59 /** 60 * @brief Connect an exception handler that doesn't expect error code 61 * 62 * Assign an exception handler to a particular vector in the IDT. 63 * 64 * @param handler A handler function of the prototype 65 * void handler(const z_arch_esf_t *esf) 66 * @param vector Vector index in the IDT 67 */ 68 #define _EXCEPTION_CONNECT_NOCODE(handler, vector, dpl) \ 69 __EXCEPTION_CONNECT(handler, vector, dpl, "push $0\n\t") 70 71 /** 72 * @brief Connect an exception handler that does expect error code 73 * 74 * Assign an exception handler to a particular vector in the IDT. 75 * The error code will be accessible in esf->errorCode 76 * 77 * @param handler A handler function of the prototype 78 * void handler(const z_arch_esf_t *esf) 79 * @param vector Vector index in the IDT 80 */ 81 #define _EXCEPTION_CONNECT_CODE(handler, vector, dpl) \ 82 __EXCEPTION_CONNECT(handler, vector, dpl, "") 83 84 #endif /* _ASMLANGUAGE */ 85 86 #endif /* ZEPHYR_ARCH_X86_INCLUDE_IA32_EXCEPTION_H_ */ 87