Skip to content

Commit 1d544b1

Browse files
Release: v5.0
Highlights: * Added support for dsPIC33AK512MPS512 * Fixes for kernel and arch test cases * Context switching refignments * Change console to on board USB-UART * Added satck protection Fixes: * Context switch fixes * System timer fixes Signed-off-by: Muhammed Zamroodh <[email protected]>
1 parent 7dc25f4 commit 1d544b1

37 files changed

+9234
-3062
lines changed

arch/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ config DSPIC
183183
select STACK_SENTINAL
184184
select ATOMIC_OPERATIONS_C
185185
select ARCH_HAS_VECTOR_TABLE_RELOCATION
186+
select ARCH_HAS_STACK_PROTECTION
186187
select TICKLESS_CAPABLE
188+
select ARCH_HAS_CUSTOM_BUSY_WAIT
187189
help
188190
dspic architecture
189191

arch/dspic/Kconfig

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ config GEN_ISR_TABLES
1414
config DYNAMIC_INTERRUPTS
1515
default n
1616

17-
config NUM_IRQS
18-
default 279
19-
2017
config GEN_IRQ_START_VECTOR
2118
default 0
2219

@@ -27,4 +24,14 @@ config DSPIC33_IRQ_OFFLOAD_IRQ
2724
Select the interrupt number used by irq_offload().
2825
This must be a valid, software-triggerable interrupt on the dsPIC33.
2926

27+
config DSPIC_STACK_PROTECTION
28+
bool
29+
default y if HW_STACK_PROTECTION
30+
select THREAD_STACK_INFO
31+
help
32+
Enable stack overflow detection
33+
Will cause a fatal exception on stack overflow
34+
35+
config TEST_EXTRA_STACK_SIZE
36+
default 512
3037
endmenu

arch/dspic/core/irq_manage.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,65 +22,57 @@ void z_irq_spurious(const void *unused)
2222

2323
void arch_irq_enable(unsigned int irq)
2424
{
25-
volatile uint32_t *int_enable_reg[] = {&IEC0, &IEC1, &IEC2, &IEC3, &IEC4,
26-
&IEC5, &IEC6, &IEC7, &IEC8};
25+
volatile uint32_t *int_enable_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), ie_offset);
2726

2827
unsigned int reg_index = irq / (sizeof(uint32_t) << 3);
2928
unsigned int bit_pos = irq % (sizeof(uint32_t) << 3);
30-
3129
/* Enable the interrupt by setting it's bit in interrupt enable register*/
32-
*int_enable_reg[reg_index] |= (uint32_t)(1u << bit_pos);
30+
int_enable_reg[reg_index] |= (uint32_t)(1u << bit_pos);
3331
}
3432

3533
int arch_irq_is_enabled(unsigned int irq)
3634
{
37-
volatile uint32_t *int_enable_reg[] = {&IEC0, &IEC1, &IEC2, &IEC3, &IEC4,
38-
&IEC5, &IEC6, &IEC7, &IEC8};
35+
volatile uint32_t *int_enable_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), ie_offset);
3936

4037
unsigned int reg_index = irq / (sizeof(uint32_t) << 3);
4138
unsigned int bit_pos = irq % (sizeof(uint32_t) << 3);
4239

43-
return ((*int_enable_reg[reg_index] >> bit_pos) & 0x1u);
40+
return ((int_enable_reg[reg_index] >> bit_pos) & 0x1u);
4441
}
4542

4643
void arch_irq_disable(unsigned int irq)
4744
{
48-
volatile uint32_t *int_enable_reg[] = {&IEC0, &IEC1, &IEC2, &IEC3, &IEC4,
49-
&IEC5, &IEC6, &IEC7, &IEC8};
45+
volatile uint32_t *int_enable_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), ie_offset);
5046

5147
unsigned int reg_index = irq / (sizeof(uint32_t) << 3);
5248
unsigned int bit_pos = irq % (sizeof(uint32_t) << 3);
5349

5450
/* Disable the interrupt by clearing it's bit in interrupt enable register*/
55-
*int_enable_reg[reg_index] &= (uint32_t)(~(1u << bit_pos));
51+
int_enable_reg[reg_index] &= (uint32_t)(~(1u << bit_pos));
5652
}
5753

5854
bool arch_dspic_irq_isset(unsigned int irq)
5955
{
60-
volatile uint32_t *int_ifs_reg[] = {&IFS0, &IFS1, &IFS2, &IFS3, &IFS4,
61-
&IFS5, &IFS6, &IFS7, &IFS8};
56+
volatile uint32_t *int_ifs_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), if_offset);
6257
volatile int ret_ifs = false;
6358
unsigned int reg_index = irq / (sizeof(uint32_t) << 3);
6459
unsigned int bit_pos = irq % (sizeof(uint32_t) << 3);
6560

66-
if ((bool)(void *)(*int_ifs_reg[reg_index] & (uint32_t)(1U << bit_pos))) {
61+
if ( (int_ifs_reg[reg_index] & (1u << bit_pos)) != 0u ) {
6762
ret_ifs = true;
6863
}
6964
return ret_ifs;
7065
}
7166

72-
73-
7467
void z_dspic_enter_irq(int irq)
7568
{
76-
volatile uint32_t *int_ifs_reg[] = {&IFS0, &IFS1, &IFS2, &IFS3, &IFS4,
77-
&IFS5, &IFS6, &IFS7, &IFS8};
69+
volatile uint32_t *int_ifs_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), if_offset);
7870

7971
unsigned int reg_index = (unsigned int)irq / (sizeof(uint32_t) << 3);
8072
unsigned int bit_pos = (unsigned int)irq % (sizeof(uint32_t) << 3);
8173

8274
/* Enable the interrupt by setting it's bit in interrupt enable register*/
83-
*int_ifs_reg[reg_index] |= (uint32_t)(1u << bit_pos);
75+
int_ifs_reg[reg_index] |= (uint32_t)(1u << bit_pos);
8476
}
8577

8678
#ifdef __cplusplus

arch/dspic/core/isr_wrapper.S

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@
22
* Copyright (c) 2025, Microchip Technology Inc.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5+
#include <zephyr/devicetree.h>
6+
#include <offsets.h>
7+
#define OFFSET DT_PROP(DT_NODELABEL(intc0), if_offset)
58

9+
#if defined(CONFIG_BOARD_DSPIC33A_CURIOSITY_P33AK512MPS512)
10+
#define RAM_END 0x00013FFC
11+
#elif defined(CONFIG_BOARD_DSPIC33A_CURIOSITY_P33AK128MC106)
12+
#define RAM_END 0x00007FFC
13+
#endif
614

715

8-
.LC0:
9-
.long _IFS0
10-
.long _IFS1
11-
.long _IFS2
12-
.long _IFS3
13-
.long _IFS4
14-
.long _IFS5
15-
.long _IFS6
16-
.long _IFS7
17-
.long _IFS8
16+
.equ IF_OFFSET, OFFSET
1817

1918
.section .text,code
2019
.section .isr.text._COMMONInterrupt,keep,code,keep
@@ -38,6 +37,9 @@ __COMMONInterrupt:
3837

3938

4039
call w1
40+
mov.w _INTTREGbits,w0
41+
and.l #(0x1ff&0xFFFF),w0
42+
sub.l w0,#9,w0
4143
call _arch_dspic_irq_clear
4244

4345

@@ -53,15 +55,12 @@ __COMMONInterrupt:
5355
bra z,.L2
5456
cp0.b _z_sys_post_kernel
5557
bra z,.L2
56-
mov.bz _INTCON1bits+1,w0
57-
bfext.l #7,#1,w0,w0
58-
mov.l w0,[w14]
59-
bclr.b _INTCON1+1,#7
60-
mov.l [w14],w0
6158
mov.l [--w15], w8
6259
ulnk
6360
CTXTSWP #0x0
6461
mov.l w0, [w15++]
62+
mov.l #RAM_END, w0
63+
mov.l w0, SPLIM
6564
mov.l sr, w0
6665
and #0xe0, w0
6766
bra nz, 1f
@@ -105,10 +104,10 @@ __COMMONInterrupt:
105104
lnk #0x4
106105

107106
mov.l #__kernel, w0
108-
mov.l #0x8, w1
107+
mov.l #___cpu_t_current_OFFSET, w1
109108
add w0, w1, w1
110109
mov.l [w1], w2
111-
mov.l #0x28, w1
110+
mov.l #___thread_t_callee_saved_OFFSET, w1
112111
add w2, w1, w1
113112

114113
mov.l w8, [w1++]
@@ -158,8 +157,6 @@ __COMMONInterrupt:
158157
mov.l [w2], [w1++]
159158
mov.l #XBREV, w2
160159
mov.l [w2], [w1++]
161-
clr A
162-
clr B
163160
slac.l A, [W1++]
164161
sac.l A, [W1++]
165162
suac.l A, [W1++]
@@ -174,15 +171,15 @@ __COMMONInterrupt:
174171
mov.sl #__kernel+20,w0
175172
mov.l [w0],w0
176173
mov.sl #__kernel,w1
177-
mov.l w0,[w1+8]
178-
mov.l [w0+300],w0
174+
mov.l w0,[w1 + ___cpu_t_current_OFFSET]
175+
mov.l [w0 + ___thread_t_tls_OFFSET],w0
179176
rcall __set_tls
180177

181178
mov.l #__kernel, w0
182-
mov.l #0x8, w1
179+
mov.l #___cpu_t_current_OFFSET, w1
183180
add w0, w1, w1
184181
mov.l [w1], w2
185-
mov.l #0x28, w1
182+
mov.l #___thread_t_callee_saved_OFFSET, w1
186183
add w2, w1, w1
187184

188185
mov.l [w1++], w8
@@ -234,12 +231,12 @@ __COMMONInterrupt:
234231
mov.l [w1++], [w2]
235232
clr A
236233
clr B
237-
slac.l A, [W1++]
238-
sac.l A, [W1++]
239-
suac.l A, [W1++]
240-
slac.l B, [W1++]
241-
sac.l B, [W1++]
242-
suac.l B, [W1++]
234+
llac.l [w1++], A
235+
lac.l [w1++], A
236+
luac.l [w1++], A
237+
llac.l [w1++], B
238+
lac.l [w1++], B
239+
luac.l [w1++], B
243240
mov.l [w1++], w15
244241
mov.l [w1++], w14
245242
mov.l #SPLIM, w2
@@ -286,10 +283,24 @@ __COMMONInterrupt:
286283
mov.l [w0], w0
287284
lnk #0x4
288285
1:
286+
mov.l w2, [w15++]
287+
mov.l w1, [w15++]
288+
mov.l w0, [w15++]
289+
mov.sl #__kernel, w0
290+
mov.l [w0 + ___cpu_t_current_OFFSET], w1
291+
mov.l #___thread_t_arch_OFFSET, w2
292+
add.l w2, w1, w1
293+
mov.l [w1 + ___thread_arch_t_swapped_from_thread_OFFSET], w0
294+
mov.l #0, w2
295+
cp.l w2, w0
296+
mov.l [--w15], w0
297+
bra z, 1f
298+
mov.l [w1 + ___thread_arch_t_swap_return_value_OFFSET], w0
299+
mov.l w2, [w1 + ___thread_arch_t_swapped_from_thread_OFFSET]
300+
1:
301+
mov.l [--w15], w1
302+
mov.l [--w15], w2
289303
nop
290-
cp.l w0,#0
291-
bra z,.L1
292-
bset.b _INTCON1+1,#7
293304
retfie
294305

295306

@@ -307,23 +318,14 @@ __COMMONInterrupt:
307318
.type _arch_dspic_irq_clear,@function
308319
_arch_dspic_irq_clear:
309320

310-
lnk #36
311-
mov.w _INTTREGbits,w0
312-
mov.sl #.LC0,w1
313-
repeat #9-1
314-
mov.l [w1++],[w14++]
315-
sub.l #36,w14
316-
sub.l #36,w1
317-
and.l #(0x1ff&0xFFFF),w0
318-
sub.l w0,#9,w0
319-
lsr.l w0,#5,w1
320-
sl.l w1,#2,w1
321-
add.l w1,w14,w1
322-
mov.l [w1],w2
323-
and.l w0,#(0x1f&0x7F),w0
324-
movs.l #0x1,w1
325-
sl.l w1,w0,w0
326-
com.l w0,w0
327-
and.l w0,[w2],[w2]
328-
ulnk
329-
return
321+
lnk #0
322+
lsr.l w0,#5,w1
323+
sl.l w1,#2,w1
324+
add.l #IF_OFFSET,w1
325+
and.l w0,#(0x1f&0x7F),w2
326+
movs.l #0x1,w0
327+
sl.l w0,w2,w0
328+
com.l w0,w0
329+
and.l w0,[w1],[w1]
330+
ulnk
331+
return

arch/dspic/core/offsets/offsets.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@
77
#include <zephyr/kernel.h>
88
#include <kernel_offsets.h>
99

10+
GEN_OFFSET_SYM(_thread_arch_t, swap_return_value);
11+
GEN_OFFSET_SYM(_thread_arch_t, swapped_from_thread);
12+
1013
GEN_ABS_SYM_END

arch/dspic/core/swap.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ int arch_swap(unsigned int key)
1919
z_thread_mark_switched_out();
2020
#endif
2121

22+
register int result __asm__("w0");
2223
/* store off key and return value */
2324
_current->arch.cpu_level = key;
2425
_current->arch.swap_return_value = -EAGAIN;
26+
_current->arch.swapped_from_thread = 1;
27+
result = _current->arch.swap_return_value;
2528

2629
/*Check if swap is needed*/
2730
if (_kernel.ready_q.cache != _current) {
@@ -39,8 +42,17 @@ int arch_swap(unsigned int key)
3942
* Make sure the return value is not being intrepreted
4043
* wrongly
4144
*/
42-
irq_unlock(key);
43-
register int result __asm__("w0");
45+
__asm__ volatile(
46+
"mov.l w1, [w15++]\n\t"
47+
"mov.l w2, [w15++]\n\t"
48+
);
49+
_current->arch.swapped_from_thread = 0;
50+
result = _current->arch.swap_return_value;
51+
irq_unlock(_current->arch.cpu_level);
52+
__asm__ volatile(
53+
"mov.l [--w15], w2\n\t"
54+
"mov.l [--w15], w1\n\t"
55+
);
4456
return result;
4557

4658
/* Context switch is performed here. Returning implies the

arch/dspic/core/thread.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
*/
55

66
#include <zephyr/kernel.h>
7+
#include <kernel_arch_func.h>
78
#include <string.h>
89

9-
#define RAM_END 0x00007FFC
1010
#define DSPIC_STATUS_DEFAULT 0
1111

1212
void z_thread_entry(k_thread_entry_t thread, void *arg1, void *arg2, void *arg3);
@@ -23,7 +23,13 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *sta
2323
/* Setting all register to zero*/
2424
(void)memset(init_frame, 0, sizeof(struct arch_esf));
2525

26-
/* Setup initial stack frame*/
26+
/* Setup initial stack frame
27+
* During the initial thread entry the w0 serves the function of thread
28+
* entry function pointer, but the general usage of w0 as per the C ABI
29+
* is to pass back the return data. Here set return value as entry pointer
30+
* value
31+
*/
32+
arch_thread_return_value_set(thread, (unsigned int)entry);
2733
init_frame->W0 = (uint32_t)entry;
2834
init_frame->W1 = (uint32_t)(void *)p1;
2935
init_frame->W2 = (uint32_t)(void *)p2;
@@ -51,11 +57,13 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *sta
5157
*/
5258
thread->callee_saved.stack = (uint32_t)(void *)init_frame + (sizeof(struct arch_esf));
5359
thread->callee_saved.frame = (uint32_t)thread->callee_saved.stack;
54-
/*TODO: Need to handle splim properly*/
55-
thread->callee_saved.splim = RAM_END;
60+
thread->callee_saved.splim = (uint32_t)(thread->stack_info.start + thread->stack_info.size);
61+
/*Set the initial key for irq unlock*/
62+
thread->arch.cpu_level = 1;
5663
}
5764

5865
int arch_coprocessors_disable(struct k_thread *thread)
5966
{
67+
(void)thread;
6068
return -ENOTSUP;
6169
}

0 commit comments

Comments
 (0)