2015-04-10 16:44:37 -07:00
|
|
|
/*
|
2015-08-20 11:04:01 -04:00
|
|
|
* Copyright (c) 2014-2015 Wind River Systems, Inc.
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* 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
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* 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.
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
2015-12-04 10:09:39 -05:00
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief Wrapper around ISRs with logic for context switching
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Wrapper installed in vector table for handling dynamic interrupts that accept
|
|
|
|
* a parameter.
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#define _ASMLANGUAGE
|
|
|
|
|
|
|
|
#include <offsets.h>
|
|
|
|
#include <toolchain.h>
|
|
|
|
#include <sections.h>
|
|
|
|
#include <sw_isr_table.h>
|
2015-06-19 11:07:02 -04:00
|
|
|
#include <nano_private.h>
|
2015-05-28 10:56:47 -07:00
|
|
|
#include <arch/cpu.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
GTEXT(_isr_enter)
|
|
|
|
GTEXT(_isr_demux)
|
|
|
|
|
arc: Support FIRQ handling when CONFIG_RGF_NUM_BANKS==1
For the EM Starterkit, one SOC I will soon be adding is EM7D.
This SOC has FIRQ, but only has one register bank.
Thus the interrupt handling for FIRQ needs to be different
when CONFIG_RGF_NUM_BANKS==1. The handler must instead push
registers onto the stack in the same stack frame layout that RIRQ uses.
This allows for context switch to be easily done since its compatible.
The common interrupt entry point _isr_enter must save r0 before using
it, because in the FIRQ 1-bank case, it would be destroyed otherwise.
So a global variable named saved_r0 has been added for this reason.
The stack cannot be used to save r0, because it first has to determine
whether its FIRQ or RIRQ here. This change has been tested on the
EM Starterkit with EM7D SOC changes -- coming soon. To make the review
easier, these 3 files are submitted first.
Also, exceptions will no longer use the _firq_stack.
This stack is not needed in the 1-bank case, but an exception stack
is needed. I've added a new stack called _exception_stack,
and made it be 512B, which should be enough for one exception.
See ZEP-966
Change-Id: I6f228b840da7c4db440dd1cfef4ae25336c87f0d
Signed-off-by: Chuck Jordan <cjordan@synopsys.com>
2016-10-15 09:50:27 -07:00
|
|
|
#if CONFIG_RGF_NUM_BANKS == 1
|
|
|
|
GDATA(saved_r0)
|
|
|
|
|
|
|
|
SECTION_VAR(BSS, saved_r0)
|
|
|
|
.word 0
|
|
|
|
#endif
|
|
|
|
|
2016-11-03 13:11:13 -07:00
|
|
|
#if defined(CONFIG_SYS_POWER_MANAGEMENT)
|
2016-10-12 11:09:58 -04:00
|
|
|
GTEXT(_sys_power_save_idle_exit)
|
2015-06-09 16:46:29 -07:00
|
|
|
#endif
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
The symbols in this file are not real functions, and neither are
|
|
|
|
_rirq_enter/_firq_enter: they are jump points.
|
|
|
|
|
|
|
|
The flow is the following:
|
|
|
|
|
|
|
|
ISR -> _isr_enter -- + -> _rirq_enter -> _isr_demux -> ISR -> _rirq_exit
|
|
|
|
|
|
|
|
|
+ -> _firq_enter -> _isr_demux -> ISR -> _firq_exit
|
|
|
|
|
|
|
|
Context switch explanation:
|
|
|
|
|
|
|
|
The context switch code is spread in these files:
|
|
|
|
|
|
|
|
isr_wrapper.s, swap.s, swap_macros.s, fast_irq.s, regular_irq.s
|
|
|
|
|
|
|
|
IRQ stack frame layout:
|
|
|
|
|
|
|
|
high address
|
|
|
|
|
|
|
|
status32
|
|
|
|
pc
|
|
|
|
lp_count
|
|
|
|
lp_start
|
|
|
|
lp_end
|
|
|
|
blink
|
|
|
|
r13
|
|
|
|
...
|
|
|
|
sp -> r0
|
|
|
|
|
|
|
|
low address
|
|
|
|
|
2016-10-07 11:51:41 -07:00
|
|
|
Registers not taken into account in the current implementation.
|
|
|
|
jli_base
|
|
|
|
ldi_base
|
|
|
|
ei_base
|
|
|
|
accl
|
|
|
|
acch
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
The context switch code adopts this standard so that it is easier to follow:
|
|
|
|
|
2015-05-08 17:12:45 -05:00
|
|
|
- r1 contains _nanokernel ASAP and is not overwritten over the lifespan of
|
2015-04-10 16:44:37 -07:00
|
|
|
the functions.
|
2015-05-08 17:12:45 -05:00
|
|
|
- r2 contains _nanokernel.current ASAP, and the incoming thread when we
|
2015-08-20 11:04:01 -04:00
|
|
|
transition from outgoing thread to incoming thread
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-05-08 17:12:45 -05:00
|
|
|
Not loading _nanokernel into r0 allows loading _nanokernel without stomping on
|
2015-04-10 16:44:37 -07:00
|
|
|
the parameter in r0 in _Swap().
|
|
|
|
|
|
|
|
|
2015-08-04 11:27:27 -04:00
|
|
|
ARCv2 processors have two kinds of interrupts: fast (FIRQ) and regular. The
|
|
|
|
official documentation calls the regular interrupts 'IRQs', but the internals
|
|
|
|
of the kernel call them 'RIRQs' to differentiate from the 'irq' subsystem,
|
|
|
|
which is the interrupt API/layer of abstraction.
|
2015-04-10 16:44:37 -07:00
|
|
|
|
arc: Support FIRQ handling when CONFIG_RGF_NUM_BANKS==1
For the EM Starterkit, one SOC I will soon be adding is EM7D.
This SOC has FIRQ, but only has one register bank.
Thus the interrupt handling for FIRQ needs to be different
when CONFIG_RGF_NUM_BANKS==1. The handler must instead push
registers onto the stack in the same stack frame layout that RIRQ uses.
This allows for context switch to be easily done since its compatible.
The common interrupt entry point _isr_enter must save r0 before using
it, because in the FIRQ 1-bank case, it would be destroyed otherwise.
So a global variable named saved_r0 has been added for this reason.
The stack cannot be used to save r0, because it first has to determine
whether its FIRQ or RIRQ here. This change has been tested on the
EM Starterkit with EM7D SOC changes -- coming soon. To make the review
easier, these 3 files are submitted first.
Also, exceptions will no longer use the _firq_stack.
This stack is not needed in the 1-bank case, but an exception stack
is needed. I've added a new stack called _exception_stack,
and made it be 512B, which should be enough for one exception.
See ZEP-966
Change-Id: I6f228b840da7c4db440dd1cfef4ae25336c87f0d
Signed-off-by: Chuck Jordan <cjordan@synopsys.com>
2016-10-15 09:50:27 -07:00
|
|
|
For FIRQ, there are two cases, depending upon the value of
|
|
|
|
CONFIG_RGF_NUM_BANKS.
|
|
|
|
|
|
|
|
CONFIG_RGF_NUM_BANKS==1 case:
|
|
|
|
Scratch registers are pushed onto the current stack just as they are with
|
|
|
|
RIRQ. See the above frame layout. Unlike RIRQ, the status32_p0 and ilink
|
|
|
|
registers are where status32 and the program counter are located, so these
|
|
|
|
need to be pushed.
|
|
|
|
|
|
|
|
CONFIG_RGF_NUM_BANKS!=1 case:
|
|
|
|
The FIRQ handler has its own register bank for general purpose registers,
|
|
|
|
and thus it doesn't have to save them on a stack. The 'loop' registers
|
|
|
|
(lp_count, lp_end, lp_start), however, are not present in the
|
|
|
|
second bank. The handler saves these special registers in unused callee saved
|
|
|
|
registers (to avoid stack accesses). It is possible to register a FIRQ
|
|
|
|
handler that operates outside of the kernel, but care must be taken to only
|
|
|
|
use instructions that only use the banked registers.
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
The kernel is able to handle transitions to and from FIRQ, RIRQ and threads
|
|
|
|
(fibers/task). The contexts are saved 'lazily': the minimum amount of work is
|
|
|
|
done upfront, and the rest is done when needed:
|
|
|
|
|
|
|
|
o RIRQ
|
|
|
|
|
|
|
|
All needed regisers to run C code in the ISR are saved automatically
|
2015-08-20 11:04:01 -04:00
|
|
|
on the outgoing thread's stack: loop, status32, pc, and the caller-
|
2015-04-10 16:44:37 -07:00
|
|
|
saved GPRs. That stack frame layout is pre-determined. If returning
|
|
|
|
to a fiber, the stack is popped and no registers have to be saved by
|
|
|
|
the kernel. If a context switch is required, the callee-saved GPRs
|
2015-08-20 11:04:01 -04:00
|
|
|
are then saved in the thread control structure (TCS).
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
o FIRQ
|
|
|
|
|
|
|
|
First, a FIRQ can be interrupting a lower-priority RIRQ: if this is the case,
|
2015-08-04 11:27:27 -04:00
|
|
|
the FIRQ does not take a scheduling decision and leaves it the RIRQ to
|
|
|
|
handle. This limits the amount of code that has to run at interrupt-level.
|
2015-04-10 16:44:37 -07:00
|
|
|
|
arc: Support FIRQ handling when CONFIG_RGF_NUM_BANKS==1
For the EM Starterkit, one SOC I will soon be adding is EM7D.
This SOC has FIRQ, but only has one register bank.
Thus the interrupt handling for FIRQ needs to be different
when CONFIG_RGF_NUM_BANKS==1. The handler must instead push
registers onto the stack in the same stack frame layout that RIRQ uses.
This allows for context switch to be easily done since its compatible.
The common interrupt entry point _isr_enter must save r0 before using
it, because in the FIRQ 1-bank case, it would be destroyed otherwise.
So a global variable named saved_r0 has been added for this reason.
The stack cannot be used to save r0, because it first has to determine
whether its FIRQ or RIRQ here. This change has been tested on the
EM Starterkit with EM7D SOC changes -- coming soon. To make the review
easier, these 3 files are submitted first.
Also, exceptions will no longer use the _firq_stack.
This stack is not needed in the 1-bank case, but an exception stack
is needed. I've added a new stack called _exception_stack,
and made it be 512B, which should be enough for one exception.
See ZEP-966
Change-Id: I6f228b840da7c4db440dd1cfef4ae25336c87f0d
Signed-off-by: Chuck Jordan <cjordan@synopsys.com>
2016-10-15 09:50:27 -07:00
|
|
|
CONFIG_RGF_NUM_BANKS==1 case:
|
|
|
|
Registers are saved on the stack frame just as they are for RIRQ.
|
|
|
|
Context switch can happen just as it does in the RIRQ case, however,
|
|
|
|
if the FIRQ interrupted a RIRQ, the FIRQ will return from interrupt and
|
|
|
|
let the RIRQ do the context switch. At entry, one register is needed in order
|
|
|
|
to have code to save other registers. r0 is saved first in a global called
|
|
|
|
saved_r0.
|
|
|
|
|
|
|
|
CONFIG_RGF_NUM_BANKS!=1 case:
|
|
|
|
During early initialization, the sp in the 2nd register bank is made to
|
|
|
|
refer to _firq_stack. This allows for the FIRQ handler to use its own stack.
|
|
|
|
GPRs are banked, loop registers are saved in unused callee saved regs upon
|
|
|
|
interrupt entry. If returning to a fiber, loop registers are restored and the
|
2015-04-10 16:44:37 -07:00
|
|
|
CPU switches back to bank 0 for the GPRs. If a context switch is
|
|
|
|
needed, at this point only are all the registers saved. First, a
|
|
|
|
stack frame with the same layout as the automatic RIRQ one is created
|
2015-08-20 11:04:01 -04:00
|
|
|
and then the callee-saved GPRs are saved in the TCS. status32_p0 and
|
2015-04-10 16:44:37 -07:00
|
|
|
ilink are saved in this case, not status32 and pc.
|
|
|
|
To create the stack frame, the FIRQ handling code must first go back to using
|
2015-08-04 11:27:27 -04:00
|
|
|
bank0 of registers, since that is where the registers containing the exiting
|
2015-04-10 16:44:37 -07:00
|
|
|
thread are saved. Care must be taken not to touch any register before saving
|
|
|
|
them: the only one usable at that point is the stack pointer.
|
|
|
|
|
|
|
|
o coop
|
|
|
|
|
|
|
|
When a coop context switch is done, the callee-saved registers are
|
2015-08-20 11:04:01 -04:00
|
|
|
saved in the TCS. The other GPRs do not need to be saved, since the
|
2015-04-10 16:44:37 -07:00
|
|
|
compiler has already placed them on the stack.
|
|
|
|
|
|
|
|
For restoring the contexts, there are six cases. In all cases, the
|
|
|
|
callee-saved registers of the incoming thread have to be restored. Then, there
|
|
|
|
are specifics for each case:
|
|
|
|
|
|
|
|
From coop:
|
|
|
|
|
|
|
|
o to coop
|
|
|
|
|
2015-08-04 11:27:27 -04:00
|
|
|
Restore interrupt lock level and do a normal function call return.
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
o to any irq
|
|
|
|
|
|
|
|
The incoming interrupted thread has an IRQ stack frame containing the
|
|
|
|
caller-saved registers that has to be popped. status32 has to be restored,
|
|
|
|
then we jump to the interrupted instruction.
|
|
|
|
|
|
|
|
From FIRQ:
|
|
|
|
|
arc: Support FIRQ handling when CONFIG_RGF_NUM_BANKS==1
For the EM Starterkit, one SOC I will soon be adding is EM7D.
This SOC has FIRQ, but only has one register bank.
Thus the interrupt handling for FIRQ needs to be different
when CONFIG_RGF_NUM_BANKS==1. The handler must instead push
registers onto the stack in the same stack frame layout that RIRQ uses.
This allows for context switch to be easily done since its compatible.
The common interrupt entry point _isr_enter must save r0 before using
it, because in the FIRQ 1-bank case, it would be destroyed otherwise.
So a global variable named saved_r0 has been added for this reason.
The stack cannot be used to save r0, because it first has to determine
whether its FIRQ or RIRQ here. This change has been tested on the
EM Starterkit with EM7D SOC changes -- coming soon. To make the review
easier, these 3 files are submitted first.
Also, exceptions will no longer use the _firq_stack.
This stack is not needed in the 1-bank case, but an exception stack
is needed. I've added a new stack called _exception_stack,
and made it be 512B, which should be enough for one exception.
See ZEP-966
Change-Id: I6f228b840da7c4db440dd1cfef4ae25336c87f0d
Signed-off-by: Chuck Jordan <cjordan@synopsys.com>
2016-10-15 09:50:27 -07:00
|
|
|
When CONFIG_RGF_NUM_BANKS==1, context switch is done as it is for RIRQ.
|
|
|
|
When CONFIG_RGF_NUM_BANKS!=1, the processor is put back to using bank0,
|
|
|
|
not bank1 anymore, because it had to save the outgoing context from bank0,
|
|
|
|
and now has to load the incoming one
|
2015-04-10 16:44:37 -07:00
|
|
|
into bank0.
|
|
|
|
|
|
|
|
o to coop
|
|
|
|
|
|
|
|
The address of the returning instruction from _Swap() is loaded in ilink and
|
|
|
|
the saved status32 in status32_p0, taking care to adjust the interrupt lock
|
|
|
|
state desired in status32_p0. The return value is put in r0.
|
|
|
|
|
|
|
|
o to any irq
|
|
|
|
|
|
|
|
The IRQ has saved the caller-saved registers in a stack frame, which must be
|
|
|
|
popped, and statu32 and pc loaded in status32_p0 and ilink.
|
|
|
|
|
|
|
|
From RIRQ:
|
|
|
|
|
|
|
|
o to coop
|
|
|
|
|
|
|
|
The interrupt return mechanism in the processor expects a stack frame, but
|
|
|
|
the outgoing context did not create one. A fake one is created here, with
|
|
|
|
only the relevant values filled in: pc, status32 and the return value in r0.
|
|
|
|
|
|
|
|
There is a discrepancy between the ABI from the ARCv2 docs, including the
|
|
|
|
way the processor pushes GPRs in pairs in the IRQ stack frame, and the ABI
|
|
|
|
GCC uses. r13 should be a callee-saved register, but GCC treats it as
|
|
|
|
caller-saved. This means that the processor pushes it in the stack frame
|
|
|
|
along with r12, but the compiler does not save it before entering a
|
|
|
|
function. So, it is saved as part of the callee-saved registers, and
|
2015-08-04 11:27:27 -04:00
|
|
|
restored there, but the processor restores it _a second time_ when popping
|
2015-04-10 16:44:37 -07:00
|
|
|
the IRQ stack frame. Thus, the correct value must also be put in the fake
|
|
|
|
stack frame when returning to a thread that context switched out
|
|
|
|
cooperatively.
|
|
|
|
|
|
|
|
o to any irq
|
|
|
|
|
|
|
|
Both types of IRQs already have an IRQ stack frame: simply return from
|
|
|
|
interrupt.
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
SECTION_FUNC(TEXT, _isr_enter)
|
arc: Support FIRQ handling when CONFIG_RGF_NUM_BANKS==1
For the EM Starterkit, one SOC I will soon be adding is EM7D.
This SOC has FIRQ, but only has one register bank.
Thus the interrupt handling for FIRQ needs to be different
when CONFIG_RGF_NUM_BANKS==1. The handler must instead push
registers onto the stack in the same stack frame layout that RIRQ uses.
This allows for context switch to be easily done since its compatible.
The common interrupt entry point _isr_enter must save r0 before using
it, because in the FIRQ 1-bank case, it would be destroyed otherwise.
So a global variable named saved_r0 has been added for this reason.
The stack cannot be used to save r0, because it first has to determine
whether its FIRQ or RIRQ here. This change has been tested on the
EM Starterkit with EM7D SOC changes -- coming soon. To make the review
easier, these 3 files are submitted first.
Also, exceptions will no longer use the _firq_stack.
This stack is not needed in the 1-bank case, but an exception stack
is needed. I've added a new stack called _exception_stack,
and made it be 512B, which should be enough for one exception.
See ZEP-966
Change-Id: I6f228b840da7c4db440dd1cfef4ae25336c87f0d
Signed-off-by: Chuck Jordan <cjordan@synopsys.com>
2016-10-15 09:50:27 -07:00
|
|
|
#if CONFIG_RGF_NUM_BANKS == 1
|
|
|
|
st r0,[saved_r0]
|
|
|
|
#endif
|
2015-04-10 16:44:37 -07:00
|
|
|
lr r0, [_ARC_V2_AUX_IRQ_ACT]
|
|
|
|
ffs r0, r0
|
|
|
|
cmp r0, 0
|
arc: Support FIRQ handling when CONFIG_RGF_NUM_BANKS==1
For the EM Starterkit, one SOC I will soon be adding is EM7D.
This SOC has FIRQ, but only has one register bank.
Thus the interrupt handling for FIRQ needs to be different
when CONFIG_RGF_NUM_BANKS==1. The handler must instead push
registers onto the stack in the same stack frame layout that RIRQ uses.
This allows for context switch to be easily done since its compatible.
The common interrupt entry point _isr_enter must save r0 before using
it, because in the FIRQ 1-bank case, it would be destroyed otherwise.
So a global variable named saved_r0 has been added for this reason.
The stack cannot be used to save r0, because it first has to determine
whether its FIRQ or RIRQ here. This change has been tested on the
EM Starterkit with EM7D SOC changes -- coming soon. To make the review
easier, these 3 files are submitted first.
Also, exceptions will no longer use the _firq_stack.
This stack is not needed in the 1-bank case, but an exception stack
is needed. I've added a new stack called _exception_stack,
and made it be 512B, which should be enough for one exception.
See ZEP-966
Change-Id: I6f228b840da7c4db440dd1cfef4ae25336c87f0d
Signed-off-by: Chuck Jordan <cjordan@synopsys.com>
2016-10-15 09:50:27 -07:00
|
|
|
#if CONFIG_RGF_NUM_BANKS == 1
|
|
|
|
bnz rirq_path
|
|
|
|
/* 1-register bank FIRQ handling must save registers on stack */
|
|
|
|
lr r0,[_ARC_V2_STATUS32_P0]
|
|
|
|
push_s r0
|
|
|
|
mov r0,ilink
|
|
|
|
push_s r0
|
|
|
|
mov r0,lp_count
|
|
|
|
push_s r0
|
|
|
|
lr r0, [_ARC_V2_LP_START]
|
|
|
|
push_s r0
|
|
|
|
lr r0, [_ARC_V2_LP_END]
|
|
|
|
push_s r0
|
|
|
|
push_s blink
|
|
|
|
push_s r13
|
|
|
|
push_s r12
|
|
|
|
push r11
|
|
|
|
push r10
|
|
|
|
push r9
|
|
|
|
push r8
|
|
|
|
push r7
|
|
|
|
push r6
|
|
|
|
push r5
|
|
|
|
push r4
|
|
|
|
push_s r3
|
|
|
|
push_s r2
|
|
|
|
push_s r1
|
|
|
|
ld r0,[saved_r0]
|
|
|
|
push_s r0
|
|
|
|
mov r3, _firq_exit
|
|
|
|
mov r2, _firq_enter
|
|
|
|
j_s [r2]
|
|
|
|
rirq_path:
|
|
|
|
mov r3, _rirq_exit
|
|
|
|
mov r2, _rirq_enter
|
|
|
|
j_s [r2]
|
|
|
|
#else
|
2015-04-10 16:44:37 -07:00
|
|
|
mov.z r3, _firq_exit
|
|
|
|
mov.z r2, _firq_enter
|
|
|
|
mov.nz r3, _rirq_exit
|
|
|
|
mov.nz r2, _rirq_enter
|
2016-05-25 09:24:55 -07:00
|
|
|
j_s [r2]
|
arc: Support FIRQ handling when CONFIG_RGF_NUM_BANKS==1
For the EM Starterkit, one SOC I will soon be adding is EM7D.
This SOC has FIRQ, but only has one register bank.
Thus the interrupt handling for FIRQ needs to be different
when CONFIG_RGF_NUM_BANKS==1. The handler must instead push
registers onto the stack in the same stack frame layout that RIRQ uses.
This allows for context switch to be easily done since its compatible.
The common interrupt entry point _isr_enter must save r0 before using
it, because in the FIRQ 1-bank case, it would be destroyed otherwise.
So a global variable named saved_r0 has been added for this reason.
The stack cannot be used to save r0, because it first has to determine
whether its FIRQ or RIRQ here. This change has been tested on the
EM Starterkit with EM7D SOC changes -- coming soon. To make the review
easier, these 3 files are submitted first.
Also, exceptions will no longer use the _firq_stack.
This stack is not needed in the 1-bank case, but an exception stack
is needed. I've added a new stack called _exception_stack,
and made it be 512B, which should be enough for one exception.
See ZEP-966
Change-Id: I6f228b840da7c4db440dd1cfef4ae25336c87f0d
Signed-off-by: Chuck Jordan <cjordan@synopsys.com>
2016-10-15 09:50:27 -07:00
|
|
|
#endif
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2016-05-04 11:55:33 -05:00
|
|
|
#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP
|
|
|
|
GTEXT(_sys_k_event_logger_exit_sleep)
|
|
|
|
|
|
|
|
.macro log_sleep_k_event
|
|
|
|
clri r0 /* do not interrupt event logger operations */
|
|
|
|
push_s r0
|
|
|
|
push_s blink
|
|
|
|
jl _sys_k_event_logger_exit_sleep
|
|
|
|
pop_s blink
|
|
|
|
pop_s r0
|
|
|
|
seti r0
|
|
|
|
.endm
|
|
|
|
#else
|
|
|
|
#define log_sleep_k_event
|
|
|
|
#endif
|
2016-04-13 16:38:38 -05:00
|
|
|
#if defined(CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT)
|
|
|
|
GTEXT(_sys_k_event_logger_interrupt)
|
|
|
|
|
|
|
|
.macro log_interrupt_k_event
|
|
|
|
clri r0 /* do not interrupt event logger operations */
|
|
|
|
push_s r0
|
|
|
|
push_s blink
|
|
|
|
jl _sys_k_event_logger_interrupt
|
|
|
|
pop_s blink
|
|
|
|
pop_s r0
|
|
|
|
seti r0
|
|
|
|
.endm
|
|
|
|
#else
|
|
|
|
#define log_interrupt_k_event
|
|
|
|
#endif
|
|
|
|
|
2016-11-03 13:11:13 -07:00
|
|
|
#if defined(CONFIG_SYS_POWER_MANAGEMENT)
|
2016-10-12 11:09:58 -04:00
|
|
|
.macro exit_tickless_idle
|
|
|
|
clri r0 /* do not interrupt exiting tickless idle operations */
|
|
|
|
push_s r1
|
|
|
|
push_s r0
|
|
|
|
mov_s r1, _nanokernel
|
|
|
|
ld_s r0, [r1, __tNANO_idle_OFFSET] /* requested idle duration */
|
|
|
|
breq r0, 0, _skip_sys_power_save_idle_exit
|
|
|
|
|
|
|
|
st 0, [r1, __tNANO_idle_OFFSET] /* zero idle duration */
|
|
|
|
push_s blink
|
|
|
|
jl _sys_power_save_idle_exit
|
|
|
|
pop_s blink
|
|
|
|
|
|
|
|
_skip_sys_power_save_idle_exit:
|
|
|
|
pop_s r0
|
|
|
|
pop_s r1
|
|
|
|
seti r0
|
|
|
|
.endm
|
2015-06-09 16:46:29 -07:00
|
|
|
#else
|
|
|
|
#define exit_tickless_idle
|
|
|
|
#endif
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
/* when getting here, r3 contains the interrupt exit stub to call */
|
|
|
|
SECTION_FUNC(TEXT, _isr_demux)
|
|
|
|
push_s r3
|
2015-06-09 16:46:29 -07:00
|
|
|
|
|
|
|
/* cannot be done before this point because we must be able to run C */
|
|
|
|
/* r0 is available to be stomped here, and exit_tickless_idle uses it */
|
|
|
|
exit_tickless_idle
|
2016-04-13 16:38:38 -05:00
|
|
|
log_interrupt_k_event
|
2016-05-04 11:55:33 -05:00
|
|
|
log_sleep_k_event
|
2015-06-09 16:46:29 -07:00
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
lr r0, [_ARC_V2_ICAUSE]
|
|
|
|
sub r0, r0, 16
|
|
|
|
|
2015-05-08 17:12:46 -05:00
|
|
|
mov r1, _sw_isr_table
|
2015-04-10 16:44:37 -07:00
|
|
|
add3 r0, r1, r0 /* table entries are 8-bytes wide */
|
|
|
|
|
2016-05-06 11:40:16 -07:00
|
|
|
ld_s r1, [r0, 4] /* ISR into r1 */
|
2015-04-10 16:44:37 -07:00
|
|
|
jl_s.d [r1]
|
|
|
|
ld_s r0, [r0] /* delay slot: ISR parameter into r0 */
|
|
|
|
|
|
|
|
/* back from ISR, jump to exit stub */
|
|
|
|
pop_s r3
|
2016-05-25 09:24:55 -07:00
|
|
|
j_s [r3]
|
2015-04-10 16:44:37 -07:00
|
|
|
nop
|