blob: 00eee3f6c92cd0733ebc4b9e7498b4c3fb89b755 [file] [log] [blame]
/*
* Copyright (c) 2015 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.
*/
#define _ASMLANGUAGE
#include <toolchain.h>
#include <sections.h>
#include <nano_private.h>
#include <arch/x86/asm.h>
#include <offsets.h> /* nanokernel structure offset definitions */
#include <arch/cpu.h> /* _NANO_ERR_SPURIOUS_INT */
GTEXT(_thread_entry_wrapper)
GTEXT(_thread_entry)
GTEXT(_irq_sw_handler)
/*
* @brief Wrapper for _thread_entry
*
* The routine pops parameters for the _thread_entry from stack frame, prepared
* by the _new_thread() routine.
*
* @return N/A
*/
SECTION_FUNC(TEXT, _thread_entry_wrapper)
popl %eax
popl %edx
popl %ecx
jmp _thread_entry
#if CONFIG_IRQ_OFFLOAD
SECTION_FUNC(TEXT, _irq_sw_handler)
pushl %eax
pushl %edx
pushl %ecx
movl $_irq_do_offload, %eax
call _execute_handler
pop %ecx
pop %edx
pop %eax
iret
#endif
#if ALL_DYN_IRQ_STUBS > 0
BRANCH_LABEL(_DynIntStubCommon)
pushl %eax
pushl %ecx
movl $_common_dynamic_irq_handler, %eax
call _execute_handler
/* Clean up and call IRET */
pop %ecx
pop %eax
pop %edx
iret
/* Create all the dynamic IRQ stubs
*
* NOTE: Please update DYN_STUB_SIZE in include/arch/x86/arch.h if you change
* how large the generated stubs are, otherwise _get_dynamic_stub() will
* be unable to correctly determine the offset
*/
/*
* Create nice labels for all the stubs so we can see where we
* are in a debugger
*/
.altmacro
.macro __INT_STUB_NUM id
BRANCH_LABEL(_DynIntStub\id)
.endm
.macro INT_STUB_NUM id
__INT_STUB_NUM %id
.endm
GTEXT(_DynIntStubsBegin)
SECTION_FUNC(TEXT, _DynIntStubsBegin)
stub_num = 0
.rept ((ALL_DYN_IRQ_STUBS + DYN_STUB_PER_BLOCK - 1) / DYN_STUB_PER_BLOCK)
block_counter = 0
.rept DYN_STUB_PER_BLOCK
.if stub_num < ALL_DYN_IRQ_STUBS
INT_STUB_NUM stub_num
pushl %edx
/*
* _common_dynamic_irq_handler() uses this to determine
* which ISR/param to use, see intconnect.c
*/
movl $stub_num, %edx
/*
* Check to make sure this isn't the last stub in
* a block, in which case we just fall through
*/
.if (block_counter <> (DYN_STUB_PER_BLOCK - 1) && \
(stub_num <> ALL_DYN_IRQ_STUBS - 1))
/* This should always be a 2-byte jmp rel8 */
jmp 1f
.endif
stub_num = stub_num + 1
block_counter = block_counter + 1
.endif
.endr
/*
* This must a 5-bvte jump rel32, which is why _DynStubCommon
* is before the actual stubs
*/
1: jmp _DynIntStubCommon
.endr
#endif /* ALL_DYN_IRQ_STUBS */