#include #include #include #include /* QEMU memory maps a UART device here. */ #define UART_BASE ((volatile char *)0x10000000) /** Send a single character to the UART device */ void uart_putc(char c) { *UART_BASE = c; } /** Send a **NULL TERMINATED** string to the UART device */ void uart_puts(const char *s) { while (*s) uart_putc(*s++); } /** * 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 */ struct spinlock sl = {0}; volatile int greeted = 0; /* This is where entry.S drops us of. All cores land here */ void start() { u64 a = r_mhartid(); acquire(&sl); if (!greeted) { uart_puts("Hello Neptune!\n"); greeted = 1; } uart_puts("Hart number: "); uart_putc(a + '0'); uart_putc('\n'); release(&sl); /* Here we will do a bunch of initialization steps */ // We should not arrive here, but if we do, hang in a while on wfi. while (1) __asm__ volatile("wfi"); // (Wait For Interrupt) }