10 static void handle_syscall(struct event_msg *ev_msg, unsigned int ev_type,
12 struct syscall sysc = {0};
13 struct event_queue *ev_q;
16 void ghetto_vcore_entry(void);
17 struct uthread *ghetto_init(void)
19 return malloc(sizeof(struct uthread));
22 struct schedule_ops ghetto_sched_ops = {
23 .sched_init = ghetto_init,
24 .sched_entry = ghetto_vcore_entry,
26 struct schedule_ops *sched_ops = &ghetto_sched_ops;
28 int main(int argc, char** argv)
30 int num_started, retval;
33 /* register our syscall handler (2LS does this) */
34 ev_handlers[EV_SYSCALL] = handle_syscall;
36 printf("Trying to block\n");
37 /* Not doing anything else to it: no EVENT_IPI yet, etc. */
38 ev_q = get_big_event_q();
39 /* issue the diagnostic block syscall */
43 num_started = __ros_arch_syscall((long)&sysc, 1);
44 if (!(sysc.flags & SC_DONE))
45 printf("Not done, looping!\n");
47 /* You could poll on this */
48 while (!(sysc.flags & SC_DONE))
51 /* But let's check on events... Spin til something happened, then handle
52 * events. This method is just used for this testing code. */
53 while (!event_activity(ev_q->ev_mbox, ev_q->ev_flags))
56 /* by now, we should have run our handler */
57 /********************************************************/
58 /* Start MCP / IPI test */
59 printf("Switching to _M mode and testing an IPI-d ev_q\n");
60 printf("Our indirect ev_q is %08p\n", ev_q);
62 /* begin: stuff userspace needs to do before switching to multi-mode */
63 /* Note we don't need to set up event reception for any particular kevent.
64 * The ev_q in the syscall said to send an IPI to vcore 0 which means an
65 * EV_EVENT will be sent straight to vcore0. */
66 /* Need to save this somewhere that you can find it again when restarting
68 core0_tls = get_tls_desc(0);
69 /* Need to save our floating point state somewhere (like in the
70 * user_thread_tcb so it can be restarted too */
72 /* end: stuff userspace needs to do before switching to multi-mode */
74 retval = vcore_request(1);
76 printf("No cores granted, Rut Ro Raggy!\n");
77 /* now we're back in thread 0 on vcore 0 */
78 ev_q->ev_flags = EVENT_IPI;
80 sysc.u_data = (void*)1; /* using this to loop on */
81 /* issue the diagnostic blocking syscall */
84 num_started = __ros_arch_syscall((long)&sysc, 1);
85 /* have this thread "wait" */
86 if (!(sysc.flags & SC_DONE))
87 printf("Not done, looping on a local variable!\n");
90 assert((sysc.flags & SC_DONE));
91 printf("Syscall unblocked, IPI broke me out of the loop.\n");
94 put_big_event_q(ev_q);
95 printf("Syscall test exiting\n");
99 static void handle_syscall(struct event_msg *ev_msg, unsigned int ev_type,
102 struct syscall *my_sysc;
105 my_sysc = ev_msg->ev_arg3;
106 printf("Handling syscall event for sysc %08p (%08p)\n",
108 /* our syscall should be done (we ought to check the msg pointer) */
109 if (sysc.flags & SC_DONE)
110 printf("Syscall is done, retval: %d\n", sysc.retval);
112 printf("BUG! Syscall wasn't done!\n");
113 /* signal to thread 0 that the sysc is done, just to show this
114 * is getting done in vcore context. */
118 void ghetto_vcore_entry(void)
120 uint32_t vcoreid = vcore_id();
121 static bool first_time = TRUE;
123 /* begin: stuff userspace needs to do to handle notifications */
125 /* Restart vcore0's context. */
127 run_current_uthread();
128 panic("should never see me!");
130 /* unmask notifications once you can let go of the notif_tf and it is okay
131 * to clobber the transition stack.
132 * Check Documentation/processes.txt: 4.2.4. In real code, you should be
133 * popping the tf of whatever user process you want (get off the x-stack) */
134 struct preempt_data *vcpd;
135 vcpd = &__procdata.vcore_preempt_data[vcoreid];
136 vcpd->notif_enabled = TRUE;
138 /* end: stuff userspace needs to do to handle notifications */
139 /* if you have other vcores, they'll just chill here */