Userspace no longer includes the kernel's arch/*
[akaros.git] / tests / mproctests.c
1 #include <parlib.h>
2 #include <stdlib.h>
3 #include <hart.h>
4 #include <ros/mman.h>
5 #include <ros/resource.h>
6 #include <stdio.h>
7
8 #ifdef __i386__ // TODO: fix me with per-arch user includes
9 static __inline uint64_t
10 read_tsc(void)
11 {
12         uint64_t tsc;
13         __asm __volatile("rdtsc" : "=A" (tsc));
14         return tsc;
15 }
16
17 static __inline void
18 cpu_relax(void)
19 {
20         asm volatile("pause" : : : "memory");
21 }
22 #else
23 static __inline uint64_t
24 read_tsc(void)
25 {
26         return read_perfctr(0,0);
27 }
28
29 static __inline void
30 cpu_relax(void)
31 {
32         int ctr = 8;
33         asm volatile("1: deccc %0; bne 1b; nop" :
34                      "=r"(ctr) : "0"(ctr) : "cc","memory");
35 }
36 #endif
37
38 // ghetto udelay, put in a lib somewhere and export the tsc freq
39 void udelay(uint64_t usec, uint64_t tsc_freq)
40 {
41         uint64_t start, end, now;
42
43         start = read_tsc();
44     end = start + (tsc_freq * usec) / 1000000;
45         if (end == 0) printf("This is terribly wrong \n");
46         do {
47         cpu_relax();
48         now = read_tsc();
49         } while (now < end || (now > start && end < start));
50         return;
51 }
52
53 #define TEST_MMAP                                        1
54 #define TEST_ONE_CORE                            2
55 #define TEST_ASK_FOR_TOO_MANY_CORES      3
56 #define TEST_INCREMENTAL_CHANGES         4
57 #define TEST_YIELD_OUT_OF_ORDER          5
58 #define TEST_YIELD_0_OUT_OF_ORDER        6
59 #define TEST_YIELD_ALL               7
60 #define TEST_SWITCH_TO_RUNNABLE_S        8
61 #define TEST_CRAZY_YIELDS                        9
62 #define TEST_CONCURRENT_SYSCALLS        10
63
64 int test = TEST_SWITCH_TO_RUNNABLE_S;
65
66 static void global_tests(uint32_t vcoreid);
67
68 int main(int argc, char** argv)
69 {
70         uint32_t vcoreid;
71         int retval;
72         hart_init();
73
74         if ((vcoreid = hart_self())) {
75                 printf("Should never see me! (from vcore %d)\n", vcoreid);
76         } else { // core 0
77                 printf("Hello from else vcore 0\n");
78                 printf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
79                 switch (test) {
80                         case TEST_MMAP:
81                                 printf("Testing MMAP\n");
82                                 void *CT(8*PGSIZE) addr;
83                                 addr = sys_mmap((void*SNT)USTACKTOP - 20*PGSIZE, 8*PGSIZE, 3,
84                                                 MAP_FIXED | MAP_ANONYMOUS, -1, 0);
85                                 printf("got addr = 0x%08x\n", addr);
86                                 *(int*)addr = 0xdeadbeef;
87                                 *(int*)(addr + 3*PGSIZE) = 0xcafebabe;
88                                 // these should work
89                                 printf("reading addr: 0x%08x\n", *(int*)addr);
90                                 printf("reading addr+3pg: 0x%08x\n", *(int*)(addr + 3*PGSIZE));
91                                 // this should fault
92                                 printf("Should page fault and die now.\n");
93                                 { TRUSTEDBLOCK
94                                 *(int*)(addr - 3*PGSIZE) = 0xdeadbeef;
95                                 }
96                                 printf("Should not see me!!!!!!!!!!!!!!!!!!\n");
97                                 while(1);
98                         case TEST_ONE_CORE:
99                                 retval = hart_request(1);
100                                 printf("One core test's core0's retval: %d\n", retval);
101                                 printf("Check to see it's on a worker core.\n");
102                                 while(1);
103                         case TEST_ASK_FOR_TOO_MANY_CORES:
104                                 retval = hart_request(12);
105                                 printf("Asked for too many, retval: %d\n", retval);
106                                 return 0;
107                         case TEST_INCREMENTAL_CHANGES:
108                                 retval = hart_request(4);
109                                 break;
110                         default:
111                                 retval = hart_request(7);
112                 }
113                 printf("Should see me if you want to relocate core0's context "
114                         "when moving from RUNNING_S\n");
115         }
116
117         // vcore0 only below here
118         switch (test) {
119                 case TEST_YIELD_OUT_OF_ORDER:
120                         udelay(10000000, 1995014570);
121                         printf("Core 2 should have yielded, asking for another\n");
122                         retval = hart_request(7);
123                         break;
124                 case TEST_YIELD_0_OUT_OF_ORDER:
125                         udelay(5000000, 1995014570);
126                         printf("Core %d yielding\n", vcoreid);
127                         sys_yield();
128                         printf("Core 0 came back where it left off in RUNNING_M!!!\n");
129                         break;
130         }
131         global_tests(vcoreid);
132         printf("Vcore %d Done!\n", vcoreid);
133         while (1);
134         return 0;
135 }
136
137 void hart_entry(void)
138 {
139         uint32_t vcoreid;
140         static int first_time = 1; // used by vcore2
141         int retval;
142
143         vcoreid = hart_self();
144         printf("Hello from hart_entry in vcore %d\n", vcoreid);
145
146         if ((vcoreid == 2) && first_time) {
147                 first_time = 0;
148                 switch (test) {
149                         case TEST_INCREMENTAL_CHANGES:
150                                 // Testing asking for less than we already have
151                                 udelay(1000000, 1995014570); // KVM's freq.  Whatever.
152                                 printf("Asking for too few:\n");
153                                 retval = hart_request(2);
154                                 printf("Should be -EINVAL(7): %d\n", retval);
155                                 // Testing getting more while running
156                                 printf("Asking for more while running:\n");
157                                 udelay(1000000, 1995014570);
158                                 retval = hart_request(7);
159                                 printf("core2's retval: %d\n", retval);
160                                 break;
161                         case TEST_YIELD_OUT_OF_ORDER:
162                                 printf("Core %d yielding\n", vcoreid);
163                                 sys_yield();
164                                 break;
165                         case TEST_YIELD_0_OUT_OF_ORDER:
166                                 udelay(7500000, 1995014570);
167                                 printf("Core 0 should have yielded, asking for another\n");
168                                 retval = hart_request(7);
169                 }
170         }
171         global_tests(vcoreid);
172         printf("Vcore %d Done!\n", vcoreid);
173 }
174
175 static void global_tests(uint32_t vcoreid)
176 {
177         int retval;
178         switch (test) {
179                 case TEST_YIELD_ALL:
180                         printf("Core %d yielding\n", vcoreid);
181                         sys_yield();
182                         // should be RUNNABLE_M now, amt_wanted == 1
183                         while(1);
184                 case TEST_SWITCH_TO_RUNNABLE_S:
185                         if (vcoreid == 2) {
186                                 printf("Core %d trying to request 0/ switch to _S\n", vcoreid);
187                                 udelay(3000000, 1995014570);
188                                 retval = hart_request(0);
189                                 // will only see this if we are scheduled()
190                                 printf("Core %d back up! (retval:%d)\n", vcoreid, retval);
191                                 printf("And exiting\n");
192                                 exit(0);
193                         } 
194                         while(1);
195                 case TEST_CRAZY_YIELDS:
196                         udelay(300000*vcoreid, 1995014570);
197                         hart_request(7);
198                         sys_yield();
199                         printf("should  never see me, unless you slip into *_S\n");
200                         break;
201                 case TEST_CONCURRENT_SYSCALLS:
202                         for (int i = 0; i < 10; i++) {
203                                 for (int j = 0; j < 100; j++)
204                                         sys_null();
205                                 printf("Hello from vcore %d, iteration %d\n", vcoreid, i);
206                         }
207                         break;
208         }
209 }