Skip to content

Commit a2156fe

Browse files
Andrew BoieAnas Nashif
authored andcommitted
arm: implement __svc on Cortex M0
This is needed for irq_offload() and k_oops()/k_panic() Issue: ZEP-2221 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
1 parent 5b4867b commit a2156fe

File tree

4 files changed

+59
-10
lines changed

4 files changed

+59
-10
lines changed

arch/arm/core/cortex_m/vector_table.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table)
4747
.word __reserved
4848
.word __reserved
4949
.word __reserved
50-
.word __reserved /* SVC not used for now (PendSV used instead) */
50+
.word __svc
5151
.word __reserved
5252
#elif defined(CONFIG_ARMV7_M)
5353
.word __mpu_fault

arch/arm/core/cortex_m/vector_table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ GTEXT(__reset)
3939
GTEXT(__nmi)
4040
GTEXT(__hard_fault)
4141
#if defined(CONFIG_ARMV6_M)
42+
GTEXT(__svc)
4243
#elif defined(CONFIG_ARMV7_M)
4344
GTEXT(__mpu_fault)
4445
GTEXT(__bus_fault)

arch/arm/core/irq_offload.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,17 @@ void _irq_do_offload(void)
2222

2323
void irq_offload(irq_offload_routine_t routine, void *parameter)
2424
{
25-
int key;
25+
#if defined(CONFIG_ARMV6_M) && defined(CONFIG_ASSERT)
26+
/* Cortex M0 hardfaults if you make a SVC call with interrupts
27+
* locked.
28+
*/
29+
unsigned int key;
2630

27-
key = irq_lock();
31+
__asm__ volatile("mrs %0, PRIMASK;" : "=r" (key) : : "memory");
32+
__ASSERT(key == 0, "irq_offload called with interrupts locked\n");
33+
#endif
34+
35+
k_sched_lock();
2836
offload_routine = routine;
2937
offload_param = parameter;
3038

@@ -34,6 +42,5 @@ void irq_offload(irq_offload_routine_t routine, void *parameter)
3442
: "memory");
3543

3644
offload_routine = NULL;
37-
38-
irq_unlock(key);
45+
k_sched_unlock();
3946
}

arch/arm/core/swap.S

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@
2020
_ASM_FILE_PROLOGUE
2121

2222
GTEXT(__swap)
23-
#if defined(CONFIG_ARMV6_M)
24-
#elif defined(CONFIG_ARMV7_M)
2523
GTEXT(__svc)
26-
#else
27-
#error Unknown ARM architecture
28-
#endif /* CONFIG_ARMV6_M */
2924
GTEXT(__pendsv)
3025
GTEXT(_do_kernel_oops)
3126
GDATA(_k_neg_eagain)
@@ -217,6 +212,52 @@ _thread_irq_disabled:
217212
bx lr
218213

219214
#if defined(CONFIG_ARMV6_M)
215+
SECTION_FUNC(TEXT, __svc)
216+
/* Use EXC_RETURN state to find out if stack frame is on the
217+
* MSP or PSP
218+
*/
219+
ldr r0, =0x4
220+
mov r1, lr
221+
tst r1, r0
222+
beq _stack_frame_msp
223+
mrs r0, PSP
224+
bne _stack_frame_endif
225+
_stack_frame_msp:
226+
mrs r0, MSP
227+
_stack_frame_endif:
228+
229+
/* Figure out what SVC call number was invoked */
230+
ldr r1, [r0, #24] /* grab address of PC from stack frame */
231+
/* SVC is a two-byte instruction, point to it and read encoding */
232+
subs r1, r1, #2
233+
ldrb r1, [r1, #0]
234+
235+
/*
236+
* grab service call number:
237+
* 1: irq_offload (if configured)
238+
* 2: kernel panic or oops (software generated fatal exception)
239+
* Planned implementation of system calls for memory protection will
240+
* expand this case.
241+
*/
242+
243+
cmp r1, #2
244+
beq _oops
245+
246+
#if CONFIG_IRQ_OFFLOAD
247+
push {lr}
248+
blx _irq_do_offload /* call C routine which executes the offload */
249+
pop {r3}
250+
mov lr, r3
251+
#endif
252+
253+
/* exception return is done in _IntExit() */
254+
b _IntExit
255+
256+
_oops:
257+
push {lr}
258+
blx _do_kernel_oops
259+
pop {pc}
260+
220261
#elif defined(CONFIG_ARMV7_M)
221262
/**
222263
*

0 commit comments

Comments
 (0)