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