1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "hardware/platform_defs.h"
8#include "hardware/irq.h"
9
10#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
11.syntax unified
12.cpu cortex-m0plus
13.thumb
14
15.data
16.align 2
17
18.global irq_handler_chain_slots
19
20.global irq_handler_chain_first_slot
21.global irq_handler_chain_remove_tail
22
23//
24// These Slots make up the code and structure of the handler chains; the only external information are the VTABLE entries
25// (obviously one set per core) and a free list head. Each individual handler chain starts with the VTABLE entry I
26// pointing at the address of slot S (with thumb bit set). Thus each slot which is part of a chain is executble.
27//
28// The execution jumps (via branch instruction) from one slot to the other, then jumps to the end of chain handler.
29// The entirety of the state needed to traverse the chain is contained within the slots of the chain, which is why
30// a VTABLE entry is all that is needed per chain (rather than requiring a separarte set of head pointers)
31//
32
33irq_handler_chain_slots:
34.set next_slot_number, 1
35.rept PICO_MAX_SHARED_IRQ_HANDLERS
36    // a slot is executable and is always 3 instructions long.
37    .hword 0    // inst1 (either: ldr r0, [pc, #4]    or for the FIRST slot : add r1, pc, #0                 )
38    .hword 0    // inst2 (        blx r0                                      b irq_handler_chain_first_slot )
39
40    .hword 0    // inst3 (either: b next_slot         or for the LAST         pop {pc}                       )
41
42    // next is a single byte index of next slot in chain (or -1 to end)
43.if next_slot_number == PICO_MAX_SHARED_IRQ_HANDLERS
44    .byte 0xff
45.else
46    .byte next_slot_number
47.endif
48    // next is the 8 bit unsigned priority
49    .byte 0x00
501:
51    // and finally the handler function pointer
52    .word 0x00000000
53    .set next_slot_number, next_slot_number + 1
54.endr
55
56irq_handler_chain_first_slot:
57    push {lr}
58    ldr  r0, [r1, #4]
59    adds r1, #1
60    mov  lr, r1
61    bx   r0
62irq_handler_chain_remove_tail:
63    mov  r0, lr
64    subs r0, #9
65    ldr  r1, =irq_add_tail_to_free_list
66    blx  r1
67    pop  {pc}
68
69
70#endif
71