blob: 4099bbd93a8a4b16642664abb5913dbc3918db82 [file] [log] [blame]
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef X86_EXCEPTION_H
#define X86_EXCEPTION_H
#ifndef _ASMLANGUAGE
/* Unfortunately, GCC extended asm doesn't work at toplevel so we need
* to stringify stuff.
*
* What we are doing here is generating entires in the .intList section
* and also the assembly language stubs for the exception. We use
* .gnu.linkonce section prefix so that the linker only includes the
* first one of these it encounters for a particular vector. In this
* way it's easy for applications or drivers to install custom exception
* handlers without having to #ifdef out previous instances such as in
* arch/x86/core/fatal.c
*/
#define _EXCEPTION_MACRO(handler, vector, enter_func) \
__asm__ ( \
".pushsection .gnu.linkonce.intList.exc_" #vector "\n\t" \
".long 1f\n\t" /* ISR_LIST.fnc */ \
".long -1\n\t" /* ISR_LIST.irq */ \
".long -1\n\t" /* ISR_LIST.priority */ \
".long " #vector "\n\t" /* ISR_LIST.vec */ \
".long 0\n\t" /* ISR_LIST.dpl */ \
".popsection\n\t" \
".pushsection .gnu.linkonce.t.exc_" #vector "_stub, \"ax\"\n\t" \
".global " #handler "Stub\n\t" \
#handler "Stub:\n\t" \
"1:\n\t" \
"call " #enter_func "\n\t" \
"call " #handler "\n\t" \
"jmp _ExcExit\n\t" \
".popsection\n\t" \
)
/**
* @brief Connect an exception handler that doesn't expect error code
*
* Assign an exception handler to a particular vector in the IDT.
*
* @param handler A handler function of the prototype
* void handler(const NANO_ESF *esf)
* @param vector Vector index in the IDT
*/
#define _EXCEPTION_CONNECT_NOCODE(handler, vector) \
_EXCEPTION_MACRO(handler, vector, _ExcEntNoErr)
/**
* @brief Connect an exception handler that does expect error code
*
* Assign an exception handler to a particular vector in the IDT.
* The error code will be accessible in esf->errorCode
*
* @param handler A handler function of the prototype
* void handler(const NANO_ESF *esf)
* @param vector Vector index in the IDT
*/
#define _EXCEPTION_CONNECT_CODE(handler, vector) \
_EXCEPTION_MACRO(handler, vector, _ExcEnt)
#endif /* _ASMLANGUAGE */
#endif /* X86_EXCEPTION_H */