blob: 4ad1285a70bc2f9b4131ea61af2d037d9f258b22 [file] [log] [blame]
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* 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.
*/
/**
* @file dynamic exception handler wrapper
*/
#define _ASMLANGUAGE
#include <toolchain.h>
#include <arch/cpu.h>
_ASM_FILE_PROLOGUE
GDATA(_sw_exc_table)
GTEXT(_exc_wrapper)
SECTION_FUNC(TEXT, _exc_wrapper)
_GDB_STUB_EXC_ENTRY
ldr ip, =_SCS_ICSR
ldr ip, [ip]
ands.w ip, #_SCS_ICSR_RETTOBASE
itte eq /* is the RETTOBASE bit zero ? */
mrseq r0, MSP /* if so, we're not returning to thread mode, thus this
* is a nested exception: the stack frame is on the MSP */
addeq.w r0, #4 /* ESF returned here is off by 4 because of the push {r2}
* in_GDB_STUB_EXC_ENTRY */
mrsne r0, PSP /* if not, we are returning to thread mode, thus this is
* not a nested exception: the stack frame is on the PSP */
/* r0 now contains the pointer to the full ESF */
push {lr} /* lr is now the first item on the stack */
ldr r1, =_sw_exc_table
mrs r2, IPSR /* get exception number */
/* find and call handler: table is 4-bytes wide, shift index by 2 */
ldr r1, [r1, r2, LSL #2]
blx r1
pop {lr}
/* exception return is done in _ExcExit(), including _GDB_STUB_EXC_EXIT */
b _ExcExit
.end