Fixed compile error on SPARC port
[akaros.git] / kern / arch / sparc / smp.c
1 #include <smp.h>
2 #include <arch/arch.h>
3 #include <arch/smp.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <error.h>
7 #include <assert.h>
8 #include <atomic.h>
9
10 #ifdef __SHARC__
11 #pragma nosharc
12 #endif
13
14 #ifdef __DEPUTY__
15 #pragma nodeputy
16 #endif
17
18 void
19 smp_boot(void)
20 {
21         extern int time_for_smp_init;
22         num_cpus = 1;
23         printd("Cores, report in!\n");
24         time_for_smp_init = 1;
25
26         smp_percpu_init();
27
28         while(*(volatile uint32_t*)&num_cpus < num_cores());
29
30         printd("%d cores reporting!\n",num_cpus);
31 }
32
33 void
34 smp_init(void)
35 {
36         static spinlock_t report_in_lock = SPINLOCK_INITIALIZER;
37
38         smp_percpu_init();
39         spin_lock(&report_in_lock);
40         num_cpus++;
41         spin_unlock(&report_in_lock);
42
43         printd("Good morning, Vietnam! (core id = %d)\n",core_id());
44
45         smp_idle();
46 }
47
48 handler_wrapper_t
49 wrapper_pool[MAX_NUM_CPUS*8] = {{{0},SPINLOCK_INITIALIZER}};
50
51 handler_wrapper_t*
52 smp_make_wrapper()
53 {
54         int i;
55         for(i = 0; i < sizeof(wrapper_pool)/sizeof(wrapper_pool[0]); i++)
56                 if(spin_trylock(&wrapper_pool[i].lock) == 0)
57                         return &wrapper_pool[i];
58         return NULL;
59 }
60
61 void
62 smp_call_wrapper(trapframe_t* tf, uint32_t src, isr_t handler,
63                  handler_wrapper_t* wrapper,void* data)
64 {
65         if(wrapper)
66                 wrapper->wait_list[core_id()] = 0;
67         handler(tf,data);
68 }
69
70 int smp_call_function_self(isr_t handler, void* data,
71                            handler_wrapper_t** wait_wrapper)
72 {
73         return smp_call_function_single(core_id(),handler,data,wait_wrapper);
74 }
75
76 int smp_call_function_all(isr_t handler, void* data,
77                           handler_wrapper_t** wait_wrapper)
78 {
79         int8_t state = 0;
80         int i;
81         handler_wrapper_t* wrapper = 0;
82         if(wait_wrapper)
83         {
84                 wrapper = *wait_wrapper = smp_make_wrapper();
85                 if(!wrapper)
86                         return -ENOMEM;
87
88                 for(i = 0; i < num_cores(); i++)
89                         wrapper->wait_list[i] = 1;
90         }
91
92         enable_irqsave(&state);
93
94         // send to others
95         for(i = 0; i < num_cores(); i++)
96         {
97                 if(i == core_id())
98                         continue;
99
100                 send_kernel_message(i, (amr_t)smp_call_wrapper,
101                                           (long)handler, (long)wrapper, 
102                                           (long)data, KMSG_IMMEDIATE);
103         }
104
105         // send to me
106         send_kernel_message(core_id(), (amr_t)smp_call_wrapper,
107                                   (long)handler, (long)wrapper,
108                                   (long)data, KMSG_IMMEDIATE);
109
110         cpu_relax(); // wait to get the interrupt
111
112         disable_irqsave(&state);
113
114         return 0;
115 }
116
117 int smp_call_function_single(uint32_t dest, isr_t handler, void* data,
118                              handler_wrapper_t** wait_wrapper)
119 {
120         int8_t state = 0;
121         handler_wrapper_t* wrapper = 0;
122         if(wait_wrapper)
123         {
124                 wrapper = *wait_wrapper = smp_make_wrapper();
125                 if(!wrapper)
126                         return -ENOMEM;
127                 wrapper->wait_list[dest] = 1;
128         }
129
130         enable_irqsave(&state);
131
132         send_kernel_message(dest, (amr_t)smp_call_wrapper,
133                                   (long)handler, (long)wrapper,
134                                   (long)data, KMSG_IMMEDIATE);
135
136         cpu_relax(); // wait to get the interrupt, if it's to this core
137
138         disable_irqsave(&state);
139
140         return 0;
141 }
142
143 int smp_call_wait(handler_wrapper_t* wrapper)
144 {
145         int i;
146         for(i = 0; i < num_cores(); i++)
147                 while(wrapper->wait_list[i]);
148
149         spin_unlock(&wrapper->lock);
150         return 0;
151 }
152
153 /* Perform any initialization needed by per_cpu_info.  Right now, this just
154  * inits the amsg list (which sparc will probably also want).  Make sure every
155  * core calls this at some point in the smp_boot process. */
156 void __arch_pcpu_init(uint32_t coreid)
157 {
158 }