1
1
#include < asm.h>
2
2
#include < cpu.h>
3
3
#include < dev/virtio/mmio.h>
4
+ #include < dev/driver.h>
4
5
#include < devicetree.h>
5
6
#include < fs/vfs.h>
6
7
#include < module.h>
@@ -72,6 +73,7 @@ extern "C" uint64_t secondary_core_stack;
72
73
static bool second_done = false ;
73
74
74
75
extern " C" void secondary_entry (int hartid) {
76
+ printk (" got into hart %d\n " , hartid);
75
77
struct rv ::hart_state sc;
76
78
sc.hartid = hartid;
77
79
sc.kernel_sp = 0 ;
@@ -101,80 +103,55 @@ extern "C" void secondary_entry(int hartid) {
101
103
}
102
104
}
103
105
104
- int start_secondary (void ) {
106
+ bool start_secondary (int i ) {
105
107
// start secondary cpus
106
- for (int i = 0 ; i < CONFIG_MAX_CPUS; i++) {
107
- auto &sc = rv::get_hstate ();
108
- if (i == sc.hartid ) continue ;
108
+ auto &sc = rv::get_hstate ();
109
+ if (i == sc.hartid ) return false ;
109
110
110
- // KINFO("[hart %d] Trying to start hart %d\n", sc.hartid, i);
111
- // allocate 2 pages for the secondary core
112
- secondary_core_stack = (uint64_t )malloc (CONFIG_RISCV_BOOTSTACK_SIZE * 4096 );
113
- secondary_core_stack += CONFIG_RISCV_BOOTSTACK_SIZE * 4096 ;
111
+ // KINFO("[hart %d] Trying to start hart %d\n", sc.hartid, i);
112
+ // allocate 2 pages for the secondary core
113
+ secondary_core_stack = (uint64_t )malloc (CONFIG_RISCV_BOOTSTACK_SIZE * 4096 );
114
+ secondary_core_stack += CONFIG_RISCV_BOOTSTACK_SIZE * 4096 ;
114
115
115
- second_done = false ;
116
- __sync_synchronize ();
116
+ second_done = false ;
117
+ __sync_synchronize ();
117
118
118
- // KINFO("[hart %d] Trying to start hart %d\n", sc.hartid, i);
119
119
120
- auto ret = sbi_call (SBI_EXT_HSM, SBI_EXT_HSM_HART_START, i, secondary_core_startup_sbi, 0 );
121
- if (ret.error != SBI_SUCCESS) {
122
- continue ;
123
- }
120
+ // KINFO("[hart %d] Trying to start hart %d\n", sc.hartid, i);
124
121
125
- while (second_done != true ) {
126
- __sync_synchronize ();
127
- }
128
- LOG (" HART #%d started\n " , i);
122
+ auto ret = sbi_call (SBI_EXT_HSM, SBI_EXT_HSM_HART_START, i, secondary_core_startup_sbi, 0 );
123
+ if (ret.error != SBI_SUCCESS) {
124
+ return false ;
125
+ }
126
+ while (second_done != true ) {
127
+ __sync_synchronize ();
129
128
}
129
+ LOG (" HART #%d started\n " , i);
130
130
131
- return 0 ;
131
+ return true ;
132
132
}
133
133
134
-
135
- #if 0
136
- template <typename T>
137
- struct lref {
134
+ class RISCVHart : public dev ::Driver {
138
135
public:
139
- lref(T &val) : val(val) {
140
- val.lock();
141
- }
142
-
143
- ~lref(void) {
144
- val.unlock();
145
- }
146
-
147
- T *operator->(void) {
148
- return &val;
149
- }
150
-
151
- T *operator*(void) {
152
- return &val;
153
- }
154
-
155
- private:
156
- T &val;
157
- };
158
-
159
- struct lockable {
160
- void do_thing(void) {
161
- printk("do thing\n");
162
- }
163
-
164
- void lock(void) {
165
- printk("lock\n");
166
- }
167
- void unlock(void) {
168
- printk("unlock\n");
169
- }
136
+ virtual ~RISCVHart (void ) {}
137
+ dev::ProbeResult probe (ck::ref<dev::Device> dev) override {
138
+ if (auto mmio = dev->cast <dev::MMIODevice>()) {
139
+ if (mmio->is_compat (" riscv" )) {
140
+ auto hartid = mmio->address ();
141
+ #ifdef CONFIG_SMP
142
+ if (hartid != rv::get_hstate ().hartid ) {
143
+ LOG (" found hart %d\n " , mmio->address ());
144
+ LOG (" Trying to start hart %d\n " , hartid);
145
+ // start the other core.
146
+ start_secondary (hartid);
147
+ }
148
+ #endif
149
+ }
150
+ }
151
+ return dev::ProbeResult::Ignore;
152
+ };
170
153
};
171
154
172
- static lockable *g_lockable = NULL;
173
- auto get_lockable(void) {
174
- if (g_lockable == NULL) g_lockable = new lockable;
175
- return lref(*g_lockable);
176
- }
177
- #endif
178
155
179
156
180
157
static int wakes = 0 ;
@@ -250,9 +227,10 @@ void main(int hartid, void *fdt) {
250
227
for (func_ptr *func = __init_array_start; func != __init_array_end; func++)
251
228
(*func)();
252
229
230
+ cpu::current ().cpunum = rv::get_hstate ().hartid ;
253
231
cpu::current ().primary = true ;
254
232
255
- dtb::promote ();
233
+ dtb::promote ();
256
234
257
235
arch_enable_ints ();
258
236
@@ -273,30 +251,16 @@ void main(int hartid, void *fdt) {
273
251
LOG (" Initialized the scheduler with %llu pages of ram (%llu bytes)\n " , phys::nfree (), phys::bytes_free ());
274
252
275
253
254
+ // add the hart driver
255
+ dev::Driver::add (ck::make_ref<RISCVHart>());
256
+
276
257
277
258
sched::proc::create_kthread (" main task" , [](void *) -> int {
278
259
LOG (" Calling kernel module init functions\n " );
279
260
initialize_builtin_modules ();
280
261
LOG (" kernel modules initialized\n " );
281
262
282
263
283
- /*
284
- dtb::walk_devices([](dtb::node *node) -> bool {
285
- for (int i = 0; i < node->ncompat; i++) {
286
- if (!strcmp(node->compatible[i], "virtio,mmio")) {
287
- virtio::check_mmio((void *)node->address, node->irq);
288
- }
289
- return true;
290
- }
291
-
292
- return false;
293
- });
294
- */
295
-
296
- #ifdef CONFIG_SMP
297
- start_secondary ();
298
- #endif
299
-
300
264
int mnt_res = vfs::mount (" /dev/disk0p1" , " /" , " ext2" , 0 , NULL );
301
265
if (mnt_res != 0 ) {
302
266
panic (" failed to mount root. Error=%d\n " , -mnt_res);
0 commit comments