# For a quick reference on RISC-V assembly:
#   https://risc-v.guru/instructions/

# Kernel entry point
#
# qemu -kernel loads the kernel at 0x80000000
# and causes each hart (i.e. CPU) to jump there.
# kernel.ld causes the following code to
# be placed at 0x80000000.

.section .text
.global _entry
_entry:
        # Clear all the registers.
        li x1, 0x0
        li x2, 0x0
        li x3, 0x0
        li x4, 0x0
        li x5, 0x0
        li x6, 0x0
        li x7, 0x0
        li x8, 0x0
        li x9, 0x0
        li x10, 0x0
        li x11, 0x0
        li x12, 0x0
        li x13, 0x0
        li x14, 0x0
        li x15, 0x0
        li x16, 0x0
        li x17, 0x0
        li x18, 0x0
        li x19, 0x0
        li x20, 0x0
        li x21, 0x0
        li x22, 0x0
        li x23, 0x0
        li x24, 0x0
        li x25, 0x0
        li x26, 0x0
        li x27, 0x0
        li x28, 0x0
        li x29, 0x0
        li x30, 0x0
        li x31, 0x0

        # set up a stack for C.
        # stack0 is declared in start.c,
        # with a 4096-byte stack per CPU.
        # sp = stack0 + (hartid * 4096)
        la sp, stack0
        li a0, 1024*4 # a0 = 4096

        # Control and Status Register Read
        csrr a1, mhartid # a1 = unique hart (core) id
        addi a1, a1, 1   # a1 += 1
        mul a0, a0, a1   # a0 *= a1, aka a0 = 4096 * (hartid + 1), the base of the stack for this hart
        add sp, sp, a0   # sp += a0, stack pointer is now properly configured

        # jump to start() in start.c
        call start

# Infinite spin loop.
spin:
        j spin