#include #include #include #include #include #include #include #include /** * Allocate one stack per CPU (hart). * Each stack is 4096 bytes, aligned to 16 bytes for safety and performance. * The entry assembly code will calculate the proper stack address for the * current hart. For more info, read up on stack pointers and see: entry.S */ char stack0[4096 * NCPU] __attribute__((aligned(16))); /* Keep this here and sync on it until we have synchronized printf */ spinlock_t sl = {0}; volatile int hold = 1; volatile int max_hart = 0; /* This is where entry.S drops us of. All cores land here */ void start() { // Do this first __sync_fetch_and_add(&max_hart, 1); __sync_synchronize(); u64 id = read_mhartid(); // Keep each CPU's hartid in its tp (thread pointer) register, for cpuid(). // This can then be retrieved with r_wp or cpuid(). It is used to index the // cpus[] array in mycpu(), which in turn holds state for each individual // cpu (struct Cpu). write_tp(id); if (id == 0) { /* Here we will do a bunch of initialization steps */ kalloc_init(); uart_puts("Hello Neptune!\n"); spinlock_init(&sl); hold = 0; } else { while (hold); } // spin_lock(&sl); // // uart_puts("Hart number: "); // uart_putc(id + '0'); // uart_putc('\n'); // // spin_unlock(&sl); if (id == 0) { spin_lock(&sl); uart_puts("Core count: "); uart_putc(max_hart + '0'); uart_putc('\n'); if (max_hart == NCPU) { uart_puts("All cores up!"); uart_putc('\n'); } spin_unlock(&sl); } // We should not arrive here, but if we do, hang in a while on wfi. while (1) __asm__ volatile("wfi"); // (Wait For Interrupt) }