Skip to content

Commit 40cd8cc

Browse files
polarvidRbb666
authored andcommitted
feat: Added rt_interrupt_context* family for nested interrupt handling
These changes introduce the rt_interrupt_context family, providing a mechanism for managing nested interrupts. The context management ensures proper storage and retrieval of interrupt states, improving reliability in nested interrupt scenarios by enabling context tracking across different interrupt levels. This enhancement is essential for platforms where nested interrupt handling is crucial, such as in real- time or multi-threaded applications. Changes: - Defined rt_interrupt_context structure with context and node fields in `rtdef.h` to support nested interrupts. - Added rt_slist_pop function in `rtservice.h` for simplified node removal in singly linked lists. - Declared rt_interrupt_context_push, rt_interrupt_context_pop, and rt_interrupt_context_get functions in `rtthread.h` to manage the interrupt/exception stack. - Modified AArch64 CPU support in `cpuport.h` to include rt_hw_show_register for debugging registers. - Refactored `_rt_hw_trap_irq` in `trap.c` for context-aware IRQ handling, with stack push/pop logic to handle nested contexts. - Implemented interrupt context push, pop, and retrieval logic in `irq.c` to manage context at the CPU level. Signed-off-by: Shell <[email protected]>
1 parent 3a696eb commit 40cd8cc

File tree

7 files changed

+76
-2
lines changed

7 files changed

+76
-2
lines changed

include/rtdef.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,9 @@ struct rt_cpu
723723
#ifdef RT_USING_CPU_USAGE_TRACER
724724
struct rt_cpu_usage_stats cpu_stat;
725725
#endif /* RT_USING_CPU_USAGE_TRACER */
726+
#ifdef ARCH_USING_IRQ_CTX_LIST
727+
rt_slist_t irq_ctx_head;
728+
#endif /* ARCH_USING_IRQ_CTX_LIST */
726729
};
727730

728731
#else /* !RT_USING_SMP */
@@ -734,6 +737,9 @@ struct rt_cpu
734737
#ifdef RT_USING_CPU_USAGE_TRACER
735738
struct rt_cpu_usage_stats cpu_stat;
736739
#endif /* RT_USING_CPU_USAGE_TRACER */
740+
#ifdef ARCH_USING_IRQ_CTX_LIST
741+
rt_slist_t irq_ctx_head;
742+
#endif /* ARCH_USING_IRQ_CTX_LIST */
737743
};
738744

739745
#endif /* RT_USING_SMP */
@@ -744,6 +750,16 @@ typedef struct rt_cpu *rt_cpu_t;
744750

745751
struct rt_thread;
746752

753+
/**
754+
* interrupt/exception frame handling
755+
*
756+
*/
757+
758+
typedef struct rt_interrupt_context {
759+
void *context; /**< arch specific context */
760+
rt_slist_t node; /**< node for nested interrupt */
761+
} *rt_interrupt_context_t;
762+
747763
#ifdef RT_USING_SMART
748764
typedef rt_err_t (*rt_wakeup_func_t)(void *object, struct rt_thread *thread);
749765

include/rtservice.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* 2012-03-22 Bernard rename kservice.h to rtservice.h
1212
* 2017-11-15 JasonJia Modify rt_slist_foreach to rt_slist_for_each_entry.
1313
* Make code cleanup.
14+
* 2024-01-03 Shell add rt_slist_pop()
1415
*/
1516

1617
#ifndef __RT_SERVICE_H__
@@ -224,6 +225,20 @@ rt_inline unsigned int rt_slist_len(const rt_slist_t *l)
224225
return len;
225226
}
226227

228+
rt_inline rt_slist_t *rt_slist_pop(rt_slist_t *l)
229+
{
230+
struct rt_slist_node *node = l;
231+
232+
/* remove node */
233+
node = node->next;
234+
if (node != (rt_slist_t *)0)
235+
{
236+
((struct rt_slist_node *)l)->next = node->next;
237+
}
238+
239+
return node;
240+
}
241+
227242
rt_inline rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n)
228243
{
229244
/* remove slist head */

include/rtthread.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,10 @@ rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg);
713713
void rt_interrupt_enter(void);
714714
void rt_interrupt_leave(void);
715715

716+
void rt_interrupt_context_push(rt_interrupt_context_t this_ctx);
717+
void rt_interrupt_context_pop(void);
718+
void *rt_interrupt_context_get(void);
719+
716720
/**
717721
* CPU object
718722
*/

libcpu/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ config ARCH_ARMV8
219219
select ARCH_ARM
220220
select ARCH_ARM_MMU
221221
select RT_USING_CPU_FFS
222+
select ARCH_USING_IRQ_CTX_LIST
222223

223224
config ARCH_MIPS
224225
bool
@@ -325,3 +326,7 @@ config ARCH_CPU_STACK_GROWS_UPWARD
325326
config ARCH_USING_HW_THREAD_SELF
326327
bool
327328
default n
329+
330+
config ARCH_USING_IRQ_CTX_LIST
331+
bool
332+
default n

libcpu/aarch64/common/include/armv8.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ struct rt_hw_exp_stack
145145
rt_uint128_t fpu[32];
146146
};
147147

148+
void rt_hw_show_register(struct rt_hw_exp_stack *regs);
149+
148150
#define SP_ELx ((unsigned long)0x01)
149151
#define SP_EL0 ((unsigned long)0x00)
150152
#define PSTATE_EL1 ((unsigned long)0x04)

libcpu/aarch64/common/trap.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs)
167167
}
168168

169169
#ifndef RT_USING_PIC
170-
void rt_hw_trap_irq(void)
170+
static void _rt_hw_trap_irq(rt_interrupt_context_t irq_context)
171171
{
172172
#ifdef SOC_BCM283x
173173
extern rt_uint8_t core_timer_flag;
@@ -269,12 +269,24 @@ void rt_hw_trap_irq(void)
269269
#endif
270270
}
271271
#else
272-
void rt_hw_trap_irq(void)
272+
static void _rt_hw_trap_irq(struct rt_interrupt_context *this_ctx)
273273
{
274274
rt_pic_do_traps();
275275
}
276276
#endif
277277

278+
void rt_hw_trap_irq(struct rt_hw_exp_stack *regs)
279+
{
280+
struct rt_interrupt_context this_ctx = {
281+
.context = regs,
282+
.node = RT_SLIST_OBJECT_INIT(this_ctx.node),
283+
};
284+
285+
rt_interrupt_context_push(&this_ctx);
286+
_rt_hw_trap_irq(&this_ctx);
287+
rt_interrupt_context_pop();
288+
}
289+
278290
#ifdef RT_USING_SMART
279291
#define DBG_CHECK_EVENT(regs, esr) dbg_check_event(regs, esr)
280292
#else

src/irq.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* 2022-07-04 Yunjie fix RT_DEBUG_LOG
1515
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
1616
* 2024-01-05 Shell Fixup of data racing in rt_interrupt_get_nest
17+
* 2024-01-03 Shell Support for interrupt context
1718
*/
1819

1920
#include <rthw.h>
@@ -69,6 +70,25 @@ void rt_interrupt_leave_sethook(void (*hook)(void))
6970
volatile rt_atomic_t rt_interrupt_nest = 0;
7071
#endif /* RT_USING_SMP */
7172

73+
#ifdef ARCH_USING_IRQ_CTX_LIST
74+
void rt_interrupt_context_push(rt_interrupt_context_t this_ctx)
75+
{
76+
struct rt_cpu *this_cpu = rt_cpu_self();
77+
rt_slist_insert(&this_cpu->irq_ctx_head, &this_ctx->node);
78+
}
79+
80+
void rt_interrupt_context_pop(void)
81+
{
82+
struct rt_cpu *this_cpu = rt_cpu_self();
83+
rt_slist_pop(&this_cpu->irq_ctx_head);
84+
}
85+
86+
void *rt_interrupt_context_get(void)
87+
{
88+
struct rt_cpu *this_cpu = rt_cpu_self();
89+
return rt_slist_first_entry(&this_cpu->irq_ctx_head, struct rt_interrupt_context, node)->context;
90+
}
91+
#endif /* ARCH_USING_IRQ_CTX_LIST */
7292

7393
/**
7494
* @brief This function will be invoked by BSP, when enter interrupt service routine

0 commit comments

Comments
 (0)