aboutsummaryrefslogtreecommitdiff
path: root/src/kern/svc.c
blob: ceca5fab3a3eabcd0a25e08e8b3c5520bf01af58 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "arch.h"
#include "kern/common.h"
#include "kern/log.h"
#include "kern/syscall.h"

void handle_svc_call(
    uint32_t syscall_id, uint32_t syscall_arg, uint32_t svc_number)
{
  switch (svc_number) {
    case 0x04:
      switch (syscall_id) {
#define SYSCALL(id, fn, kernfn, argt) \
  case id:                    \
    kernfn((argt)syscall_arg);    \
    break;
#include "kern/syscall/syscall_tbl.inc"
#undef SYSCALL
      }
      break;

    default:
      /* An illegal syscall. TODO kill whatever is happening. */
      break;
  }
}

#ifdef ARCH_STM32L4
/* The actual handling for the svc call. Overrides the weak
 * symbol on_svc in irq.h */
asm("	.align	2\n"
    "	.global	on_svc\n"
    "	.syntax unified\n"
    "	.fpu softvfp\n"
    "	.type	on_svc, %function\n"
    "on_svc:\n"
    "	tst   lr,#4\n"
    " ite   eq\n"
    "	moveq r12,sp\n"
    "	mrsne r12,psp\n"
    "	ldr   r12, [r12, #24]\n"
    "	ldrh  r12, [r12, #-2]\n"
    "	bics  r12, r12, #0xff00\n"
    "	push  {r4, lr}\n"
    "	mov   r2 , r12\n"
    "	bl    handle_svc_call\n"
    "	pop   {r4, lr}\n"
    "	tst   lr, #4\n"
    " ite   eq\n"
    "	moveq r12,sp\n"
    "	mrsne r12,psp\n"
    "	stm   r12,{r0-r3}\n"
    "	bx    lr\n");
#endif