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