Skip to content

Commit 7ffe979

Browse files
committed
Reworked this all slightly:
* There was a pre-existing (undocumented) variable PICO_NO_STORED_VECTOR_TABLE that did something similar (have replaced that with the new var) * Renamed PICO_MINIMAL_VECTOR_TABLE to PICO_MINIMAL_STORED_VECTOR_TABLE to contrast PICO_NO_RAM_VECTOR_TABLE * Explicitly mentioned that PICO_MINIMAL_STORED_VECTOR_TABLE has no effect on RISC-V atm * Added a new documented variable PICO_NUM_VTABLE_IRQs to indicate how many IRQs the user would like to store in the vtable (either stored or RAM) - this is the limit of what any IRQ api can touch, or indeed what isr_irqN you can override. This is a better alternative to changing PICO_RAM_VECTOR_TABLE_SIZE (which wasn't documented), but did allow you (unsafely) to limit the RAM vector table size (but not the stored size) TLDR: 1. if you set PICO_MINIMAL_STORED_VECTOR_TABLE=1, you get a 4 word VTABLE on Arm.. you still get a RAM vector table with up to PICO_NUM_VTABLE_IRQs (defaults to NUM_IRQs) but everything - including things like `isr_pendsv` point to `__unhandled_user_irq`. 2. PICO_NUM_VTABLE_IRQs (default NUM_IRQS) sets the number of IRQs that have handlers in the VTABLE (this affects the space reserved, and what the irq APIs let you touch - at least as far as invalid_params_if!) 3. If you set PICO_MINIMAL_STORED_VECTOR_TABLE=1 for a no flash binary, then PICO_NUM_VTABLE_IRQs is forced to 0 as there is no reserved space for the handlers.
1 parent 1412f8a commit 7ffe979

File tree

9 files changed

+90
-151
lines changed

9 files changed

+90
-151
lines changed

src/host/hardware_irq/include/hardware/irq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ extern "C" {
128128
typedef void (*irq_handler_t)(void);
129129

130130
static inline void check_irq_param(__unused uint num) {
131-
invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS);
131+
invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS);
132132
}
133133

134134
/*! \brief Set specified interrupt's priority

src/host/hardware_irq/irq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void PICO_WEAK_FUNCTION_IMPL_NAME(irq_init_priorities)() {
9696
}
9797

9898
static uint get_user_irq_claim_index(uint irq_num) {
99-
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS);
99+
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS);
100100
// we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31
101101
static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today.
102102
return NUM_IRQS - irq_num - 1u;

src/rp2040/pico_platform/include/pico/platform.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@
6666
#define PICO_RP2040_B2_SUPPORTED 1
6767
#endif
6868

69-
#ifndef PICO_RAM_VECTOR_TABLE_SIZE
70-
#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS)
71-
#endif
72-
7369
// PICO_CONFIG: PICO_CLKDIV_ROUND_NEAREST, True if floating point clock divisors should be rounded to the nearest possible clock divisor by default rather than rounding down, type=bool, default=1, group=pico_platform
7470
#ifndef PICO_CLKDIV_ROUND_NEAREST
7571
#define PICO_CLKDIV_ROUND_NEAREST 1

src/rp2350/pico_platform/include/pico/platform.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@
5454
#define PICO_NO_RAM_VECTOR_TABLE 0
5555
#endif
5656

57-
#ifndef PICO_RAM_VECTOR_TABLE_SIZE
58-
#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS)
59-
#endif
60-
6157
// PICO_CONFIG: PICO_USE_STACK_GUARDS, Enable/disable stack guards, type=bool, default=0, advanced=true, group=pico_platform
6258
#ifndef PICO_USE_STACK_GUARDS
6359
#define PICO_USE_STACK_GUARDS 0

src/rp2_common/hardware_irq/include/hardware/irq.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@
2323
#define PICO_VTABLE_PER_CORE 0
2424
#endif
2525

26+
// note this is defined here as it simplifies dependencies
27+
// PICO_CONFIG: PICO_MINIMAL_STORED_VECTOR_TABLE, Only store a very minimal vector table in the binary on Arm, type=bool, default=0, advanced=true, group=pico_crt0
28+
#ifndef PICO_MINIMAL_STORED_VECTOR_TABLE
29+
#define PICO_MINIMAL_STORED_VECTOR_TABLE 0
30+
#endif
31+
32+
#if PICO_MINIMAL_STORED_VECTOR_TABLE && (PICO_NO_FLASH && !defined(__riscv))
33+
#if PICO_NUM_VTABLE_IRQS
34+
#warning PICO_NUM_VTABLE_IRQS is specied with PICO_MINIMAL_STORED_VECTOR_TABLE for NO_FLASH Arm binary; ignored
35+
#undef PICO_NUM_VTABLE_IRQS
36+
#endif
37+
#define PICO_NUM_VTABLE_IRQS 0
38+
#else
39+
// PICO_CONFIG: PICO_NUM_VTABLE_IRQS, Number of IRQ handlers in the vector table - can be lowered to save space if you aren't using some higher IRQs, type=int, default=NUM_IRQS, group=hardware_irq
40+
#ifndef PICO_NUM_VTABLE_IRQS
41+
#define PICO_NUM_VTABLE_IRQS NUM_IRQS
42+
#endif
43+
#endif
44+
2645
#ifndef __ASSEMBLER__
2746

2847
#include "pico.h"
@@ -195,7 +214,7 @@ extern "C" {
195214
typedef void (*irq_handler_t)(void);
196215

197216
static inline void check_irq_param(__unused uint num) {
198-
invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS);
217+
invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS);
199218
}
200219

201220
/*! \brief Set specified interrupt's priority

src/rp2_common/hardware_irq/irq.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ bool irq_is_enabled(uint num) {
7676
}
7777

7878
static inline void irq_set_mask_n_enabled_internal(uint n, uint32_t mask, bool enabled) {
79-
invalid_params_if(HARDWARE_IRQ, n * 32u >= ((NUM_IRQS + 31u) & ~31u));
79+
invalid_params_if(HARDWARE_IRQ, n * 32u >= ((PICO_NUM_VTABLE_IRQS + 31u) & ~31u));
8080
#if defined(__riscv)
8181
if (enabled) {
8282
hazard3_irqarray_clear(RVCSR_MEIFA_OFFSET, 2 * n, mask & 0xffffu);
@@ -658,15 +658,15 @@ __weak void runtime_init_per_core_irq_priorities(void) {
658658
*p++ = prio4;
659659
}
660660
#else
661-
for (uint i = 0; i < NUM_IRQS; ++i) {
661+
for (uint i = 0; i < PICO_NUM_VTABLE_IRQS; ++i) {
662662
irq_set_priority(i, PICO_DEFAULT_IRQ_PRIORITY);
663663
}
664664
#endif
665665
#endif
666666
}
667667

668668
static uint get_user_irq_claim_index(uint irq_num) {
669-
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS);
669+
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS);
670670
// we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31
671671
static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today.
672672
return NUM_IRQS - irq_num - 1u;

src/rp2_common/pico_crt0/crt0.S

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "hardware/regs/addressmap.h"
1313
#include "hardware/regs/sio.h"
14+
#include "hardware/irq.h"
1415
#include "pico/binary_info/defs.h"
1516
#include "boot/picobin.h"
1617
#include "pico/bootrom.h"
@@ -23,26 +24,22 @@
2324

2425
pico_default_asm_setup
2526

27+
#ifdef PICO_NO_STORED_VECTOR_TABLE
28+
#warning PICO_NO_STORED_VECTOR_TABLE is no longer used. PICO_MINIMAL_STORED_VECTOR_TABLE is not identical but usually serves the same purpose
29+
#endif
30+
2631
.section .vectors, "ax"
2732
.align 2
2833

29-
// PICO_CONFIG: PICO_MINIMAL_VECTOR_TABLE, Use Minimal Vector Table - this prevents use of all interrupts, type=bool, default=0, advanced=true, group=pico_crt0
30-
#ifndef PICO_MINIMAL_VECTOR_TABLE
31-
#define PICO_MINIMAL_VECTOR_TABLE 0
32-
#endif
33-
34-
.global __vectors, __VECTOR_TABLE
34+
.global __vectors, __VECTOR_TABLE, __vectors_end
3535
__VECTOR_TABLE:
3636
__vectors:
3737
.word __StackTop
3838
.word _reset_handler
3939

40-
#if PICO_MINIMAL_VECTOR_TABLE
4140
.word isr_invalid // NMI
4241
.word isr_invalid // HardFault
43-
#else
44-
.word isr_nmi
45-
.word isr_hardfault
42+
#if !PICO_MINIMAL_STORED_VECTOR_TABLE
4643
.word isr_invalid // Reserved, should never fire
4744
.word isr_invalid // Reserved, should never fire
4845
.word isr_invalid // Reserved, should never fire
@@ -55,15 +52,9 @@ __vectors:
5552
.word isr_invalid // Reserved, should never fire
5653
.word isr_pendsv
5754
.word isr_systick
58-
#if PICO_NO_STORED_VECTOR_TABLE && !PICO_NO_FLASH // note in no flash binary, we only have the single RAM vector table anyway
59-
#if PICO_NO_RAM_VECTOR_TABLE
60-
#error Can't specify PICO_NO_STORED_VECTOR_TABLE and PICO_NO_RAM_VECTOR_TABLE
61-
#endif
62-
// we don't include any IRQ vectors; we will initialize them during runtime_init in the RAM vector table
63-
#else
6455

6556
.macro if_irq_word num func
66-
.if \num < NUM_IRQS
57+
.if \num < PICO_NUM_VTABLE_IRQS
6758
.word \func
6859
.endif
6960
.endm
@@ -152,11 +143,11 @@ if_irq_word 76 isr_irq76
152143
if_irq_word 77 isr_irq77
153144
if_irq_word 78 isr_irq78
154145
if_irq_word 79 isr_irq79
155-
#if NUM_IRQS > 80
146+
#if PICO_NUM_VTABLE_IRQS > 80
156147
#error more IRQ entries required
157148
#endif
158-
#endif
159-
#endif // #if !PICO_MINIMAL_VECTOR_TABLE
149+
#endif // #if !PICO_MINIMAL_STORED_VECTOR_TABLE
150+
__vectors_end:
160151

161152
// all default exception handlers do nothing, and we can check for them being set to our
162153
// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end
@@ -177,7 +168,7 @@ __default_isrs_start:
177168

178169
// these are separated out for clarity
179170
decl_isr_bkpt isr_invalid
180-
#if !PICO_MINIMAL_VECTOR_TABLE
171+
#if !PICO_MINIMAL_STORED_VECTOR_TABLE
181172
decl_isr_bkpt isr_nmi
182173
decl_isr_bkpt isr_hardfault
183174
decl_isr_bkpt isr_svcall
@@ -189,7 +180,7 @@ __default_isrs_end:
189180

190181
.altmacro
191182
.macro decl_isr name
192-
#if !PICO_NO_STORED_VECTOR_TABLE | PICO_NO_FLASH
183+
#if !PICO_MINIMAL_STORED_VECTOR_TABLE | PICO_NO_FLASH
193184
// We declare a weak label, so user can override
194185
.weak \name
195186
#else
@@ -201,8 +192,13 @@ __default_isrs_end:
201192
.endm
202193

203194
.macro if_irq_decl num func
204-
.if \num < NUM_IRQS
195+
.if \num < PICO_NUM_VTABLE_IRQS
205196
decl_isr \func
197+
.elseif \num < NUM_IRQS
198+
// We declare a strong label, so user can't override, since there is no vtable entry
199+
.type \func,%function
200+
.thumb_func
201+
\func:
206202
.endif
207203
.endm
208204

@@ -286,10 +282,11 @@ if_irq_decl 76 isr_irq76
286282
if_irq_decl 77 isr_irq77
287283
if_irq_decl 78 isr_irq78
288284
if_irq_decl 79 isr_irq79
289-
#if NUM_IRQS > 80
285+
#if PICO_NUM_VTABLE_IRQS > 80
290286
#error more IRQ entries required
291287
#endif
292288

289+
#endif // #if !PICO_MINIMAL_STORED_VECTOR_TABLE
293290
// All unhandled USER IRQs fall through to here
294291
.global __unhandled_user_irq
295292
.thumb_func
@@ -299,7 +296,6 @@ __unhandled_user_irq:
299296
.global unhandled_user_irq_num_in_r0
300297
unhandled_user_irq_num_in_r0:
301298
bkpt #0
302-
#endif // #if !PICO_MINIMAL_VECTOR_TABLE
303299

304300
// ----------------------------------------------------------------------------
305301

src/rp2_common/pico_crt0/crt0_riscv.S

Lines changed: 29 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88

99
#include "hardware/regs/addressmap.h"
1010
#include "hardware/regs/rvcsr.h"
11+
#include "hardware/irq.h"
1112
#include "pico/binary_info/defs.h"
12-
#include "boot/picobin.h"
1313
#include "pico/bootrom_constants.h"
14+
#include "boot/picobin.h"
1415

1516
#ifdef NDEBUG
1617
#ifndef COLLAPSE_IRQS
@@ -160,64 +161,22 @@ check_irq_before_exit:
160161
addi sp, sp, 80
161162
mret
162163

164+
163165
// Default software vector table for system interrupts, routed through
164166
// mip.meip. Note this is assumed in e.g. hardware_irq to begin exactly 0x34
165167
// words after the hardware vector table indicated by mtvec (defined above).
166168
.p2align 4
167169
.global __soft_vector_table
168170
__soft_vector_table:
169-
.word isr_irq0
170-
.word isr_irq1
171-
.word isr_irq2
172-
.word isr_irq3
173-
.word isr_irq4
174-
.word isr_irq5
175-
.word isr_irq6
176-
.word isr_irq7
177-
.word isr_irq8
178-
.word isr_irq9
179-
.word isr_irq10
180-
.word isr_irq11
181-
.word isr_irq12
182-
.word isr_irq13
183-
.word isr_irq14
184-
.word isr_irq15
185-
.word isr_irq16
186-
.word isr_irq17
187-
.word isr_irq18
188-
.word isr_irq19
189-
.word isr_irq20
190-
.word isr_irq21
191-
.word isr_irq22
192-
.word isr_irq23
193-
.word isr_irq24
194-
.word isr_irq25
195-
.word isr_irq26
196-
.word isr_irq27
197-
.word isr_irq28
198-
.word isr_irq29
199-
.word isr_irq30
200-
.word isr_irq31
201-
.word isr_irq32
202-
.word isr_irq33
203-
.word isr_irq34
204-
.word isr_irq35
205-
.word isr_irq36
206-
.word isr_irq37
207-
.word isr_irq38
208-
.word isr_irq39
209-
.word isr_irq40
210-
.word isr_irq41
211-
.word isr_irq42
212-
.word isr_irq43
213-
.word isr_irq44
214-
.word isr_irq45
215-
.word isr_irq46
216-
.word isr_irq47
217-
.word isr_irq48
218-
.word isr_irq49
219-
.word isr_irq50
220-
.word isr_irq51
171+
.macro vtable_irq_n n
172+
.word isr_irq\n
173+
.endm
174+
175+
.set IRQN, 0
176+
.rept PICO_NUM_VTABLE_IRQS
177+
vtable_irq_n IRQN
178+
.set IRQN, IRQN + 1
179+
.endr
221180

222181
// all default trap handlers do nothing, and we can check for them being set to our
223182
// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end
@@ -252,58 +211,23 @@ decl_isr isr_riscv_machine_exception
252211
decl_isr_bkpt isr_riscv_machine_timer
253212
decl_isr_bkpt isr_riscv_machine_soft_irq
254213

255-
decl_isr isr_irq0
256-
decl_isr isr_irq1
257-
decl_isr isr_irq2
258-
decl_isr isr_irq3
259-
decl_isr isr_irq4
260-
decl_isr isr_irq5
261-
decl_isr isr_irq6
262-
decl_isr isr_irq7
263-
decl_isr isr_irq8
264-
decl_isr isr_irq9
265-
decl_isr isr_irq10
266-
decl_isr isr_irq11
267-
decl_isr isr_irq12
268-
decl_isr isr_irq13
269-
decl_isr isr_irq14
270-
decl_isr isr_irq15
271-
decl_isr isr_irq16
272-
decl_isr isr_irq17
273-
decl_isr isr_irq18
274-
decl_isr isr_irq19
275-
decl_isr isr_irq20
276-
decl_isr isr_irq21
277-
decl_isr isr_irq22
278-
decl_isr isr_irq23
279-
decl_isr isr_irq24
280-
decl_isr isr_irq25
281-
decl_isr isr_irq26
282-
decl_isr isr_irq27
283-
decl_isr isr_irq28
284-
decl_isr isr_irq29
285-
decl_isr isr_irq30
286-
decl_isr isr_irq31
287-
decl_isr isr_irq32
288-
decl_isr isr_irq33
289-
decl_isr isr_irq34
290-
decl_isr isr_irq35
291-
decl_isr isr_irq36
292-
decl_isr isr_irq37
293-
decl_isr isr_irq38
294-
decl_isr isr_irq39
295-
decl_isr isr_irq40
296-
decl_isr isr_irq41
297-
decl_isr isr_irq42
298-
decl_isr isr_irq43
299-
decl_isr isr_irq44
300-
decl_isr isr_irq45
301-
decl_isr isr_irq46
302-
decl_isr isr_irq47
303-
decl_isr isr_irq48
304-
decl_isr isr_irq49
305-
decl_isr isr_irq50
306-
decl_isr isr_irq51
214+
// Declare all the ISR labels
215+
.macro decl_isr_n n
216+
.if \n < PICO_NUM_VTABLE_IRQS
217+
decl_isr isr_irq\n
218+
.elseif \n < NUM_IRQS
219+
// We declare a strong label, so user can't override, since there is no vtable entry
220+
.type isr_irq\n,%function
221+
.thumb_func
222+
isr_irq\n:
223+
.endif
224+
.endm
225+
226+
.set IRQN, 0
227+
.rept PICO_NUM_VTABLE_IRQS
228+
decl_isr_n IRQN
229+
.set IRQN, IRQN + 1
230+
.endr
307231
// fall through
308232

309233
// All unhandled USER IRQs fall through to here. Note there is no way to get

0 commit comments

Comments
 (0)