base-hw: RISC-V BBL
The Berkley Boot Loader handles kernel loading and machine mode
This commit is contained in:
parent
4cbfed11ee
commit
6c95eb9aff
|
@ -12,7 +12,7 @@ SRC_CC += spec/riscv/kernel/cpu.cc
|
||||||
SRC_CC += spec/riscv/platform_support.cc
|
SRC_CC += spec/riscv/platform_support.cc
|
||||||
|
|
||||||
#add assembly sources
|
#add assembly sources
|
||||||
SRC_S += spec/riscv/mode_transition.s
|
SRC_S += $(REP_DIR)/src/bootstrap/spec/riscv/exception_vector.s
|
||||||
SRC_S += spec/riscv/crt0.s
|
SRC_S += spec/riscv/crt0.s
|
||||||
|
|
||||||
# include less specific configuration
|
# include less specific configuration
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
65cc50461e5e1c4d89f8e41dce69362023f445d7
|
|
@ -0,0 +1,8 @@
|
||||||
|
LICENSE := BSD-3-Clause
|
||||||
|
VERSION := git
|
||||||
|
DOWNLOADS := bbl.git
|
||||||
|
|
||||||
|
URL(bbl) = https://github.com/ssumpf/bbl-lite.git
|
||||||
|
REV(bbl) = b24944dde265016ff9b3c8608fe5cc24994e360a
|
||||||
|
DIR(bbl) = src/lib/bbl
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _ERRNO_H_
|
||||||
|
#define _ERRNO_H_
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ENOSYS = 38,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _ERRNO_H_ */
|
|
@ -0,0 +1,9 @@
|
||||||
|
.section ".payload","a",@progbits
|
||||||
|
.align 3
|
||||||
|
|
||||||
|
.globl _payload_start, _payload_end
|
||||||
|
_payload_start:
|
||||||
|
#ifdef BBL_PAYLOAD
|
||||||
|
.incbin BBL_PAYLOAD
|
||||||
|
#endif
|
||||||
|
_payload_end:
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _LIMITS_H_
|
||||||
|
#define _LIMITS_H_
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ULONG_MAX = ~0UL
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _LIMITS_H_ */
|
|
@ -0,0 +1,7 @@
|
||||||
|
.section ".payload","a",@progbits
|
||||||
|
.align 3
|
||||||
|
|
||||||
|
.globl _payload_start, _payload_end
|
||||||
|
_payload_start:
|
||||||
|
.incbin BBL_PAYLOAD
|
||||||
|
_payload_end:
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef _STDINT_H_
|
||||||
|
#define _STDINT_H_
|
||||||
|
|
||||||
|
typedef unsigned long uintptr_t;
|
||||||
|
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned uint32_t;
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
typedef signed long long int64_t;
|
||||||
|
|
||||||
|
typedef signed long ssize_t;
|
||||||
|
typedef unsigned long size_t;
|
||||||
|
|
||||||
|
#endif /* _STDINT_H_ */
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef _STDIO_H_
|
||||||
|
#define _STDIO_H_
|
||||||
|
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
|
||||||
|
#endif /* _STDIO_H_ */
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _STRING_H_
|
||||||
|
#define _STRING_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void *memset(void *s, int c, size_t n);
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n);
|
||||||
|
|
||||||
|
#endif /* _STRING_H_ */
|
|
@ -0,0 +1,33 @@
|
||||||
|
TARGET = bbl
|
||||||
|
REQUIRES = riscv
|
||||||
|
|
||||||
|
SRC_C = bbl.c \
|
||||||
|
configstring.c \
|
||||||
|
kernel_elf.c \
|
||||||
|
logo.c \
|
||||||
|
mtrap.c \
|
||||||
|
minit.c \
|
||||||
|
sbi_impl.c \
|
||||||
|
snprintf.c \
|
||||||
|
string.c \
|
||||||
|
mentry.S \
|
||||||
|
sbi_entry.S \
|
||||||
|
sbi.S \
|
||||||
|
image.S
|
||||||
|
|
||||||
|
IMAGE_ELF ?= $(PRG_DIR)/dummy
|
||||||
|
|
||||||
|
INC_DIR += $(PRG_DIR)
|
||||||
|
|
||||||
|
CC_OPT_PIC =
|
||||||
|
CC_C_OPT += -mcmodel=medany
|
||||||
|
CC_OPT_image += -DBBL_PAYLOAD=\"$(IMAGE_ELF)\"
|
||||||
|
|
||||||
|
LD_TEXT_ADDR = 0x80000000
|
||||||
|
|
||||||
|
CONTRIB = $(call select_from_ports,bbl)/src/lib/bbl/bbl
|
||||||
|
|
||||||
|
LD_SCRIPT_STATIC = $(CONTRIB)/bbl.lds
|
||||||
|
|
||||||
|
vpath %.c $(CONTRIB)
|
||||||
|
vpath %.S $(CONTRIB)
|
|
@ -34,7 +34,7 @@ addi a0, a0, 8
|
||||||
bne a0, a1, 1b
|
bne a0, a1, 1b
|
||||||
|
|
||||||
la sp, _stack_area_start
|
la sp, _stack_area_start
|
||||||
la a0, STACK_SIZE
|
li a0, STACK_SIZE
|
||||||
ld a0, (a0)
|
ld a0, (a0)
|
||||||
add sp, sp, a0
|
add sp, sp, a0
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,13 @@
|
||||||
|
|
||||||
.set CALL_PUT_CHAR, 0x100
|
.set CALL_PUT_CHAR, 0x100
|
||||||
.set CALL_SET_SYS_TIMER, 0x101
|
.set CALL_SET_SYS_TIMER, 0x101
|
||||||
.set CALL_IS_USER_MODE, 0x102
|
.set CALL_GET_SYS_TIMER, 0x102
|
||||||
|
|
||||||
.set CPU_IP, 0
|
.set CPU_IP, 0
|
||||||
.set CPU_EXCEPTION, 8
|
.set CPU_EXCEPTION, 8
|
||||||
.set CPU_X1, 2*8
|
.set CPU_X1, 2*8
|
||||||
.set CPU_SP, 3*8
|
.set CPU_SP, 3*8
|
||||||
.set CPU_SASID, 33*8
|
.set CPU_SPTBR, 33*8
|
||||||
.set CPU_SPTBR, 34*8
|
|
||||||
|
|
||||||
|
|
||||||
# From encoding.h (riscv-opcode)
|
# From encoding.h (riscv-opcode)
|
||||||
|
@ -120,21 +119,20 @@
|
||||||
# If irq from supervisor and MSTATUS.IE1 is not set,
|
# If irq from supervisor and MSTATUS.IE1 is not set,
|
||||||
# then bail out using 'eret'
|
# then bail out using 'eret'
|
||||||
#
|
#
|
||||||
.if \mode == SUPERVISOR_MODE
|
.if \mode == SUPERVISOR_MODE
|
||||||
csrr t1, mstatus
|
csrr t1, mstatus
|
||||||
and t0, t1, MSTATUS_IE1
|
and t0, t1, MSTATUS_IE1
|
||||||
bne zero, t0, 1f
|
bne zero, t0, 1f
|
||||||
|
|
||||||
# So, IE1 is not set.
|
# So, IE1 is not set.
|
||||||
_restore_scratch_registers \mode
|
_restore_scratch_registers \mode
|
||||||
eret
|
mret
|
||||||
|
.endif
|
||||||
.endif
|
|
||||||
|
|
||||||
1:
|
1:
|
||||||
# should cause a interrupt trap in supervisor mode
|
# should cause a interrupt trap in supervisor mode
|
||||||
_restore_scratch_registers \mode
|
_restore_scratch_registers \mode
|
||||||
mrts
|
# mrts
|
||||||
2:
|
2:
|
||||||
# If interrupt source is IRQ HOST ....
|
# If interrupt source is IRQ HOST ....
|
||||||
li t1, IRQ_HOST * 2
|
li t1, IRQ_HOST * 2
|
||||||
|
@ -143,7 +141,7 @@
|
||||||
3:
|
3:
|
||||||
# Empty mfromhost
|
# Empty mfromhost
|
||||||
li t0, 0
|
li t0, 0
|
||||||
csrrw t0, mfromhost, t0
|
#csrrw t0, mfromhost, t0
|
||||||
bne zero,t0, 3b
|
bne zero,t0, 3b
|
||||||
j 9f
|
j 9f
|
||||||
|
|
||||||
|
@ -153,7 +151,7 @@
|
||||||
9:
|
9:
|
||||||
#******** IRQ OUT *********
|
#******** IRQ OUT *********
|
||||||
_restore_scratch_registers \mode
|
_restore_scratch_registers \mode
|
||||||
eret
|
mret
|
||||||
|
|
||||||
11:
|
11:
|
||||||
# Handle trap
|
# Handle trap
|
||||||
|
@ -179,7 +177,7 @@
|
||||||
li t1, CALL_SET_SYS_TIMER
|
li t1, CALL_SET_SYS_TIMER
|
||||||
beq t1, a0, 13f
|
beq t1, a0, 13f
|
||||||
|
|
||||||
li t1, CALL_IS_USER_MODE
|
li t1, CALL_GET_SYS_TIMER
|
||||||
beq t1, a0, 14f
|
beq t1, a0, 14f
|
||||||
|
|
||||||
# else, unknown ecall number
|
# else, unknown ecall number
|
||||||
|
@ -187,17 +185,17 @@
|
||||||
# Assume that Genode (supervisor trap handler)
|
# Assume that Genode (supervisor trap handler)
|
||||||
# knows what to do then.
|
# knows what to do then.
|
||||||
_restore_scratch_registers \mode
|
_restore_scratch_registers \mode
|
||||||
mrts
|
# mrts
|
||||||
.endif
|
.endif
|
||||||
j 15f
|
j 15f
|
||||||
|
|
||||||
12:
|
12:
|
||||||
# output character but first wait until mtohost reads 0 atomically
|
# output character but first wait until mtohost reads 0 atomically
|
||||||
# to make sure any previous character is gone..
|
# to make sure any previous character is gone..
|
||||||
csrr t1, mtohost
|
#csrr t1, mtohost
|
||||||
bne zero, t1, 12b
|
bne zero, t1, 12b
|
||||||
|
|
||||||
csrw mtohost, a1
|
#csrw mtohost, a1
|
||||||
j 15f
|
j 15f
|
||||||
|
|
||||||
13:
|
13:
|
||||||
|
@ -208,7 +206,7 @@
|
||||||
csrc mip, t0
|
csrc mip, t0
|
||||||
|
|
||||||
# Set system timer
|
# Set system timer
|
||||||
csrw mtimecmp, a1
|
#csrw mtimecmp, a1
|
||||||
|
|
||||||
# enable timer interrupt in M-mode
|
# enable timer interrupt in M-mode
|
||||||
li t0, MIP_MTIP
|
li t0, MIP_MTIP
|
||||||
|
@ -217,17 +215,16 @@
|
||||||
j 15f
|
j 15f
|
||||||
|
|
||||||
14:
|
14:
|
||||||
mv a0, x0
|
.if \mode == SUPERVISOR_MODE
|
||||||
.if \mode == USER_MODE
|
#csrr a0, mtime
|
||||||
li a0, 1
|
|
||||||
.endif
|
.endif
|
||||||
j 15f
|
j 15f
|
||||||
|
|
||||||
15:
|
15:
|
||||||
#******* ECALL OUT *********
|
#******* ECALL OUT *********
|
||||||
# Empty mfromhost
|
# Empty mfromhost
|
||||||
li t0, 0
|
li t0, 0
|
||||||
csrrw t0, mfromhost, t0
|
#csrrw t0, mfromhost, t0
|
||||||
bne zero,t0, 14b
|
bne zero,t0, 14b
|
||||||
|
|
||||||
# advance epc
|
# advance epc
|
||||||
|
@ -236,7 +233,7 @@
|
||||||
csrw mepc, t0
|
csrw mepc, t0
|
||||||
|
|
||||||
_restore_scratch_registers \mode
|
_restore_scratch_registers \mode
|
||||||
eret
|
mret
|
||||||
19:
|
19:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ -278,7 +275,7 @@ user_trap:
|
||||||
_save_scratch_registers USER_MODE
|
_save_scratch_registers USER_MODE
|
||||||
_handle_trap USER_MODE
|
_handle_trap USER_MODE
|
||||||
_restore_scratch_registers USER_MODE
|
_restore_scratch_registers USER_MODE
|
||||||
mrts
|
# mrts
|
||||||
|
|
||||||
supervisor_trap:
|
supervisor_trap:
|
||||||
|
|
||||||
|
@ -340,15 +337,11 @@ _mt_kernel_entry_pic:
|
||||||
csrrw x31, sscratch, x31
|
csrrw x31, sscratch, x31
|
||||||
addi x31, x31, 8
|
addi x31, x31, 8
|
||||||
|
|
||||||
# save x29, x30 in master
|
# save x30 in master
|
||||||
sd x29, CPU_X1 + 8 * 28(x31)
|
sd x30, CPU_X1 + 8 * 28(x31)
|
||||||
sd x30, CPU_X1 + 8 * 29(x31)
|
|
||||||
|
|
||||||
# load kernel page table
|
# load kernel page table
|
||||||
ld x29, CPU_SASID(x31)
|
|
||||||
ld x30, CPU_SPTBR(x31)
|
ld x30, CPU_SPTBR(x31)
|
||||||
|
|
||||||
csrw sasid, x29
|
|
||||||
csrw sptbr, x30
|
csrw sptbr, x30
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -421,11 +414,9 @@ _mt_user_entry_pic:
|
||||||
.endr
|
.endr
|
||||||
|
|
||||||
# switch page table
|
# switch page table
|
||||||
ld x31, CPU_SASID(x30)
|
ld x31, CPU_SPTBR(x30)
|
||||||
ld x30, CPU_SPTBR(x30)
|
|
||||||
|
|
||||||
csrw sasid, x31
|
csrw sptbr, x31
|
||||||
csrw sptbr, x30
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# FIXME
|
# FIXME
|
||||||
|
@ -440,7 +431,7 @@ _mt_user_entry_pic:
|
||||||
ld x\reg, CPU_X1 + 8 * (\reg - 1)(x29)
|
ld x\reg, CPU_X1 + 8 * (\reg - 1)(x29)
|
||||||
.endr
|
.endr
|
||||||
|
|
||||||
eret
|
sret
|
||||||
|
|
||||||
# end of the mode transition code
|
# end of the mode transition code
|
||||||
.global _mt_end
|
.global _mt_end
|
||||||
|
|
|
@ -29,32 +29,40 @@ void Bootstrap::Platform::enable_mmu()
|
||||||
SUPERVISOR = 1,
|
SUPERVISOR = 1,
|
||||||
Sv39 = 9,
|
Sv39 = 9,
|
||||||
};
|
};
|
||||||
struct Ie : Bitfield<0, 1> { };
|
struct Uie : Bitfield<0, 1> { };
|
||||||
struct Priv : Bitfield<1, 2> { };
|
struct Sie : Bitfield<1, 1> { };
|
||||||
struct Ie1 : Bitfield<3, 1> { };
|
struct Upie : Bitfield<4, 1> { };
|
||||||
struct Priv1 : Bitfield<4, 2> { };
|
struct Spie : Bitfield<5, 1> { };
|
||||||
struct Fs : Bitfield<12, 2> { enum { INITIAL = 1 }; };
|
struct Spp : Bitfield<8, 1> { };
|
||||||
struct Vm : Bitfield<17, 5> { };
|
struct Mpp : Bitfield<11, 2> { };
|
||||||
|
|
||||||
|
|
||||||
|
struct Fs : Bitfield<13, 2> { enum { INITIAL = 1 }; };
|
||||||
|
struct Vm : Bitfield<24, 5> { };
|
||||||
};
|
};
|
||||||
|
|
||||||
/* read status register */
|
/* read status register */
|
||||||
Mstatus::access_t mstatus = 0;
|
Mstatus::access_t mstatus = 0;
|
||||||
|
|
||||||
Mstatus::Vm::set(mstatus, Mstatus::Sv39); /* enable Sv39 paging */
|
Mstatus::Vm::set(mstatus, Mstatus::Sv39); /* enable Sv39 paging */
|
||||||
Mstatus::Fs::set(mstatus, Mstatus::Fs::INITIAL); /* enable FPU */
|
Mstatus::Fs::set(mstatus, Mstatus::Fs::INITIAL); /* enable FPU */
|
||||||
Mstatus::Ie1::set(mstatus, 1); /* user mode interrupt */
|
Mstatus::Upie::set(mstatus, 1); /* user mode interrupt */
|
||||||
Mstatus::Priv1::set(mstatus, Mstatus::USER); /* set user mode */
|
Mstatus::Spp::set(mstatus, Mstatus::USER); /* set user mode */
|
||||||
Mstatus::Ie::set(mstatus, 0); /* disable interrupts */
|
Mstatus::Spie::set(mstatus, 0); /* disable interrupts */
|
||||||
Mstatus::Priv::set(mstatus, Mstatus::SUPERVISOR); /* set supervisor mode */
|
Mstatus::Mpp::set(mstatus, Mstatus::SUPERVISOR); /* set supervisor mode */
|
||||||
|
|
||||||
asm volatile ("csrw sasid, %0\n" /* address space id */
|
asm volatile (
|
||||||
"csrw sptbr, %1\n" /* set page table */
|
"la t0, 1f\n"
|
||||||
"csrw mstatus, %2\n" /* change mode */
|
"csrw sepc, t0\n"
|
||||||
|
"csrw sptbr, %0\n" /* set asid | page table */
|
||||||
|
"csrw mstatus, %1\n" /* change mode */
|
||||||
|
"mret \n" /* supverisor mode, jump to 1f */
|
||||||
|
"rdtime t0 \n"
|
||||||
|
"1: \n"
|
||||||
:
|
:
|
||||||
: "r" (0/*core_pd.asid*/),
|
: "r" ((addr_t)core_pd->table_base >> 12),
|
||||||
"r" (core_pd->table_base),
|
|
||||||
"r" (mstatus)
|
"r" (mstatus)
|
||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/stdint.h>
|
#include <base/stdint.h>
|
||||||
#include <cpu/cpu_state.h>
|
#include <cpu/cpu_state.h>
|
||||||
|
#include <util/register.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
|
@ -42,23 +44,28 @@ class Genode::Cpu
|
||||||
*/
|
*/
|
||||||
struct Context : Cpu_state
|
struct Context : Cpu_state
|
||||||
{
|
{
|
||||||
addr_t sasid = 0;
|
struct Sptbr : Register<64>
|
||||||
addr_t sptbr = 0; /* supervisor page table register */
|
{
|
||||||
|
struct Ppn : Bitfield<0, 38> { };
|
||||||
|
struct Asid : Bitfield<38, 26> { };
|
||||||
|
};
|
||||||
|
|
||||||
|
Sptbr::access_t sptbr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return base of assigned translation table
|
* Return base of assigned translation table
|
||||||
*/
|
*/
|
||||||
addr_t translation_table() const { return sptbr; }
|
addr_t translation_table() const { return Sptbr::Ppn::get(sptbr) << 12; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign translation-table base 'table'
|
* Assign translation-table base 'table'
|
||||||
*/
|
*/
|
||||||
void translation_table(addr_t const table) { sptbr = table; }
|
void translation_table(addr_t const table) { Sptbr::Ppn::set(sptbr, table >> 12); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign protection domain
|
* Assign protection domain
|
||||||
*/
|
*/
|
||||||
void protection_domain(Genode::uint8_t const id) { sasid = id; }
|
void protection_domain(Genode::uint8_t const id) { Sptbr::Asid::set(sptbr, id); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Pd
|
struct Pd
|
||||||
|
@ -120,10 +127,10 @@ class Genode::Cpu
|
||||||
*/
|
*/
|
||||||
static void sfence()
|
static void sfence()
|
||||||
{
|
{
|
||||||
asm volatile ("csrrw t0, sasid, x0\n"
|
/*
|
||||||
"sfence.vm\n"
|
* Note: In core the address space id must be zero
|
||||||
"csrw sasid, t0\n"
|
*/
|
||||||
: : : "t0");
|
asm volatile ("sfence.vm\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Hw {
|
||||||
*/
|
*/
|
||||||
constexpr Call_arg call_id_put_char() { return 0x100; }
|
constexpr Call_arg call_id_put_char() { return 0x100; }
|
||||||
constexpr Call_arg call_id_set_sys_timer() { return 0x101; }
|
constexpr Call_arg call_id_set_sys_timer() { return 0x101; }
|
||||||
constexpr Call_arg call_id_is_user_mode() { return 0x102; }
|
constexpr Call_arg call_id_get_sys_timer() { return 0x102; }
|
||||||
|
|
||||||
inline void put_char(uint64_t c) {
|
inline void put_char(uint64_t c) {
|
||||||
Kernel::call(call_id_put_char(), (Call_arg)c); }
|
Kernel::call(call_id_put_char(), (Call_arg)c); }
|
||||||
|
@ -38,8 +38,8 @@ namespace Hw {
|
||||||
inline void set_sys_timer(addr_t t) {
|
inline void set_sys_timer(addr_t t) {
|
||||||
Kernel::call(call_id_set_sys_timer(), (Call_arg)t); }
|
Kernel::call(call_id_set_sys_timer(), (Call_arg)t); }
|
||||||
|
|
||||||
inline bool is_user_mode() {
|
inline addr_t get_sys_timer() {
|
||||||
return Kernel::call(call_id_is_user_mode()); }
|
return Kernel::call(call_id_get_sys_timer()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _SRC__LIB__HW__SPEC__RISCV__MACHINE_CALL_H_ */
|
#endif /* _SRC__LIB__HW__SPEC__RISCV__MACHINE_CALL_H_ */
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
## Run tool configuration
|
## Run tool configuration
|
||||||
##
|
##
|
||||||
|
|
||||||
RUN_OPT = --include power_on/spike --include log/spike
|
RUN_OPT = --include image/bbl
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
proc run_image {elf_img} {
|
||||||
|
puts "using '$elf_img' as bbl image"
|
||||||
|
|
||||||
|
exec rm -f bbl/image.o
|
||||||
|
exec make IMAGE_ELF=[pwd]/$elf_img bbl
|
||||||
|
}
|
Loading…
Reference in New Issue