#include "opt_console.h"
#include "opt_multiprocessor.h"
#include "opt_riscv_debug.h"
#include <machine/asm.h>
#include "assym.h"
#define BOOT_AP_STACKSIZE 1024
#define NBBY_SHIFT 3
#define PRINTS(string) \
call locore_prints ; \
.asciz string ; \
.align 3 ; \
#if defined(VERBOSE_INIT_RISCV)
#define VPRINTS(string) \
call locore_prints ; \
.asciz string ; \
.align 3 ; \
#define VPRINTX(regno) \
mv a0, regno ; \
call locore_printx
#define VPRINTXNL(regno) \
mv a0, regno ; \
call locore_printxnl
.option norelax
#else
#define VPRINTS(string)
#define VPRINTX(regno)
#define VPRINTXNL(regno)
#endif
#if VM_MIN_KERNEL_ADDRESS != VM_KERNEL_BASE
#error VM_MIN_KERNEL_ADDRESS assumed to match VM_KERNEL_BASE
#endif
ENTRY_NP(start)
csrw sie, zero
csrw sip, zero
li s0, SR_FS
csrc sstatus, s0
mv s10, a0
mv s11, a1
PTR_LA t0, _C_LABEL(bootstk)
mv sp, t0
VPRINTS("\n------------\nNetBSD start\n\n")
VPRINTS("sp: ")
VPRINTXNL(sp)
VPRINTS("pc: ")
auipc a0, 0
VPRINTXNL(a0)
VPRINTS("hart: ")
VPRINTXNL(s10)
VPRINTS("dtb: ")
VPRINTXNL(s11)
PTR_LA t0, start
PTR_L s8, .Lstart
sub s8, s8, t0
PTR_LA s5, _C_LABEL(lwp0uspace)
PTR_LA s6, _C_LABEL(bootstk)
addi sp, sp, -(2 * SZREG)
REG_S zero, 0(sp)
REG_S zero, SZREG(sp)
VPRINTS("vendor: ")
li a7, SBI_EID_BASE
li a6, SBI_FID_BASE_GETMVENDORID
ecall
VPRINTXNL(a1)
#ifdef _LP64
li a0, CPU_VENDOR_THEAD
bne a0, a1, 9f
csrr a1, 0x5c0
li a0, TX_SXSTATUS_MAEE
and a0, a0, a1
beqz a0, .Lpdetab
VPRINTS("extsn: T-Head XMAE\r\n")
li a0, PTE_XMAE_PMA
REG_S a0, 0(sp)
li a0, PTE_XMAE_IO
REG_S a0, SZREG(sp)
j .Lpdetab
9:
#endif
.Lpdetab:
li a1, 0
PTR_LA s2, _C_LABEL(l1_pte)
mv s4, s2
#ifdef _LP64
PTR_LA s3, _C_LABEL(l2_pte)
mv s4, s3
#ifdef notyet
PTR_LA s4, _C_LABEL(l3_pte)
#endif
#endif
PTR_LA s7, _C_LABEL(mmutables_end)
VPRINTS("l1: ")
VPRINTXNL(s2)
#ifdef _LP64
VPRINTS("l2: ")
VPRINTXNL(s3)
#endif
VPRINTS("uspace: ")
VPRINTXNL(s5)
VPRINTS("bootstk: ")
VPRINTXNL(s6)
VPRINTS("vtopdiff:")
VPRINTXNL(s8)
VPRINTS("\n\r")
VPRINTS("bss: ")
PTR_LA a0, _C_LABEL(__bss_start)
VPRINTX(a0)
VPRINTS(" - ")
VPRINTXNL(s7)
VPRINTS("\n\r")
PTR_LA a0, _C_LABEL(__bss_start)
mv a1, s7
call clear_bss
li s7, PTE_V
#ifdef _LP64
VPRINTS("l2pde: ")
srli t0, s2, (PGSHIFT - PTE_PPN_SHIFT)
or t0, t0, s7
#if ((VM_MIN_KERNEL_ADDRESS >> XSEGSHIFT) & (NPDEPG - 1)) * SZREG
li t1, ((VM_MIN_KERNEL_ADDRESS >> XSEGSHIFT) & (NPDEPG - 1)) * SZREG
add t1, t1, s3
REG_S t0, 0(t1)
VPRINTX(t1)
#else
REG_S t0, 0(s3)
VPRINTX(s3)
#endif
VPRINTS(": ")
VPRINTXNL(t0)
VPRINTS("\n\r")
#endif
li t1, ((VM_MIN_KERNEL_ADDRESS >> SEGSHIFT) & (NPDEPG - 1)) * SZREG
add s9, s2, t1
#if PGSHIFT < PTE_PPN_SHIFT
#error Code assumes PGSHIFT is greater than PTE_PPN_SHIFT
#endif
li s5, (VM_KERNEL_SIZE >> SEGSHIFT)
li s6, (NBSEG >> (PGSHIFT - PTE_PPN_SHIFT))
li s7, PTE_KERN | PTE_HARDWIRED | PTE_R | PTE_W | PTE_X
REG_L a0, 0(sp)
or s7, s7, a0
PTR_LA s0, start
srli s0, s0, SEGSHIFT
slli s0, s0, (SEGSHIFT - PGSHIFT + PTE_PPN_SHIFT)
or s0, s0, s7
1:
VPRINTS("kern: ")
VPRINTX(s9)
VPRINTS(": ")
VPRINTXNL(s0)
REG_S s0, 0(s9)
add s0, s0, s6
add s9, s9, SZREG
addi s5, s5, -1
bnez s5, 1b
li t1, ((VM_KERNEL_DTB_BASE >> SEGSHIFT) & (NPDEPG - 1)) * SZREG
add s9, s2, t1
li s7, PTE_KERN | PTE_HARDWIRED | PTE_R | PTE_W
REG_L a0, 0(sp)
or s7, s7, a0
mv s0, s11
srli s0, s0, SEGSHIFT
slli s0, s0, (SEGSHIFT - PGSHIFT + PTE_PPN_SHIFT)
or s0, s0, s7
VPRINTS("dtb: ")
VPRINTX(s9)
VPRINTS(": ")
VPRINTXNL(s0)
REG_S s0, 0(s9)
#ifdef CONSADDR
li s7, PTE_KERN | PTE_HARDWIRED | PTE_R | PTE_W
REG_L a0, SZREG(sp)
or s7, s7, a0
li t1, ((VM_KERNEL_IO_BASE >> SEGSHIFT) & (NPDEPG - 1)) * SZREG
add s9, s2, t1
PTR_L t0, .Lconsaddr
mv s0, t0
srli s0, s0, SEGSHIFT
slli s0, s0, (SEGSHIFT - PGSHIFT + PTE_PPN_SHIFT)
or s0, s0, s7
VPRINTS("cons: ")
VPRINTX(s9)
VPRINTS(": ")
VPRINTXNL(s0)
REG_S s0, 0(s9)
#endif
addi sp, sp, (2 * SZREG)
li a0, 'P'
call _C_LABEL(uartputc)
PTR_LA t0, vstart
add t0, t0, s8
csrw stvec, t0
srli t1, s4, PGSHIFT
#ifdef _LP64
li t0, SATP_MODE_SV39
#else
li t0, SATP_MODE_SV32
#endif
or t0, t0, t1
sfence.vma
csrw satp, t0
.align 2
.global vstart
vstart:
csrw sscratch, zero
#ifdef CONSADDR
add sp, sp, s8
#endif
li a0, 'M'
call _C_LABEL(uartputc)
li a0, '\n'
call _C_LABEL(uartputc)
li a0, '\r'
call _C_LABEL(uartputc)
PTR_LA tp, _C_LABEL(lwp0)
PTR_LA a0, _C_LABEL(cpu_exception_handler)
csrw stvec, a0
PTR_LA t0, bootstk
PTR_S t0, L_PCB(tp)
addi sp, t0, -TF_LEN
PTR_S sp, L_MD_UTF(tp)
PTR_LA t1, _C_LABEL(kernel_pmap_store)
add t2, s4, s8
srli t3, s4, PGSHIFT
PTR_S t2, PM_PDETAB(t1)
PTR_S t3, PM_MD_PPN(t1)
PTR_LA t0, _C_LABEL(kern_vtopdiff)
PTR_S s8, 0(t0)
#if notyet
mv a0, s11
call _C_LABEL(init_mmu)
#endif
li t0, VM_MIN_KERNEL_ADDRESS + VM_KERNEL_SIZE
li t1, NBSEG - 1
and t1, s11, t1
or t0, t0, t1
.option push
.option norelax
lla gp, __global_pointer$
.option pop
mv a0, s10
mv a1, s11
li s0, 0
call _C_LABEL(init_riscv)
tail _C_LABEL(main)
END(start)
#if defined(MULTIPROCESSOR)
ENTRY(cpu_mpstart)
mv s10, a0
mv s11, a1
li t1, BOOT_AP_STACKSIZE
mul t1, s11, t1
PTR_LA t0, _C_LABEL(bootstk)
add sp, t0, t1
PTR_LA t0, start
PTR_L s8, .Lstart
sub s8, s8, t0
#ifdef _LP64
PTR_LA s4, _C_LABEL(l2_pte)
#else
PTR_LA s4, _C_LABEL(l1_pte)
#endif
PTR_LA t0, vmpstart
add t0, t0, s8
csrw stvec, t0
srli t1, s4, PGSHIFT
#ifdef _LP64
li t0, SATP_MODE_SV39
#else
li t0, SATP_MODE_SV32
#endif
or t0, t0, t1
sfence.vma
csrw satp, t0
.align 2
.global vmpstart
vmpstart:
csrw sscratch, zero
.option push
.option norelax
lla gp, __global_pointer$
.option pop
add sp, sp, s8
PTR_LA a0, _C_LABEL(ipi_handler)
csrw stvec, a0
csrsi sie, SIE_SSIE
csrsi sstatus, SR_SIE
li tp, 0
mv a0, s11
call _C_LABEL(cpu_init_secondary_processor)
li t3, 1
andi t0, s11, (1U << (LONG_SCALESHIFT + NBBY_SHIFT)) - 1
sll t3, t3, t0
PTR_LA t0, _C_LABEL(riscv_cpu_mbox)
srli t1, s11, LONG_SCALESHIFT + NBBY_SHIFT
slli t1, t1, LONG_SCALESHIFT
add t4, t0, t1
1:
fence rw, r
LONG_L t0, 0(t4)
and t0, t0, t3
bne t0, zero, 9f
wfi
j 1b
9:
PTR_LA a0, _C_LABEL(cpu_exception_handler)
csrw stvec, a0
li t0, CI_SIZE
mul t0, s11, t0
PTR_LA t1, _C_LABEL(cpu_info_store)
add a0, t0, t1
PTR_L tp, CI_IDLELWP(a0)
PTR_S tp, CI_CURLWP(a0)
PTR_L t2, L_PCB(tp)
li t3, UPAGES * PAGE_SIZE
add t2, t2, t3
addi sp, t2, -TF_LEN
li s0, 0
PTR_L a0, L_CPU(tp)
mv a1, s11
call _C_LABEL(cpu_hatch)
li s0, 0
tail idle_loop
END(cpu_mpstart)
toomanyharts:
PRINTS("too many harts, or hart id doesn't exist in cpu_hart[]\n")
1: wfi
j 1b
.align 2
ipi_handler:
csrrw tp, sscratch, tp
bnez tp, 1f
csrr tp, scause
bgez tp, 2f
csrw sip, zero
csrrw tp, sscratch, zero
sret
1:
wfi
j 1b
2:
wfi
j 2b
#endif
.align 3
.Lstart:
#ifdef _LP64
.quad start
#else
.word start
#endif
#ifdef CONSADDR
.align 3
.Lconsaddr:
#ifdef _LP64
.quad CONSADDR
#else
.word CONSADDR
#endif
#endif
ENTRY_NP(uartputc)
#ifdef EARLYCONS
tail ___CONCAT(EARLYCONS, _platform_early_putchar)
#else
#define SBI_LEGACY_CONSOLE_PUTCHAR 1
li a7, SBI_LEGACY_CONSOLE_PUTCHAR
ecall
ret
#endif
END(uartputc)
ENTRY_NP(uartgetc)
#ifdef EARLYCONS
li a0, -1
#else
#define SBI_LEGACY_CONSOLE_GETCHAR 2
li a7, SBI_LEGACY_CONSOLE_GETCHAR
ecall
ret
#endif
ENTRY_NP(clear_bss)
bgeu a0, a1, 1f
2:
sb zero, 0(a0)
addi a0, a0, 1
bne a1, a0, 2b
1:
ret
END(clear_bss)
.globl _C_LABEL(cpu_Debugger_insn)
.globl _C_LABEL(cpu_Debugger_ret)
ENTRY_NP(cpu_Debugger)
cpu_Debugger_insn:
ebreak
cpu_Debugger_ret:
ret
END(cpu_Debugger)
ENTRY_NP(locore_prints)
addi sp, sp, -(SZREG * 2)
REG_S s0, (0 * SZREG)(sp)
mv s0, ra
1:
lbu a0, 0(s0)
beqz a0, 2f
call uartputc
addi s0, s0, 1
j 1b
2:
addi s0, s0, 8
andi ra, s0, -8
REG_L s0, (0 * SZREG)(sp)
addi sp, sp, (SZREG * 2)
ret
END(locore_prints)
#if defined(VERBOSE_INIT_RISCV)
ENTRY_NP(locore_printx)
addi sp, sp, -(SZREG * 4)
REG_S s0, (0 * SZREG)(sp)
REG_S s1, (1 * SZREG)(sp)
REG_S s2, (2 * SZREG)(sp)
REG_S ra, (3 * SZREG)(sp)
mv s1, a0
li s2, 10
li a0, '0'
call uartputc
li a0, 'x'
call uartputc
li s0, (SZREG * 8)
1:
addi s0, s0, -4
srl a0, s1, s0
andi a0, a0, 0xf
bltu a0, s2, 2f
addi a0, a0, ('a' - '0' - 10)
2: addi a0, a0, '0'
call uartputc
beqz s0, 3f
and a0, s0, (16 - 1)
bnez a0, 1b
li a0, '_'
call uartputc
j 1b
3:
REG_L s0, (0 * SZREG)(sp)
REG_L s1, (1 * SZREG)(sp)
REG_L s2, (2 * SZREG)(sp)
REG_L ra, (3 * SZREG)(sp)
addi sp, sp, (SZREG * 4)
ret
END(locore_printx)
ENTRY_NP(locore_printxnl)
addi sp, sp, -(SZREG * 2)
REG_S ra, (1 * SZREG)(sp)
call locore_printx
li a0, '\n'
call uartputc
li a0, '\r'
call uartputc
REG_L ra, (1 * SZREG)(sp)
addi sp, sp, (SZREG * 2)
ret
END(locore_printxnl)
#endif
.data
.align 2
hart_boot:
.word 0
.align PGSHIFT
.global _C_LABEL(lwp0uspace)
_C_LABEL(lwp0uspace):
.space UPAGES * PAGE_SIZE
bootstk:
#ifdef MULTIPROCESSOR
.space BOOT_AP_STACKSIZE * (MAXCPUS - 1)
#endif
.align PGSHIFT
mmutables_start:
bootstrap_pde:
.global _C_LABEL(bootstrap_pde)
#ifdef _LP64
.global _C_LABEL(l2_pte)
l2_pte:
.space PAGE_SIZE
#endif
.global _C_LABEL(l1_pte)
l1_pte:
.space PAGE_SIZE
mmutables_end: