diff --git a/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk index 3e3e0ff06..3015751ca 100644 --- a/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk @@ -3,6 +3,5 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/bootstrap/spec/riscv SRC_CC += bootstrap/spec/riscv/platform.cc SRC_CC += lib/base/riscv/kernel/interface.cc SRC_S += bootstrap/spec/riscv/crt0.s -SRC_S += bootstrap/spec/riscv/exception_vector.s include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk index e62d655b2..46bf63c09 100644 --- a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk @@ -10,9 +10,10 @@ SRC_CC += spec/riscv/kernel/thread.cc SRC_CC += spec/riscv/kernel/pd.cc SRC_CC += spec/riscv/kernel/cpu.cc SRC_CC += spec/riscv/platform_support.cc +SRC_CC += spec/riscv/timer.cc #add assembly sources -SRC_S += $(REP_DIR)/src/bootstrap/spec/riscv/exception_vector.s +SRC_S += spec/riscv/exception_vector.s SRC_S += spec/riscv/crt0.s # include less specific configuration diff --git a/repos/base-hw/src/bootstrap/init.cc b/repos/base-hw/src/bootstrap/init.cc index 8c25f83a1..8269197ef 100644 --- a/repos/base-hw/src/bootstrap/init.cc +++ b/repos/base-hw/src/bootstrap/init.cc @@ -25,7 +25,6 @@ extern "C" void init() __attribute__ ((noreturn)); extern "C" void init() { - Genode::init_log(); Bootstrap::platform().enable_mmu(); Bootstrap::platform().start_core(); } diff --git a/repos/base-hw/src/bootstrap/log.cc b/repos/base-hw/src/bootstrap/log.cc index 18c9be57d..7887fd59d 100644 --- a/repos/base-hw/src/bootstrap/log.cc +++ b/repos/base-hw/src/bootstrap/log.cc @@ -56,5 +56,3 @@ struct Buffer Genode::Log &Genode::Log::log() { return unmanaged_singleton()->log; } - -void Genode::init_log() { }; diff --git a/repos/base-hw/src/bootstrap/spec/riscv/board.h b/repos/base-hw/src/bootstrap/spec/riscv/board.h index 37aeee2a3..a6eabdfc8 100644 --- a/repos/base-hw/src/bootstrap/spec/riscv/board.h +++ b/repos/base-hw/src/bootstrap/spec/riscv/board.h @@ -16,6 +16,7 @@ #include #include +#include namespace Bootstrap { struct Cpu {}; @@ -23,6 +24,9 @@ namespace Bootstrap { } namespace Board { + + using namespace Riscv; + enum { UART_BASE, UART_CLOCK }; struct Serial : Hw::Riscv_uart { Serial(unsigned, unsigned, unsigned) {} }; diff --git a/repos/base-hw/src/bootstrap/spec/riscv/crt0.s b/repos/base-hw/src/bootstrap/spec/riscv/crt0.s index 2688c6c44..23b5ce270 100644 --- a/repos/base-hw/src/bootstrap/spec/riscv/crt0.s +++ b/repos/base-hw/src/bootstrap/spec/riscv/crt0.s @@ -35,13 +35,10 @@ bne a0, a1, 1b la sp, _stack_area_start li a0, STACK_SIZE -ld a0, (a0) add sp, sp, a0 /* save kernel stack pointer in mscratch */ -csrw mscratch, sp - -jal setup_riscv_exception_vector +csrw sscratch, sp jal init 1: j 1b diff --git a/repos/base-hw/src/bootstrap/spec/riscv/exception_vector.s b/repos/base-hw/src/bootstrap/spec/riscv/exception_vector.s deleted file mode 100644 index 6493e341f..000000000 --- a/repos/base-hw/src/bootstrap/spec/riscv/exception_vector.s +++ /dev/null @@ -1,438 +0,0 @@ -/* - * \brief Transition between kernel/userland - * \author Sebastian Sumpf - * \author Mark Vels - * \date 2015-06-22 - */ - -/* - * Copyright (C) 2015-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -.set USER_MODE, 0 -.set SUPERVISOR_MODE, 1 -.set MACHINE_MODE, 3 - -.set CALL_PUT_CHAR, 0x100 -.set CALL_SET_SYS_TIMER, 0x101 -.set CALL_GET_SYS_TIMER, 0x102 - -.set CPU_IP, 0 -.set CPU_EXCEPTION, 8 -.set CPU_X1, 2*8 -.set CPU_SP, 3*8 -.set CPU_SPTBR, 33*8 - - -# From encoding.h (riscv-opcode) -.set MIP_MTIP, 0x00000020 -.set MIP_SSIP, 0x00000002 -.set MIP_HSIP, 0x00000004 -.set MIP_MSIP, 0x00000008 -.set MIP_STIP, 0x00000020 -.set MIP_HTIP, 0x00000040 -.set MIP_MTIP, 0x00000080 -.set MSTATUS_IE, 0x00000001 -.set MSTATUS_PRV, 0x00000006 -.set MSTATUS_IE1, 0x00000008 -.set MSTATUS_PRV1, 0x00000030 -.set MSTATUS_IE2, 0x00000040 -.set MSTATUS_PRV2, 0x00000180 -.set MSTATUS_IE3, 0x00000200 -.set MSTATUS_PRV3, 0x00000C00 -.set MSTATUS_FS, 0x00003000 -.set MSTATUS_XS, 0x0000C000 -.set MSTATUS_MPRV, 0x00010000 -.set MSTATUS_VM, 0x003E0000 -.set MSTATUS64_SD, 0x8000000000000000 - -.set TRAP_ECALL_FROM_USER, 8 -.set TRAP_ECALL_FROM_SUPERVISOR, 9 -.set TRAP_ECALL_FROM_HYPERVISOR, 10 -.set TRAP_ECALL_FROM_MACHINE, 11 - -.set TRAP_INTERRUPT_BITNR, 63 -.set IRQ_SOFT, 0x0 -.set IRQ_TIMER, 0x1 -.set IRQ_HOST, 0x2 -.set IRQ_COP, 0x3 - - - -.macro _save_scratch_registers mode - - .if \mode == USER_MODE - csrrw sp, mscratch, sp - .endif - - addi sp, sp, -24 - sd t0, 0(sp) - sd t1, 8(sp) - sd t2, 16(sp) -.endm - -.macro _restore_scratch_registers mode - ld t0, 0(sp) - ld t1, 8(sp) - ld t2, 16(sp) - addi sp, sp, 24 - - .if \mode == USER_MODE - csrrw sp, mscratch, sp - .endif -.endm - -.macro _handle_trap mode - - csrr t0, mcause - - # If IRQ bit not setup, goto trap handler. - # If an interrupt has occurred, the MSB will be set and - # hence mcause will be negative - # - bgez t0, 11f - - # The bit was not set so we're handling an interrupt - # Valid interrupts are : - # - Software IRQ - 0 - # - Timer IRQ - 1 - # - HOST HTIF - 2 - # - COP - 3 - # - - sll t0, t0, 1 # discard MSB - - # If interrupt source is IRQ TIMER .... - li t1, IRQ_TIMER * 2 - bne t0, t1, 2f - - # Forward handling of timer IRQ to SUPERVISOR - li t0, MIP_MTIP - csrc mip, t0 - csrc mie, t0 - li t1, MIP_STIP - csrs mip, t1 - - # If irq from supervisor and MSTATUS.IE1 is not set, - # then bail out using 'eret' - # - .if \mode == SUPERVISOR_MODE - csrr t1, mstatus - and t0, t1, MSTATUS_IE1 - bne zero, t0, 1f - - # So, IE1 is not set. - _restore_scratch_registers \mode - mret - .endif - -1: - # should cause a interrupt trap in supervisor mode - _restore_scratch_registers \mode -# mrts -2: - # If interrupt source is IRQ HOST .... - li t1, IRQ_HOST * 2 - bne t0, t1, 9f - -3: - # Empty mfromhost - li t0, 0 - #csrrw t0, mfromhost, t0 - bne zero,t0, 3b - j 9f - - # Future implementation check for more interrupt sources - # to handle here..... - -9: - #******** IRQ OUT ********* - _restore_scratch_registers \mode - mret - -11: - # Handle trap - - # check if ecall (8..11): - # 8 : Environment call from U-mode - # 9 : Environment call from S-mode - # 10 : Environment call from H-mode - # 11 : Environment call from M-mode - # - # If not, jump to end of macro. - # - - li t1, TRAP_ECALL_FROM_USER - bltu t0, t1, 19f - li t1, TRAP_ECALL_FROM_MACHINE - bgt t0, t1, 19f - - # Switch on ecall number - li t1, CALL_PUT_CHAR - beq t1, a0, 12f - - li t1, CALL_SET_SYS_TIMER - beq t1, a0, 13f - - li t1, CALL_GET_SYS_TIMER - beq t1, a0, 14f - - # else, unknown ecall number - .if \mode == USER_MODE - # Assume that Genode (supervisor trap handler) - # knows what to do then. - _restore_scratch_registers \mode - # mrts - .endif - j 15f - -12: - # output character but first wait until mtohost reads 0 atomically - # to make sure any previous character is gone.. - #csrr t1, mtohost - bne zero, t1, 12b - - #csrw mtohost, a1 - j 15f - -13: - # Only allow timer fiddling from supervisor mode - .if \mode == SUPERVISOR_MODE - # Clear any pending STIP - li t0, MIP_STIP - csrc mip, t0 - - # Set system timer - #csrw mtimecmp, a1 - - # enable timer interrupt in M-mode - li t0, MIP_MTIP - csrrs t0, mie, t0 - .endif - j 15f - -14: - .if \mode == SUPERVISOR_MODE - #csrr a0, mtime - .endif - j 15f - -15: - #******* ECALL OUT ********* - # Empty mfromhost - li t0, 0 - #csrrw t0, mfromhost, t0 - bne zero,t0, 14b - - # advance epc - csrr t0, mepc - addi t0, t0, 4 - csrw mepc, t0 - - _restore_scratch_registers \mode - mret -19: -.endm - -.section .text - -## - # Page aligned base of mode transition code. - # - # This position independent code switches between a kernel context and a - # user context and thereby between their address spaces. Due to the latter - # it must be mapped executable to the same region in every address space. - # To enable such switching, the kernel context must be stored within this - # region, thus one should map it solely accessable for privileged modes. - # - - - -.p2align 8 -.global _machine_begin -_machine_begin: - -# 0x100 user mode -j user_trap -.space 0x3c -# 0x140 supervisor -j supervisor_trap -.space 0x3c -# 0x180 hypervisor -1: j 1b -.space 0x3c -# 0x1c0 machine -j machine_trap -.space 0x38 -# 0x1fc non-maksable interrupt -1: j 1b - -user_trap: - - _save_scratch_registers USER_MODE - _handle_trap USER_MODE - _restore_scratch_registers USER_MODE -# mrts - -supervisor_trap: - - _save_scratch_registers SUPERVISOR_MODE - _handle_trap SUPERVISOR_MODE - j fault - -machine_trap: - - _save_scratch_registers MACHINE_MODE - _handle_trap MACHINE_MODE - j fault - - -fault:j fault # TODO: handle trap from supervisor or machine mode - -.global _machine_end -_machine_end: - -.p2align 12 -.global _mt_begin -_mt_begin: - -# 0x100 user mode -j _mt_kernel_entry_pic -.space 0x3c -# 0x140 supervisor -1: j 1b -.space 0x3c -# 0x180 hypervisor -1: j 1b -.space 0x3c -# 0x1c0 machine -1: j 1b -.space 0x38 -# 0x1fc non-maksable interrupt -1: j 1b - -/* space for a client context-pointer per CPU */ -.p2align 3 -.global _mt_client_context_ptr -_mt_client_context_ptr: -.space 8 - -/* space for a copy of the kernel context */ -.global _mt_master_context_begin -_mt_master_context_begin: - -/* space must be at least as large as 'Context' */ -.space 35*8 - -.global _mt_master_context_end -_mt_master_context_end: - -.global _mt_kernel_entry_pic -_mt_kernel_entry_pic: - - # master context - csrrw x31, sscratch, x31 - addi x31, x31, 8 - - # save x30 in master - sd x30, CPU_X1 + 8 * 28(x31) - - # load kernel page table - ld x30, CPU_SPTBR(x31) - csrw sptbr, x30 - - # - # FIXME - # A TLB flush. Might be necessary to remove this in the near future again - # because on real hardware we currently get problems without. - # - sfence.vm x0 - - # save x29 - x31 in user context - mv x29, x31 - addi x29, x29, -8 - ld x29, (x29) - - .irp reg,29,30 - ld x30, CPU_X1 + 8 * (\reg - 1)(x31) - sd x30, CPU_X1 + 8 * (\reg - 1)(x29) - .endr - - csrr x30, sscratch /* x31 */ - sd x30, CPU_X1 + 8 * 30(x29) - - # save x1 - x28 - .irp reg,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 - sd x\reg, CPU_X1 + 8 * (\reg - 1)(x29) - .endr - - # trap reason - csrr x30, scause - sd x30, CPU_EXCEPTION(x29) - - # ip - csrr x30, sepc - sd x30, CPU_IP(x29) - - # load kernel stack and ip - ld sp, CPU_SP(x31) - ld x30, CPU_IP(x31) - - # restore scratch - addi x31, x31, -8 - csrw sscratch, x31 - - jalr x30 - - -.global _mt_user_entry_pic -_mt_user_entry_pic: - - # client context pointer - csrr x30, sscratch - ld x30, (x30) - - # set return IP - ld x31, CPU_IP(x30) - csrw sepc, x31 - - # restore x1-x28 - .irp reg,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 - ld x\reg, CPU_X1 + 8 * (\reg - 1)(x30) - .endr - - # save x29, x30, x31 to master context - csrr x29, sscratch - addi x29, x29, 8 # master context - - .irp reg,29,30,31 - ld x31, CPU_X1 + 8 * (\reg - 1)(x30) - sd x31, CPU_X1 + 8 * (\reg - 1)(x29) - .endr - - # switch page table - ld x31, CPU_SPTBR(x30) - - csrw sptbr, x31 - - # - # FIXME - # A TLB flush. Might be necessary to remove this in the near future again - # because on real hardware we currently get problems without. - # - - sfence.vm x0 - - # restore x29 - x31 from master context - .irp reg,31,30,29 - ld x\reg, CPU_X1 + 8 * (\reg - 1)(x29) - .endr - - sret - -# end of the mode transition code -.global _mt_end -_mt_end: diff --git a/repos/base-hw/src/bootstrap/spec/riscv/platform.cc b/repos/base-hw/src/bootstrap/spec/riscv/platform.cc index a41fbadbd..44957b794 100644 --- a/repos/base-hw/src/bootstrap/spec/riscv/platform.cc +++ b/repos/base-hw/src/bootstrap/spec/riscv/platform.cc @@ -11,72 +11,18 @@ * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ - -#include - #include +using namespace Board; + Bootstrap::Platform::Board::Board() -: early_ram_regions(Memory_region { 0, 128 * 1024 * 1024 } ) {} +: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE } ) {} void Bootstrap::Platform::enable_mmu() { - struct Mstatus : Genode::Register<64> - { - enum { - USER = 0, - SUPERVISOR = 1, - Sv39 = 9, - }; - struct Uie : Bitfield<0, 1> { }; - struct Sie : Bitfield<1, 1> { }; - struct Upie : Bitfield<4, 1> { }; - struct Spie : Bitfield<5, 1> { }; - struct Spp : Bitfield<8, 1> { }; - struct Mpp : Bitfield<11, 2> { }; - - - struct Fs : Bitfield<13, 2> { enum { INITIAL = 1 }; }; - struct Vm : Bitfield<24, 5> { }; - }; - - /* read status register */ - Mstatus::access_t mstatus = 0; - - Mstatus::Vm::set(mstatus, Mstatus::Sv39); /* enable Sv39 paging */ - Mstatus::Fs::set(mstatus, Mstatus::Fs::INITIAL); /* enable FPU */ - Mstatus::Upie::set(mstatus, 1); /* user mode interrupt */ - Mstatus::Spp::set(mstatus, Mstatus::USER); /* set user mode */ - Mstatus::Spie::set(mstatus, 0); /* disable interrupts */ - Mstatus::Mpp::set(mstatus, Mstatus::SUPERVISOR); /* set supervisor mode */ - - asm volatile ( - "la t0, 1f\n" - "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" + asm volatile ("csrw sptbr, %0\n" /* set asid | page table */ : - : "r" ((addr_t)core_pd->table_base >> 12), - "r" (mstatus) + : "r" ((addr_t)core_pd->table_base >> 12) : "memory"); } - - -extern int _machine_begin, _machine_end; - -extern "C" void setup_riscv_exception_vector() -{ - using namespace Genode; - - /* retrieve exception vector */ - addr_t vector; - asm volatile ("csrr %0, mtvec\n" : "=r"(vector)); - - /* copy machine mode exception vector */ - memcpy((void *)vector, - &_machine_begin, (addr_t)&_machine_end - (addr_t)&_machine_begin); -} diff --git a/repos/base-hw/src/core/spec/riscv/board.h b/repos/base-hw/src/core/spec/riscv/board.h index a65aa8015..908413fa3 100644 --- a/repos/base-hw/src/core/spec/riscv/board.h +++ b/repos/base-hw/src/core/spec/riscv/board.h @@ -14,6 +14,8 @@ #ifndef _CORE__SPEC__RISCV__BOARD_H_ #define _CORE__SPEC__RISCV__BOARD_H_ +#include + namespace Board { enum { UART_BASE, UART_CLOCK }; struct Serial : Hw::Riscv_uart { diff --git a/repos/base-hw/src/core/spec/riscv/exception_vector.s b/repos/base-hw/src/core/spec/riscv/exception_vector.s new file mode 100644 index 000000000..feb0d47e7 --- /dev/null +++ b/repos/base-hw/src/core/spec/riscv/exception_vector.s @@ -0,0 +1,161 @@ +/* + * \brief Transition between kernel/userland + * \author Sebastian Sumpf + * \author Mark Vels + * \date 2015-06-22 + */ + +/* + * Copyright (C) 2015-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +.set CPU_IP, 0 +.set CPU_EXCEPTION, 8 +.set CPU_X1, 2*8 +.set CPU_SP, 3*8 +.set CPU_SPTBR, 33*8 + +.p2align 12 +.global _mt_begin +_mt_begin: + +# 0x100 user mode +j _mt_kernel_entry_pic +.space 0x3c +# 0x140 supervisor +1: j 1b +.space 0x3c +# 0x180 hypervisor +1: j 1b +.space 0x3c +# 0x1c0 machine +1: j 1b +.space 0x38 +# 0x1fc non-maksable interrupt +1: j 1b + +/* space for a client context-pointer per CPU */ +.p2align 3 +.global _mt_client_context_ptr +_mt_client_context_ptr: +.space 8 + +/* space for a copy of the kernel context */ +.global _mt_master_context_begin +_mt_master_context_begin: + +/* space must be at least as large as 'Context' */ +.space 35*8 + +.global _mt_master_context_end +_mt_master_context_end: + +.global _mt_kernel_entry_pic +_mt_kernel_entry_pic: + + # master context + csrrw x31, sscratch, x31 + addi x31, x31, 8 + + # save x30 in master + sd x30, CPU_X1 + 8 * 28(x31) + + # load kernel page table + ld x30, CPU_SPTBR(x31) + csrw sptbr, x30 + + # + # FIXME + # A TLB flush. Might be necessary to remove this in the near future again + # because on real hardware we currently get problems without. + # + sfence.vm x0 + + # save x29 - x31 in user context + mv x29, x31 + addi x29, x29, -8 + ld x29, (x29) + + .irp reg,29,30 + ld x30, CPU_X1 + 8 * (\reg - 1)(x31) + sd x30, CPU_X1 + 8 * (\reg - 1)(x29) + .endr + + csrr x30, sscratch /* x31 */ + sd x30, CPU_X1 + 8 * 30(x29) + + # save x1 - x28 + .irp reg,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 + sd x\reg, CPU_X1 + 8 * (\reg - 1)(x29) + .endr + + # trap reason + csrr x30, scause + sd x30, CPU_EXCEPTION(x29) + + # ip + csrr x30, sepc + sd x30, CPU_IP(x29) + + # load kernel stack and ip + ld sp, CPU_SP(x31) + ld x30, CPU_IP(x31) + + # restore scratch + addi x31, x31, -8 + csrw sscratch, x31 + + jalr x30 + + +.global _mt_user_entry_pic +_mt_user_entry_pic: + + # client context pointer + csrr x30, sscratch + ld x30, (x30) + + # set return IP + ld x31, CPU_IP(x30) + csrw sepc, x31 + + # restore x1-x28 + .irp reg,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 + ld x\reg, CPU_X1 + 8 * (\reg - 1)(x30) + .endr + + # save x29, x30, x31 to master context + csrr x29, sscratch + addi x29, x29, 8 # master context + + .irp reg,29,30,31 + ld x31, CPU_X1 + 8 * (\reg - 1)(x30) + sd x31, CPU_X1 + 8 * (\reg - 1)(x29) + .endr + + # switch page table + ld x31, CPU_SPTBR(x30) + + csrw sptbr, x31 + + # + # FIXME + # A TLB flush. Might be necessary to remove this in the near future again + # because on real hardware we currently get problems without. + # + + sfence.vm x0 + + # restore x29 - x31 from master context + .irp reg,31,30,29 + ld x\reg, CPU_X1 + 8 * (\reg - 1)(x29) + .endr + + sret + +# end of the mode transition code +.global _mt_end +_mt_end: diff --git a/repos/base-hw/src/core/spec/riscv/timer.cc b/repos/base-hw/src/core/spec/riscv/timer.cc index 8a442427f..3193f84a5 100644 --- a/repos/base-hw/src/core/spec/riscv/timer.cc +++ b/repos/base-hw/src/core/spec/riscv/timer.cc @@ -13,7 +13,7 @@ /* Core includes */ #include -#include +#include using namespace Genode; using namespace Kernel; @@ -27,10 +27,10 @@ Timer_driver::Timer_driver(unsigned) } -void Timer::_start_one_shot(time_t const ticks, unsigned const) +void Timer::_start_one_shot(time_t const ticks) { _driver.timeout = _driver.stime() + ticks; - Machine::set_sys_timer(_driver.timeout); + Hw::set_sys_timer(_driver.timeout); } @@ -42,11 +42,11 @@ time_t Timer::us_to_ticks(time_t const us) const { return (us / 1000) * Driver::TICS_PER_MS; } -time_t Timer::_max_value() { +time_t Timer::_max_value() const { return (addr_t)~0; } -time_t Timer::_value(unsigned const) +time_t Timer::_value() { addr_t time = _driver.stime(); return time < _driver.timeout ? _driver.timeout - time : 0; diff --git a/repos/base-hw/src/core/spec/riscv/timer_driver.h b/repos/base-hw/src/core/spec/riscv/timer_driver.h index 035da617b..59f73df76 100644 --- a/repos/base-hw/src/core/spec/riscv/timer_driver.h +++ b/repos/base-hw/src/core/spec/riscv/timer_driver.h @@ -32,11 +32,10 @@ struct Kernel::Timer_driver addr_t timeout = 0; + /* TODO: implement */ addr_t stime() { - Genode::addr_t t; - asm volatile ("csrr %0, stime\n" : "=r"(t)); - return t; + return 0; } Timer_driver(unsigned); diff --git a/repos/base-hw/src/lib/hw/spec/riscv/machine_call.h b/repos/base-hw/src/lib/hw/spec/riscv/machine_call.h index 85aaf46f2..ebef18011 100644 --- a/repos/base-hw/src/lib/hw/spec/riscv/machine_call.h +++ b/repos/base-hw/src/lib/hw/spec/riscv/machine_call.h @@ -28,12 +28,21 @@ namespace Hw { * * Keep in sync with mode_transition.s. */ - constexpr Call_arg call_id_put_char() { return 0x100; } constexpr Call_arg call_id_set_sys_timer() { return 0x101; } constexpr Call_arg call_id_get_sys_timer() { return 0x102; } - inline void put_char(uint64_t c) { - Kernel::call(call_id_put_char(), (Call_arg)c); } + inline void ecall(addr_t call, addr_t arg) + { + asm volatile ("mv a0, %0\n" + "mv a1, %1\n" + "ecall \n" + : : "r"(call), "r"(arg) + : "a0", "a1"); + } + + inline void put_char(addr_t c) { + ecall(Kernel::call_id_print_char(), c); + } inline void set_sys_timer(addr_t t) { Kernel::call(call_id_set_sys_timer(), (Call_arg)t); } diff --git a/repos/base-hw/src/lib/hw/spec/riscv/page_table.h b/repos/base-hw/src/lib/hw/spec/riscv/page_table.h index 0fae1b075..b3c0eec8d 100644 --- a/repos/base-hw/src/lib/hw/spec/riscv/page_table.h +++ b/repos/base-hw/src/lib/hw/spec/riscv/page_table.h @@ -53,48 +53,47 @@ namespace Sv39 struct Sv39::Descriptor : Register<64> { enum Descriptor_type { INVALID, TABLE, BLOCK }; - struct V : Bitfield<0, 1> { }; /* present */ - struct Type : Bitfield<1, 4> /* type and access rights */ + struct V : Bitfield<0, 1> { }; /* present */ + struct R : Bitfield<1, 1> { }; /* read */ + struct W : Bitfield<2, 1> { }; /* write */ + struct X : Bitfield<3, 1> { }; /* executable */ + struct U : Bitfield<4, 1> { }; /* user */ + struct G : Bitfield<5, 1> { }; /* global */ + + struct Perm : Bitfield<0, 5> { }; + struct Type : Bitfield<1, 3> { enum { - POINTER = 0, - POINTER_GLOBAL = 1, - USER = 4, /* R + 0, RW + 1, RX + 2, RWX + 3 */ - KERNEL = 8, - GLOBAL = 12, + POINTER = 0 }; }; struct Ppn : Bitfield<10, 38> { }; /* physical address 10 bit aligned */ struct Base : Bitfield<12, 38> { }; /* physical address page aligned */ - template - static access_t rwx(Hw::Page_flags const &f) - { - if (f.writeable && f.executable) - return BASE + 3; - else if (f.writeable) - return BASE + 1; - else if (f.executable) - return BASE + 2; - else - return BASE; - } - static access_t permission_bits(Hw::Page_flags const &f) { + access_t rights = 0; + R::set(rights, 1); + + if (f.writeable) + W::set(rights, 1); + + if (f.executable) + X::set(rights, 1); + + if (!f.privileged) + U::set(rights, 1); + if (f.global) - return rwx(f); + G::set(rights, 1); - if (f.privileged) - return rwx(f); - - return rwx(f); + return rights; } static Descriptor_type type(access_t const v) { if (!V::get(v)) return INVALID; - if (Type::get(v) == Type::POINTER || Type::get(v) == Type::POINTER_GLOBAL) + if (Type::get(v) == Type::POINTER) return TABLE; return BLOCK; @@ -127,7 +126,7 @@ struct Sv39::Block_descriptor : Descriptor access_t desc = 0; Ppn::set(desc, base); - Type::set(desc, permission_bits(f)); + Perm::set(desc, permission_bits(f)); V::set(desc, 1); return desc; diff --git a/repos/base-hw/src/lib/hw/spec/riscv/uart.h b/repos/base-hw/src/lib/hw/spec/riscv/uart.h index 8d7d13af1..8f5e4ffee 100644 --- a/repos/base-hw/src/lib/hw/spec/riscv/uart.h +++ b/repos/base-hw/src/lib/hw/spec/riscv/uart.h @@ -24,16 +24,7 @@ struct Hw::Riscv_uart { void put_char(char const c) { - struct Arg : Genode::Register<64> - { - struct Char : Bitfield<0, 8> { }; - struct Write_cmd : Bitfield<48, 1> { }; - struct Stdout : Bitfield<56, 1> { }; - }; - - Hw::put_char(Arg::Char::bits(c) | - Arg::Stdout::bits(1) | - Arg::Write_cmd::bits(1)); + Hw::put_char(c); } }; diff --git a/repos/base/include/drivers/defs/riscv.h b/repos/base/include/drivers/defs/riscv.h new file mode 100644 index 000000000..c48ff0fe3 --- /dev/null +++ b/repos/base/include/drivers/defs/riscv.h @@ -0,0 +1,25 @@ +/* + * \brief MMIO and IRQ definitions for RISC-V (1.9.1) + * \author Sebastian Sumpf + * \date 2017-05-29 + */ + +/* + * Copyright (C) 2013-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__DRIVERS__DEFS__RISCV_H_ +#define _INCLUDE__DRIVERS__DEFS__RISCV_H_ + +namespace Riscv { + enum { + RAM_0_BASE = 0x81000000, + RAM_0_SIZE = 0x6e00000, + }; +} + +#endif /* _INCLUDE__DRIVERS__DEFS__RISCV_H_ */ + diff --git a/repos/os/include/spec/riscv/trace/timestamp.h b/repos/os/include/spec/riscv/trace/timestamp.h new file mode 100644 index 000000000..7da737d8f --- /dev/null +++ b/repos/os/include/spec/riscv/trace/timestamp.h @@ -0,0 +1,31 @@ +/* + * \brief Trace timestamp + * \author Sebastian Sumpf + * \date 2017-05-26 + * + * Serialized reading of performance counter on ARM. + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__SPEC__RISCV__TRACE__TIMESTAMP_H_ +#define _INCLUDE__SPEC__RISCV__TRACE__TIMESTAMP_H_ + +#include + +namespace Genode { namespace Trace { + + typedef uint32_t Timestamp; + + inline Timestamp timestamp() + { + return 0; + } +} } + +#endif /* _INCLUDE__SPEC__RISCV__TRACE__TIMESTAMP_H_ */ diff --git a/tool/run/boot_dir/hw b/tool/run/boot_dir/hw index 76626c584..174c2943f 100644 --- a/tool/run/boot_dir/hw +++ b/tool/run/boot_dir/hw @@ -15,7 +15,7 @@ proc bootstrap_link_address { } { if {[have_spec "arndale"]} { return "0x80000000" } if {[have_spec "panda"]} { return "0x81000000" } if {[have_spec "zynq"]} { return "0x00100000" } - if {[have_spec "riscv"]} { return "0x00000200" } + if {[have_spec "riscv"]} { return "0x81000000" } if {[have_spec "rpi"]} { return "0x00800000" } puts "unknown platform no linker address known"