Temporarily add RISC-V GCC CAS routines to parlib
[akaros.git] / tests / msr_get_singlecore.c
1 /* tests/msr_get_singlecore.c
2  *
3  * Like msr_get_cores.c, but it only gets one core. */
4
5
6 #include <parlib.h>
7 #include <ros/mman.h>
8 #include <ros/resource.h>
9 #include <ros/procdata.h>
10 #include <ros/bcq.h>
11 #include <arch/arch.h>
12 #include <stdio.h>
13 #include <vcore.h>
14 #include <mcs.h>
15 #include <timing.h>
16 #include <rassert.h>
17 #include <uthread.h>
18
19 #ifdef __sparc_v8__
20 # define udelay(x) udelay((x)/2000)
21 #endif
22
23 mcs_barrier_t b;
24
25 void *core0_tls = 0;
26 uint64_t begin = 0, end = 0;
27 volatile bool core1_up = FALSE;
28
29 int main(int argc, char** argv)
30 {
31         uint32_t vcoreid = vcore_id();
32         int retval = 0;
33
34         mcs_barrier_init(&b, max_vcores());
35
36 /* begin: stuff userspace needs to do before switching to multi-mode */
37         vcore_init();
38         #if 0
39         /* tell the kernel where and how we want to receive notifications */
40         struct notif_method *nm;
41         for (int i = 0; i < MAX_NR_NOTIF; i++) {
42                 nm = &__procdata.notif_methods[i];
43                 nm->flags |= NOTIF_WANTED | NOTIF_MSG | NOTIF_IPI;
44                 nm->vcoreid = i % 2; // vcore0 or 1, keepin' it fresh.
45         }
46         #endif
47         /* Need to save this somewhere that you can find it again when restarting
48          * core0 */
49         core0_tls = get_tls_desc(0);
50         /* Need to save our floating point state somewhere (like in the
51          * user_thread_tcb so it can be restarted too */
52 /* end: stuff userspace needs to do before switching to multi-mode */
53
54         /* get into multi mode */
55         retval = vcore_request(1);
56         if (retval)
57                 printf("Fucked!\n");
58
59         printf("Proc %d requesting another vcore\n", getpid());
60         begin = read_tsc();
61         retval = vcore_request(1);
62         if (retval)
63                 printf("Fucked!\n");
64         while (!core1_up)
65                 cpu_relax;
66         end = read_tsc();
67         printf("Took %llu usec (%llu nsec) to receive 1 core (cold).\n",
68                udiff(begin, end), ndiff(begin, end));
69         printf("[T]:002:%llu:%llu:1:C.\n",
70                udiff(begin, end), ndiff(begin, end));
71         core1_up = FALSE;
72         udelay(2000000);
73         printf("Proc %d requesting the vcore again\n", getpid());
74         begin = read_tsc();
75         retval = vcore_request(1);
76         if (retval)
77                 printf("Fucked!\n");
78         while (!core1_up)
79                 cpu_relax();
80         end = read_tsc();
81         printf("Took %llu usec (%llu nsec) to receive 1 core (warm).\n",
82                udiff(begin, end), ndiff(begin, end));
83         printf("[T]:002:%llu:%llu:1:W.\n",
84                udiff(begin, end), ndiff(begin, end));
85         return 0;
86 }
87
88 void vcore_entry(void)
89 {
90         uint32_t vcoreid = vcore_id();
91
92 /* begin: stuff userspace needs to do to handle notifications */
93         struct vcore *vc = &__procinfo.vcoremap[vcoreid];
94         struct preempt_data *vcpd;
95         vcpd = &__procdata.vcore_preempt_data[vcoreid];
96         
97         /* Lets try to restart vcore0's context.  Note this doesn't do anything to
98          * set the appropriate TLS.  On x86, this will involve changing the LDT
99          * entry for this vcore to point to the TCB of the new user-thread. */
100         if (vcoreid == 0) {
101                 clear_notif_pending(vcoreid);
102                 set_tls_desc(core0_tls, 0);
103                 assert(__vcoreid == 0); /* in case anyone uses this */
104                 /* Load silly state (Floating point) too */
105                 pop_ros_tf(&vcpd->notif_tf, vcoreid);
106                 panic("should never see me!");
107         }       
108 /* end: stuff userspace needs to do to handle notifications */
109
110         /* all other vcores are down here */
111         core1_up = TRUE;
112
113         while (core1_up)
114                 cpu_relax();
115         printf("Proc %d's vcore %d is yielding\n", getpid(), vcoreid);
116         sys_yield(0);
117
118         while(1);
119 }
120