diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/fbos.ld.S | 5 | ||||
| -rw-r--r-- | kernel/head.S | 17 | ||||
| -rw-r--r-- | kernel/main.c | 11 | ||||
| -rw-r--r-- | kernel/printk.c | 15 |
4 files changed, 46 insertions, 2 deletions
diff --git a/kernel/fbos.ld.S b/kernel/fbos.ld.S index 160a5cb..3bda55b 100644 --- a/kernel/fbos.ld.S +++ b/kernel/fbos.ld.S @@ -41,13 +41,16 @@ SECTIONS { .data : { *(.data) } - . = ALIGN(8); .rodata : { *(.rodata) } + . = ALIGN(8); + .sdata : { + *(.sdata*) + } . = ALIGN(8); .bss : { diff --git a/kernel/head.S b/kernel/head.S index 74f83d8..b175b89 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -63,6 +63,23 @@ _start_kernel: // Flush the instruction cache fence.i + // Run the hart lottery. If this is not the first time that it happens, then + // stall this hart forever: on this simple kernel we only want one hart + // available to avoid SMP shenanigans. See explanation on fbos/init.h. + la a3, hart_lottery + li a2, 1 + amoadd.w a3, a2, (a3) + beqz a3, .Lhart_proceed +.Lhart_wait: + wfi + j .Lhart_wait + +.Lhart_proceed: + // Store the hart id as we will tamper with the 'a0' register later when + // performing the call to `start_kernel`. + la a3, hart_id + sw a0, 0(a3) + // Reset all registers except ra, a0, a1. li sp, 0 li gp, 0 diff --git a/kernel/main.c b/kernel/main.c index a2e4d13..822d638 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -5,6 +5,12 @@ #include <fbos/string.h> #include <fbos/dt.h> +/* + * Data related to harts and set by kernel/head.S. Defined in fbos/init.h. + */ +atomic32_t hart_lottery __section(".sdata"); +uint32_t hart_id; + // Stack to be used by our processes, which is initialized in head.S. // "Blasphemy!" I hear you say. "How dare you use the same stack for kernel and // user space?" It's not like this is some sort of utopian system in which @@ -52,6 +58,11 @@ __noreturn __kernel void start_kernel(void *dtb) write("\n", 1); } + // And print the hart ID where this is being run. + printk("Running on Hart ID: "); + print_digit(hart_id); + write("\n", 1); + // At this point everything has already been handled: setup the interrupt // vector and enable the timer to start ticking and scheduling the three // tasks at hand. diff --git a/kernel/printk.c b/kernel/printk.c index bd2bcab..1cc68db 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -3,7 +3,7 @@ #include <fbos/string.h> #include <fbos/sbi.h> -void __noreturn __kernel die(const char *const message) +__kernel __noreturn void die(const char *const message) { if (message) { printk(message); @@ -13,6 +13,19 @@ void __noreturn __kernel die(const char *const message) ; } +__kernel void print_digit(uint32_t digit) +{ + char buffer[2]; + + if (digit > 9) { + die("We cannot print numbers with two or more digits :D\n"); + } + + buffer[0] = '0' + digit; + buffer[1] = '\0'; + write(buffer, 2); +} + __kernel void write(const char *const message, size_t n) { struct sbi_ret ret = sbi_ecall2(DBCN_EXT, DBCN_WRITE, n, (unsigned long)message); |
