arc: fix management of IRQ priority levels

A previous re-work of IRQ priorities was led astray by an incorrect
comment. Priority level 1 is not a non-maskable interrupt priority.
In addition, zero latency IRQs are not implemented on ARC.

Timer driver now doesn't specify IRQ_ZERO_LATENCY (as that wouldn't be
correct) and its IRQ priority is now tunable in Kconfig. The default is 0.

IPM driver on both ARC and x86 side were being configured with hard-coded
priority of 2, which wasn't valid for ARC and caused an assertion failure.
The priority level is now tunable with Kconfig and defaults to 1 for ARC.

Issue: ZEP-693
Change-Id: If76dbfee214be7630d787be0bce4549a1ecbcb5b
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2016-08-16 10:58:40 -07:00
parent d6fb8d3611
commit 533c2ee30d
10 changed files with 58 additions and 42 deletions

View file

@ -78,35 +78,23 @@ void _arch_irq_disable(unsigned int irq)
*
* @brief Set an interrupt's priority
*
* Valid values are from 0 to 13. Lower values take priority over higher
* values. Special case priorities are expressed via mutually exclusive
* flags.
* Lower values take priority over higher values. Special case priorities are
* expressed via mutually exclusive flags.
* The priority is verified if ASSERT_ON is enabled.
* The priority is verified if ASSERT_ON is enabled; max priority level
* depends on CONFIG_NUM_IRQ_PRIO_LEVELS.
*
* @return N/A
*/
void _irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
{
ARG_UNUSED(flags);
int key = irq_lock();
/* HW priorties 0 and 1 are special case selected by flags.
* 2 and above are 'regular' IRQs.
* Since the IRQ_CONNECT() API specifies that all priority values
* have the same semantics and 'special' priorities are set via
* flags, add 2 to the supplied value if flags are not in play.
*/
if (flags & IRQ_ZERO_LATENCY) {
prio = 0;
} else if (flags & IRQ_NON_MASKABLE) {
prio = 1;
} else {
prio += 2;
}
__ASSERT(prio >= 0 && prio < CONFIG_NUM_IRQ_PRIO_LEVELS,
"invalid priority!");
__ASSERT(prio < CONFIG_NUM_IRQ_PRIO_LEVELS,
"invalid priority %d for irq %d", prio, irq);
_arc_v2_irq_unit_prio_set(irq, prio);
irq_unlock(key);
}

View file

@ -0,0 +1,28 @@
#
# 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.
#
if ARC && SOC_QUARK_SE_SS
if IPM
config QUARK_SE_SS_IPM_IRQ_PRI
int "IPM interrupt priority"
default 1
help
Priority level for interrupts coming in from the inter-processor
mailboxes.
endif # IPM
endif # SOC_QUARK_SE_SS

View file

@ -24,7 +24,7 @@
static int arc_quark_se_ipm_init(void)
{
IRQ_CONNECT(QUARK_SE_IPM_INTERRUPT, QUARK_SE_IPM_INTERRUPT_PRI,
IRQ_CONNECT(QUARK_SE_IPM_INTERRUPT, CONFIG_QUARK_SE_SS_IPM_IRQ_PRI,
quark_se_ipm_isr, NULL, 0);
irq_enable(QUARK_SE_IPM_INTERRUPT);
return 0;

View file

@ -67,6 +67,14 @@ config ARC_GDB_ENABLE
the ARC slave processor. This will allow GDB to halt and
engage the ARC processor to proceed step by step execution.
if IPM
config QUARK_SE_IPM_IRQ_PRI
int "IPM interrupt priority"
default 2
help
Priority level for interrupts coming in from the inter-processor
mailboxes.
if IPM_CONSOLE_RECEIVER
config QUARK_SE_IPM_CONSOLE_RING_BUF_SIZE32
int "IPM Console Ring Buffer Size"
@ -75,5 +83,6 @@ config QUARK_SE_IPM_CONSOLE_RING_BUF_SIZE32
Size of the buffer for the console reciever, for incoming
console messages from the ARC side. Must be a power of 2.
endif
endif
endif #SOC_QUARK_SE_X86

View file

@ -29,7 +29,7 @@
static int x86_quark_se_ipm_init(void)
{
IRQ_CONNECT(QUARK_SE_IPM_INTERRUPT, QUARK_SE_IPM_INTERRUPT_PRI,
IRQ_CONNECT(QUARK_SE_IPM_INTERRUPT, CONFIG_QUARK_SE_IPM_IRQ_PRI,
quark_se_ipm_isr, NULL, 0);
irq_enable(QUARK_SE_IPM_INTERRUPT);
return 0;

View file

@ -103,12 +103,6 @@ struct __packed quark_se_ipm {
#define QUARK_SE_IPM(channel) ((volatile struct quark_se_ipm *)(QUARK_SE_IPM_BASE + \
((channel) * sizeof(struct quark_se_ipm))))
/* XXX I pulled this number out of thin air -- how to choose
* the right priority?
*/
#define QUARK_SE_IPM_INTERRUPT_PRI 2
struct quark_se_ipm_controller_config_info {
int (*controller_init)(void);
};

View file

@ -133,6 +133,14 @@ config ARCV2_TIMER
This module implements a kernel device driver for the ARCv2 processor timer 0
and provides the standard "system clock driver" interfaces.
config ARCV2_TIMER_IRQ_PRIORITY
int "ARC timer interrupt priority"
default 0
depends on ARCV2_TIMER
help
This option specifies the IRQ priority used by the ARC timer. Lower
values have higher priority.
config CORTEX_M_SYSTICK
bool "Cortex-M SYSTICK timer"
default y

View file

@ -338,7 +338,8 @@ int _sys_clock_driver_init(struct device *device)
cycles_per_tick = sys_clock_hw_cycles_per_tick;
IRQ_CONNECT(IRQ_TIMER0, 0, _timer_int_handler, NULL, IRQ_ZERO_LATENCY);
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
_timer_int_handler, NULL, 0);
/*
* Set the reload value to achieve the configured tick rate, enable the

View file

@ -82,20 +82,11 @@ extern void _irq_priority_set(unsigned int irq, unsigned int prio,
* 3. The priority level for the interrupt is configured by a call to
* _irq_priority_set()
*
* Supported flags:
*
* IRQ_ZERO_LATENCY - Aka 'firqs'. Cannot make kernel calls due to
* insufficent context being saved. priority_p argument
* ignored.
* IRQ_NON_MASKABLE - These high-priority interrupts are not maked when
* interrupts are locked system-wide. priority_p
* argument ignored.
*
* @param irq_p IRQ line number
* @param priority_p Interrupt priority, in range 0-13
* @param isr_p Interrupt service routine
* @param isr_param_p ISR parameter
* @param flags_p IRQ options
* @param flags_p IRQ options (ignored for now)
*
* @return The vector assigned to this interrupt
*/

View file

@ -33,9 +33,6 @@
extern "C" {
#endif
#define IRQ_ZERO_LATENCY BIT(0)
#define IRQ_NON_MASKABLE BIT(1)
#ifdef _ASMLANGUAGE
GTEXT(_irq_exit);
GTEXT(_arch_irq_connect)