87 lines
2.5 KiB
C
87 lines
2.5 KiB
C
#include <assert.h>
|
|
#include <banner.h>
|
|
#include <buddy.h>
|
|
#include <config.h>
|
|
#include <freelist.h>
|
|
#include <memory.h>
|
|
#include <panic.h>
|
|
#include <proc.h>
|
|
#include <riscv.h>
|
|
#include <spinlock.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <uart.h>
|
|
#include <util.h>
|
|
|
|
/**
|
|
* 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
|
|
__atomic_fetch_add(&max_hart, 1, __ATOMIC_SEQ_CST);
|
|
|
|
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 (unlikely(id == 0)) {
|
|
/* Here we will do a bunch of initialization steps */
|
|
memory_sweep(heap_start, heap_end);
|
|
buddy_init(heap_start, heap_end);
|
|
spinlock_init(&sl);
|
|
for (int i = 0; i < banner_len; i++) uart_putc(banner[i]);
|
|
__sync_synchronize();
|
|
hold = 0;
|
|
} else {
|
|
while (hold);
|
|
}
|
|
|
|
if (id == 0) {
|
|
spin_lock(&sl);
|
|
kprintf("Core count: %d\n", max_hart);
|
|
|
|
if (max_hart == NCPU)
|
|
kprintf("All cores up!\n");
|
|
else
|
|
PANIC("Some cores seem to have been enumerated incorrectly!\n");
|
|
|
|
{
|
|
FreeList fl;
|
|
void *mem = buddy_alloc(4096);
|
|
fl_init(&fl, (uintptr_t)mem, 4096, sizeof(int));
|
|
|
|
uint32_t *hello = fl_alloc(&fl);
|
|
|
|
*hello = UINT32_MAX;
|
|
|
|
int a = fl_available(&fl);
|
|
assert_msg(fl_check(&fl) > 0, "FreeList checking failed, might be corrupt.");
|
|
kprintf("Available: %d\n", a);
|
|
kprintf("Size: %d\n", fl.size);
|
|
|
|
buddy_free(mem);
|
|
}
|
|
|
|
kprintf("To exit qemu, press CTRL+a followed by x\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)
|
|
}
|