SYSCALL cleanup and ivt rewrite
[cortex-from-scratch] / syscall.c
1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
2  * 
3  * $LOG$
4  * 2019/9/20 - ROBIN KRENS      
5  * Initial version 
6  * 
7  * $DESCRIPTION$
8  * 
9  * |----------------------------|
10  * | SYSTEM CALL        | #     |
11  * |--------------------|-------|
12  * | THEOS_getenv       |       |
13  * | THEOS_killenv      |       |
14  * | THEOS_setenv       |       |
15  * | THEOS_newenv       |       |
16  * | THEOS_cputs        |       |
17  * | THEOS_omnigod      |       |
18  * | THEOS_brk          |       |
19  * | THEOS_time         |       |
20  * | THEOS_magic        |       |
21  * |----------------------------|
22  *
23  * TODO: include in header enum
24  * */
25
26
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <stdint.h>
30
31 #include <sys/robsys.h>
32 #include <sys/mmap.h>
33
34 #include <lib/stdio.h>
35 #include <lib/string.h>
36 #include <lib/regfunc.h>
37 #include <lib/tinyprintf.h>
38
39
40 /*
41  * This is a so-called first interrupt handler
42  * The naked attribute makes sure the compiler doesn't
43  * places registers on the stack.  */
44
45 __attribute__ ((naked))
46 void * _svc_handler(void) {
47
48         uint32_t * current_sp;
49
50         /* Test whether system call was invoked from supervisor (use MSP) or
51          * user (use PSP) mode */
52         asm volatile (
53         "tst lr, #4" "\n\t"
54         "ite eq" "\n\t"
55         "mrseq %0, msp" "\n\t"
56         "mrsne %0, psp" : "=r" (current_sp));
57
58         /* An exception (or interrupt) before entering this handler
59          * places the following on the stack 
60          * 
61          * R0
62          * R1
63          * R2
64          * R3
65          * R12
66          * LR
67          * PC <- placed at current_sp[6]
68          * PSR 
69          *
70          * PC contains the return address that will continue after this SVC handler
71          * is finised. The previous address (the svc # call) is at PC - 2, the
72          * first byte contains the svc number.
73          * */
74
75         uint8_t svc_nr = ((char *) current_sp[6])[-2];
76
77         printf("SYSTEM CALL NR: %d", svc_nr);
78
79         for (;;);
80
81 }
82
83 void syscall(unsigned int * args) {
84
85         uint32_t svc_number = 99;
86         printf("SYSCALL NR: %x", svc_number);
87
88         for(;;);
89         /* switch(SYSCALL_NO) {
90                 case THEOS_cputs:
91                         kernel_cputs(a1, a2);
92                         break;
93                 default:
94                         for (;;);
95         } */
96
97 }
98
99 void syscall_init() {
100
101         /* SVC is located at position 11 in the interrupt vector table  */
102         ivt_set_gate(11, _svc_handler, 0);
103
104 }
105
106 static void kernel_cputs(char * s, size_t l) {
107
108         // TODO
109 }
110
111
112 void kernel_omnigod() {
113
114         /* */
115
116 }
117
118
119