Vcore0 can restart in _M mode
[akaros.git] / tests / mhello.c
1 #include <parlib.h>
2 #include <ros/mman.h>
3 #include <ros/resource.h>
4 #include <ros/procdata.h>
5 #include <ros/notification.h>
6 #include <ros/bcq.h>
7 #include <arch/arch.h>
8 #include <stdio.h>
9 #include <hart.h>
10
11 hart_barrier_t b;
12
13 __thread int temp;
14
15 int main(int argc, char** argv)
16 {
17         uint32_t vcoreid;
18         int retval;
19
20         hart_barrier_init(&b,hart_max_harts()-1);
21
22 /* begin: stuff userspace needs to do before switching to multi-mode */
23         if (hart_init())
24                 printf("Harts failed, we're fucked!\n");
25
26         /* tell the kernel where and how we want to receive notifications */
27         struct notif_method *nm;
28         for (int i = 1; i < MAX_NR_NOTIF; i++) {
29                 nm = &__procdata.notif_methods[i];
30                 nm->flags |= NOTIF_WANTED | NOTIF_MSG | NOTIF_IPI;
31                 nm->vcoreid = i % 2; // vcore0 or 1, keepin' it fresh.
32         }
33
34         /* don't forget to enable notifs on vcore0 at some point */
35         struct preempt_data *vcpd;
36         vcpd = &__procdata.vcore_preempt_data[0];
37         vcpd->notif_enabled = TRUE;
38         
39 /* end: stuff userspace needs to do before switching to multi-mode */
40
41         if ((vcoreid = hart_self())) {
42                 printf("Should never see me! (from vcore %d)\n", vcoreid);
43         } else { // core 0
44                 temp = 0xdeadbeef;
45                 printf("Hello from vcore %d with temp addr = %p and temp = %p\n",
46                        vcoreid, &temp, temp);
47                 printf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
48                 //retval = sys_resource_req(RES_CORES, 2, 0);
49                 //retval = hart_request(hart_max_harts()-2);
50                 retval = hart_request(2); // doesn't do what you think.  this gives 3.
51                 //debug("retval = %d\n", retval);
52         }
53         printf("Vcore %d Done!\n", vcoreid);
54
55         hart_barrier_wait(&b,hart_self());
56
57         printf("All Cores Done!\n", vcoreid);
58         while(1); // manually kill from the monitor
59         return 0;
60 }
61
62 void hart_entry(void)
63 {
64         uint32_t vcoreid = hart_self();
65
66 /* begin: stuff userspace needs to do to handle notifications */
67
68         struct preempt_data *vcpd;
69         vcpd = &__procdata.vcore_preempt_data[vcoreid];
70         
71         /* here is how you receive a notif_event */
72         struct notif_event ne = {0};
73         bcq_dequeue(&vcpd->notif_evts, &ne, NR_PERCORE_EVENTS);
74         printf("the queue is on vcore %d and has a ne with type %d\n", vcoreid,
75                ne.ne_type);
76         /* it might be in bitmask form too: */
77         //printf("and the bitmask looks like: ");
78         //PRINT_BITMASK(__procdata.vcore_preempt_data[vcoreid].notif_bmask, MAX_NR_NOTIF);
79         /* can see how many messages had to be sent as bits */
80         printf("Number of event overflows: %d\n", vcpd->event_overflows);
81
82         /* unmask notifications once you can let go of the notif_tf and it is okay
83          * to clobber the transition stack.
84          * Check Documentation/processes.txt: 4.2.4 */
85         vcpd->notif_enabled = TRUE;
86         
87 /* end: stuff userspace needs to do to handle notifications */
88
89         temp = 0xcafebabe;
90         printf("Hello from hart_entry in vcore %d with temp addr %p and temp %p\n",
91                vcoreid, &temp, temp);
92         hart_barrier_wait(&b,hart_self());
93         while(1);
94 }