diff --git a/repos/base-hw/ports/bbl.hash b/repos/base-hw/ports/bbl.hash index a68fab5077..010c8043b8 100644 --- a/repos/base-hw/ports/bbl.hash +++ b/repos/base-hw/ports/bbl.hash @@ -1 +1 @@ -10f40152b12a9fd068f88a587e84e342b707698e +30243a733d49c8545adbb230df7e01f8a8fc12a0 diff --git a/repos/base-hw/ports/bbl.port b/repos/base-hw/ports/bbl.port index 2f006cf133..1476e09847 100644 --- a/repos/base-hw/ports/bbl.port +++ b/repos/base-hw/ports/bbl.port @@ -2,7 +2,7 @@ LICENSE := BSD-3-Clause VERSION := git DOWNLOADS := bbl.git -URL(bbl) = https://github.com/ssumpf/bbl-lite.git -REV(bbl) = 0f86d104c470cfad70a9bc049865edb2ab0c4710 +URL(bbl) = https://github.com/skalk/bbl-lite.git +REV(bbl) = 20e03dfa317747dd39175f9fc3c15c50b702ac04 DIR(bbl) = src/lib/bbl diff --git a/repos/base-hw/src/bootstrap/platform.cc b/repos/base-hw/src/bootstrap/platform.cc index dbacd7ade6..6c1e5013a6 100644 --- a/repos/base-hw/src/bootstrap/platform.cc +++ b/repos/base-hw/src/bootstrap/platform.cc @@ -120,9 +120,9 @@ Mapping Platform::_load_elf() phys = dst; } - //FIXME: set read-only, privileged and global accordingly + //FIXME: set read-only accordingly Page_flags flags{RW, segment.flags().x ? EXEC : NO_EXEC, - USER, GLOBAL, RAM, CACHED}; + KERN, GLOBAL, RAM, CACHED}; Mapping m((addr_t)phys, (addr_t)segment.start(), size, flags); /* diff --git a/repos/base-hw/src/bootstrap/spec/arm/cpu.cc b/repos/base-hw/src/bootstrap/spec/arm/cpu.cc index 95460b85b7..ea308d52f0 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/cpu.cc +++ b/repos/base-hw/src/bootstrap/spec/arm/cpu.cc @@ -24,16 +24,17 @@ void Bootstrap::Cpu::enable_mmu_and_caches(Genode::addr_t table) /* do not use domains, but permission bits in table */ Dacr::write(Dacr::D0::bits(1)); - Ttbcr::write(0); + Ttbcr::write(1); - Ttbr::access_t ttbr0 = Ttbr::Ba::masked(table); - Ttbr::Rgn::set(ttbr0, Ttbr::CACHEABLE); + Ttbr::access_t ttbr = Ttbr::Ba::masked(table); + Ttbr::Rgn::set(ttbr, Ttbr::CACHEABLE); if (Mpidr::read()) { /* check for SMP system */ - Ttbr::Irgn::set(ttbr0, Ttbr::CACHEABLE); - Ttbr::S::set(ttbr0, 1); + Ttbr::Irgn::set(ttbr, Ttbr::CACHEABLE); + Ttbr::S::set(ttbr, 1); } else - Ttbr::C::set(ttbr0, 1); - Ttbr0::write(ttbr0); + Ttbr::C::set(ttbr, 1); + Ttbr0::write(ttbr); + Ttbr1::write(ttbr); Sctlr::access_t sctlr = Sctlr::read(); Sctlr::C::set(sctlr, 1); diff --git a/repos/base-hw/src/bootstrap/spec/riscv/platform.cc b/repos/base-hw/src/bootstrap/spec/riscv/platform.cc index 44957b7946..a20f7d99b2 100644 --- a/repos/base-hw/src/bootstrap/spec/riscv/platform.cc +++ b/repos/base-hw/src/bootstrap/spec/riscv/platform.cc @@ -12,6 +12,7 @@ * under the terms of the GNU Affero General Public License version 3. */ #include +#include using namespace Board; @@ -21,8 +22,6 @@ Bootstrap::Platform::Board::Board() void Bootstrap::Platform::enable_mmu() { - asm volatile ("csrw sptbr, %0\n" /* set asid | page table */ - : - : "r" ((addr_t)core_pd->table_base >> 12) - : "memory"); + using Sptbr = Hw::Riscv_cpu::Sptbr; + Sptbr::write(Sptbr::Ppn::masked((addr_t)core_pd->table_base >> 12)); } diff --git a/repos/base-hw/src/core/core_region_map.cc b/repos/base-hw/src/core/core_region_map.cc index 6cefb59e67..eaae882620 100644 --- a/repos/base-hw/src/core/core_region_map.cc +++ b/repos/base-hw/src/core/core_region_map.cc @@ -61,8 +61,8 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t size, /* map the dataspace's physical pages to corresponding virtual addresses */ unsigned num_pages = page_rounded_size >> get_page_size_log2(); - Page_flags const flags { ds->writable() ? RW : RO, NO_EXEC, USER, - NO_GLOBAL, ds->io_mem() ? DEVICE : RAM, + Page_flags const flags { ds->writable() ? RW : RO, NO_EXEC, KERN, + GLOBAL, ds->io_mem() ? DEVICE : RAM, ds->cacheability() }; if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages, flags)) return nullptr; diff --git a/repos/base-hw/src/core/kernel/core_interface.h b/repos/base-hw/src/core/kernel/core_interface.h index b26ef14c36..a5be22a550 100644 --- a/repos/base-hw/src/core/kernel/core_interface.h +++ b/repos/base-hw/src/core/kernel/core_interface.h @@ -59,6 +59,7 @@ namespace Kernel constexpr Call_arg call_id_new_obj() { return 121; } constexpr Call_arg call_id_delete_obj() { return 122; } constexpr Call_arg call_id_cancel_thread_blocking() { return 123; } + constexpr Call_arg call_id_new_core_thread() { return 124; } /** * Update locally effective domain configuration to in-memory state diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 9cd38704b1..7efa50c326 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -37,8 +37,6 @@ extern "C" void _core_start(void); using namespace Kernel; -bool Thread::_core() const { return pd() == core_pd(); } - void Thread::_signal_context_kill_pending() { assert(_state == ACTIVE); @@ -170,6 +168,16 @@ void Thread::_call_new_thread() } +void Thread::_call_new_core_thread() +{ + void * const p = (void *)user_arg_1(); + char const * const label = (char *)user_arg_2(); + Core_object * co = + Genode::construct_at >(p, label); + user_arg_0(co->core_capid()); +} + + void Thread::_call_thread_quota() { Thread * const thread = (Thread *)user_arg_1(); @@ -234,7 +242,7 @@ void Thread::_call_restart_thread() return; } Thread * const thread = pd()->cap_tree().find(user_arg_1()); - if (!thread || (!_core() && (pd() != thread->pd()))) { + if (!thread || (!_core && (pd() != thread->pd()))) { warning(*this, ": failed to lookup thread ", (unsigned)user_arg_1(), " to restart it"); _die(); @@ -567,7 +575,7 @@ void Thread::_call() case call_id_time(): user_arg_0(Cpu_job::time()); return; default: /* check wether this is a core thread */ - if (!_core()) { + if (!_core) { Genode::warning(*this, ": not entitled to do kernel call"); _die(); return; @@ -576,6 +584,7 @@ void Thread::_call() /* switch over kernel calls that are restricted to core */ switch (call_id) { case call_id_new_thread(): _call_new_thread(); return; + case call_id_new_core_thread(): _call_new_core_thread(); return; case call_id_thread_quota(): _call_thread_quota(); return; case call_id_delete_thread(): _call_delete(); return; case call_id_start_thread(): _call_start_thread(); return; @@ -614,11 +623,11 @@ void Thread::_call() Thread::Thread(unsigned const priority, unsigned const quota, - char const * const label) + char const * const label, bool core) : Cpu_job(priority, quota), _fault_pd(0), _fault_addr(0), _fault_writes(0), _state(AWAITS_START), - _signal_receiver(0), _label(label) + _signal_receiver(0), _label(label), _core(core) { _init(); } @@ -640,7 +649,7 @@ Genode::uint8_t __initial_stack_base[DEFAULT_STACK_SIZE]; *****************/ Core_thread::Core_thread() -: Core_object(Cpu_priority::MAX, 0, "core") +: Core_object("core") { using namespace Genode; diff --git a/repos/base-hw/src/core/kernel/thread.h b/repos/base-hw/src/core/kernel/thread.h index 0a9ab57013..3cf9a40ef3 100644 --- a/repos/base-hw/src/core/kernel/thread.h +++ b/repos/base-hw/src/core/kernel/thread.h @@ -63,6 +63,7 @@ class Kernel::Thread capid_t _timeout_sigid = 0; bool _paused = false; bool _cancel_next_await_signal = false; + bool const _core = false; void _init(); @@ -83,11 +84,6 @@ class Kernel::Thread int _route_event(unsigned const event_id, Signal_context * const signal_context_id); - /** - * Return wether this is a core thread - */ - bool _core() const; - /** * Switch from an inactive state to the active state */ @@ -138,6 +134,7 @@ class Kernel::Thread *********************************************************/ void _call_new_thread(); + void _call_new_core_thread(); void _call_thread_quota(); void _call_start_thread(); void _call_stop_thread(); @@ -232,9 +229,18 @@ class Kernel::Thread * \param priority scheduling priority * \param quota CPU-time quota * \param label debugging label + * \param core whether it is a core thread or not */ Thread(unsigned const priority, unsigned const quota, - char const * const label); + char const * const label, bool core = false); + + /** + * Constructor for core/kernel thread + * + * \param label debugging label + */ + Thread(char const * const label) + : Thread(Cpu_priority::MAX, 0, label, true) { } /** * Syscall to create a thread @@ -254,6 +260,20 @@ class Kernel::Thread (Call_arg)quota, (Call_arg)label); } + /** + * Syscall to create a core thread + * + * \param p memory donation for the new kernel thread object + * \param label debugging label of the new thread + * + * \retval capability id of the new kernel object + */ + static capid_t syscall_create(void * const p, char const * const label) + { + return call(call_id_new_core_thread(), (Call_arg)p, + (Call_arg)label); + } + /** * Syscall to destroy a thread * diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index 32bd62c60a..65ce36e1a9 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -81,8 +81,7 @@ void Hw::Address_space::flush(addr_t virt, size_t size, Core_local_addr) Hw::Address_space::Address_space(Kernel::Pd & pd, Page_table & tt, Page_table::Allocator & tt_alloc) : _tt(tt), _tt_phys(Platform::core_page_table()), - _tt_alloc(tt_alloc), _kernel_pd(pd) { - Kernel::mtc()->map(_tt, _tt_alloc); } + _tt_alloc(tt_alloc), _kernel_pd(pd) { } Hw::Address_space::Address_space(Kernel::Pd & pd) diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index cbfe8822bf..350fc30bfb 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -57,7 +57,7 @@ void Platform_thread::quota(size_t const quota) { Platform_thread::Platform_thread(const char * const label, Native_utcb * utcb) -: Kernel_object(true, Kernel::Cpu_priority::MAX, 0, _label), +: Kernel_object(true, _label), _pd(Kernel::core_pd()->platform_pd()), _pager(nullptr), _utcb_core_addr(utcb), diff --git a/repos/base-hw/src/core/spec/arm/cpu_context.cc b/repos/base-hw/src/core/spec/arm/cpu_context.cc index 41ff0ddf4e..21ddb0fd1c 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_context.cc +++ b/repos/base-hw/src/core/spec/arm/cpu_context.cc @@ -13,12 +13,12 @@ #include -Genode::Arm_cpu::User_context::User_context() +void Genode::Arm_cpu::User_context::init(bool privileged) { using Psr = Arm_cpu::Psr; Psr::access_t v = 0; - Psr::M::set(v, Psr::M::USR); + Psr::M::set(v, privileged ? Psr::M::SYS : Psr::M::USR); Psr::F::set(v, 1); Psr::A::set(v, 1); cpsr = v; diff --git a/repos/base-hw/src/core/spec/arm/cpu_context_trustzone.cc b/repos/base-hw/src/core/spec/arm/cpu_context_trustzone.cc index 9c773e58ee..41497f6e41 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_context_trustzone.cc +++ b/repos/base-hw/src/core/spec/arm/cpu_context_trustzone.cc @@ -13,12 +13,12 @@ #include -Genode::Arm_cpu::User_context::User_context() +void Genode::Arm_cpu::User_context::init(bool privileged) { using Psr = Genode::Arm_cpu::Psr; Psr::access_t v = 0; - Psr::M::set(v, Psr::M::USR); + Psr::M::set(v, privileged ? Psr::M::SYS : Psr::M::USR); Psr::I::set(v, 1); Psr::A::set(v, 1); cpsr = v; diff --git a/repos/base-hw/src/core/spec/arm/cpu_support.h b/repos/base-hw/src/core/spec/arm/cpu_support.h index f72fdce7a6..0a00c060e6 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/spec/arm/cpu_support.h @@ -107,7 +107,7 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu */ struct User_context : Context { - User_context(); + void init(bool privileged); /** * Support for kernel calls diff --git a/repos/base-hw/src/core/spec/arm/kernel/cpu.cc b/repos/base-hw/src/core/spec/arm/kernel/cpu.cc index 590448df83..653b3f52a2 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/cpu.cc @@ -31,5 +31,8 @@ void Kernel::Cpu::init(Kernel::Pic &pic) void Kernel::Cpu_domain_update::_domain_update() { /* flush TLB by ASID */ - Cpu::Tlbiasid::write(_domain_id); + if (_domain_id) + Cpu::Tlbiasid::write(_domain_id); + else + Cpu::Tlbiall::write(0); } diff --git a/repos/base-hw/src/core/spec/arm/kernel/cpu_idle.cc b/repos/base-hw/src/core/spec/arm/kernel/cpu_idle.cc index dcead4b3de..e62614c3be 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/cpu_idle.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/cpu_idle.cc @@ -28,6 +28,7 @@ Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::MIN, 0) ip = (addr_t)&_main; sp = (addr_t)&_stack[stack_size]; init_thread((addr_t)core_pd()->translation_table(), core_pd()->asid); + init(true); } diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread.cc b/repos/base-hw/src/core/spec/arm/kernel/thread.cc index 3fbd979da3..3c1495ac3d 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread.cc @@ -18,7 +18,11 @@ using namespace Kernel; -void Kernel::Thread::_init() { cpu_exception = RESET; } +void Kernel::Thread::_init() +{ + init(_core); + cpu_exception = RESET; +} void Thread::exception(unsigned const cpu) @@ -92,7 +96,7 @@ void Kernel::Thread::_call_update_data_region() * address space so we can use virtual addresses of the caller. Up * until then we apply operations to caches as a whole instead. */ - if (!_core()) { + if (!_core) { cpu->clean_invalidate_data_cache(); return; } @@ -116,7 +120,7 @@ void Kernel::Thread::_call_update_instr_region() * address space so we can use virtual addresses of the caller. Up * until then we apply operations to caches as a whole instead. */ - if (!_core()) { + if (!_core) { cpu->clean_invalidate_data_cache(); cpu->invalidate_instr_cache(); return; diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc b/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc index 2b9efc5d50..2b52aa300c 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc @@ -20,5 +20,8 @@ void Kernel::Thread::_call_update_pd() Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id()); cpu->invalidate_instr_cache(); cpu->clean_invalidate_data_cache(); - Cpu::Tlbiasid::write(pd->asid); /* flush TLB by ASID */ + if (pd->asid) + Cpu::Tlbiasid::write(pd->asid); /* flush TLB by ASID */ + else + Cpu::Tlbiall::write(0); } diff --git a/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc b/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc index 10eb3bc854..26deff7b02 100644 --- a/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc @@ -28,5 +28,8 @@ Kernel::Lock & Kernel::data_lock() { void Kernel::Cpu_domain_update::_domain_update() { /* flush TLB by ASID */ - Cpu::Tlbiasid::write(_domain_id); + if (_domain_id) + Cpu::Tlbiasid::write(_domain_id); + else + Cpu::Tlbiall::write(0); } diff --git a/repos/base-hw/src/core/spec/cortex_a15/cpu.h b/repos/base-hw/src/core/spec/cortex_a15/cpu.h index 49bdf71749..7517088de3 100644 --- a/repos/base-hw/src/core/spec/cortex_a15/cpu.h +++ b/repos/base-hw/src/core/spec/cortex_a15/cpu.h @@ -154,10 +154,10 @@ class Genode::Cpu : public Arm_v7_cpu */ struct User_context : Context { - User_context() + void init(bool privileged) { Psr::access_t v = 0; - Psr::M::set(v, Psr::M::USR); + Psr::M::set(v, privileged ? Psr::M::SYS : Psr::M::USR); Psr::F::set(v, 1); Psr::A::set(v, 1); cpsr = v; diff --git a/repos/base-hw/src/core/spec/riscv/cpu.h b/repos/base-hw/src/core/spec/riscv/cpu.h index 9b96c143bb..50dfcd634c 100644 --- a/repos/base-hw/src/core/spec/riscv/cpu.h +++ b/repos/base-hw/src/core/spec/riscv/cpu.h @@ -19,6 +19,8 @@ #include #include +#include +#include namespace Genode { @@ -32,40 +34,37 @@ namespace Genode namespace Kernel { class Pd; } -class Genode::Cpu +class Genode::Cpu : public Hw::Riscv_cpu { public: static constexpr addr_t mtc_size = 0x1000; - static constexpr addr_t exception_entry = (~0ULL) & ~(0xfff); + static constexpr addr_t exception_entry = 0xffffffc000000000; /** * Extend basic CPU state by members relevant for 'base-hw' only */ struct Context : Cpu_state { - struct Sptbr : Register<64> - { - struct Ppn : Bitfield<0, 38> { }; - struct Asid : Bitfield<38, 26> { }; - }; - Sptbr::access_t sptbr; /** * Return base of assigned translation table */ - addr_t translation_table() const { return Sptbr::Ppn::get(sptbr) << 12; } + addr_t translation_table() const { + return Sptbr::Ppn::get(sptbr) << 12; } /** * Assign translation-table base 'table' */ - void translation_table(addr_t const table) { Sptbr::Ppn::set(sptbr, table >> 12); } + void translation_table(addr_t const table) { + Sptbr::Ppn::set(sptbr, table >> 12); } /** * Assign protection domain */ - void protection_domain(Genode::uint8_t const id) { Sptbr::Asid::set(sptbr, id); } + void protection_domain(Genode::uint8_t const id) { + Sptbr::Asid::set(sptbr, id); } }; struct Pd @@ -153,18 +152,17 @@ class Genode::Cpu */ static unsigned primary_id() { return 0; } - static addr_t sbadaddr() - { - addr_t addr; - asm volatile ("csrr %0, sbadaddr\n" : "=r"(addr)); - return addr; - } - /************* ** Dummies ** *************/ - void switch_to(User_context&) { } + void switch_to(User_context& context) + { + bool user = Sptbr::Asid::get(context.sptbr); + Sstatus::access_t v = Sstatus::read(); + Sstatus::Spp::set(v, user ? 0 : 1); + Sstatus::write(v); + } }; #endif /* _CORE__SPEC__RISCV__CPU_H_ */ diff --git a/repos/base-hw/src/core/spec/riscv/exception_vector.s b/repos/base-hw/src/core/spec/riscv/exception_vector.s index 5ddea40b45..5b93f658b5 100644 --- a/repos/base-hw/src/core/spec/riscv/exception_vector.s +++ b/repos/base-hw/src/core/spec/riscv/exception_vector.s @@ -18,6 +18,8 @@ .set CPU_SP, 3*8 .set CPU_SPTBR, 33*8 +.section ".text.crt0" + .p2align 12 .global _mt_begin _mt_begin: diff --git a/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc b/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc index d65c2028ac..14000eecf9 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc @@ -25,12 +25,9 @@ void Kernel::Cpu::init(Kernel::Pic &pic/*, Kernel::Pd & core_pd, { addr_t client_context_ptr_off = (addr_t)&_mt_client_context_ptr & 0xfff; addr_t client_context_ptr = exception_entry | client_context_ptr_off; - asm volatile ("csrw stvec, %0\n" /* exception vector */ - "csrw sscratch,%1\n" /* master conext ptr */ - : - : "r" (exception_entry), - "r" (client_context_ptr) - : "memory"); + asm volatile ( "csrw sscratch,%0\n" /* master conext ptr */ + :: "r" (client_context_ptr) : "memory"); + Stvec::write(exception_entry); } diff --git a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc index ed6bb0557f..3e99e94617 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc @@ -26,6 +26,7 @@ void Thread::exception(unsigned const cpu) switch(cpu_exception) { case ECALL_FROM_USER: + case ECALL_FROM_SUPERVISOR: _call(); ip += 4; /* set to next instruction */ break; @@ -36,7 +37,7 @@ void Thread::exception(unsigned const cpu) break; default: Genode::error(*this, ": unhandled exception ", cpu_exception, - " at ip=", (void*)ip, " addr=", Genode::Hex(Cpu::sbadaddr())); + " at ip=", (void*)ip, " addr=", Genode::Hex(Cpu::Sbadaddr::read())); _die(); } } @@ -46,7 +47,7 @@ void Thread::_mmu_exception() { _become_inactive(AWAITS_RESTART); _fault_pd = (addr_t)_pd->platform_pd(); - _fault_addr = Cpu::sbadaddr(); + _fault_addr = Cpu::Sbadaddr::read(); if (_pager) _pager->submit(1); } diff --git a/repos/base-hw/src/core/spec/riscv/macros.s b/repos/base-hw/src/core/spec/riscv/macros.s deleted file mode 100644 index 3b3407f313..0000000000 --- a/repos/base-hw/src/core/spec/riscv/macros.s +++ /dev/null @@ -1,16 +0,0 @@ -/* - * \brief Macros that are used by multiple assembly files - * \author Sebastian Sumpf - * \date 2015-06-02 - */ - -/* - * 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. - */ - -/* alignment constraints */ -.set DATA_ACCESS_ALIGNM_LOG2, 3 -.set MIN_PAGE_SIZE_LOG2, 12 diff --git a/repos/base-hw/src/core/spec/riscv/translation_table.h b/repos/base-hw/src/core/spec/riscv/translation_table.h index f84f56e605..20d034c1bc 100644 --- a/repos/base-hw/src/core/spec/riscv/translation_table.h +++ b/repos/base-hw/src/core/spec/riscv/translation_table.h @@ -15,13 +15,11 @@ #define _CORE__SPEC__RISCV__TRANSLATION_TABLE_H_ #include -#include +#include template void Sv39::Level_x_translation_table::_translation_added(addr_t addr, - size_t size) -{ - Kernel::update_data_region(addr, size); -} + size_t size) { + Genode::Cpu::sfence(); } #endif /* _CORE__SPEC__RISCV__TRANSLATION_TABLE_H_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.cc b/repos/base-hw/src/core/spec/x86_64/cpu.cc index d8eb68e49e..0992cbe962 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/cpu.cc @@ -31,12 +31,10 @@ void Genode::Cpu::Context::init(addr_t const table, bool core) cr3 = Cr3::init(table); - /* - * Enable interrupts for all threads, set I/O privilege level - * (IOPL) to 3 for core threads to allow UART access. - */ + /* enable interrupts for all threads */ eflags = EFLAGS_IF_SET; - if (core) eflags |= EFLAGS_IOPL_3; + cs = core ? 0x8 : 0x1b; + ss = core ? 0x10 : 0x23; } diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc index b3351c5c1b..4089159179 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc @@ -29,6 +29,8 @@ Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::MIN, 0) Cpu_job::cpu(cpu); ip = (addr_t)&_main; sp = (addr_t)&_stack[stack_size]; + cs = 0x8; + ss = 0x10; init((addr_t)core_pd()->translation_table(), true); } diff --git a/repos/base-hw/src/core/spec/x86_64/mode_transition.s b/repos/base-hw/src/core/spec/x86_64/mode_transition.s index 7ea6de6cdc..b261a9849e 100644 --- a/repos/base-hw/src/core/spec/x86_64/mode_transition.s +++ b/repos/base-hw/src/core/spec/x86_64/mode_transition.s @@ -29,7 +29,9 @@ .set ERRCODE_OFFSET, 17 * 8 .set FLAGS_OFFSET, 18 * 8 .set TRAPNO_OFFSET, 19 * 8 -.set CR3_OFFSET, 21 * 8 +.set CS_OFFSET, 20 * 8 +.set SS_OFFSET, 22 * 8 +.set CR3_OFFSET, 23 * 8 /* tss segment constants */ .set TSS_LIMIT, 0x68 @@ -210,11 +212,11 @@ mov (%rax), %rax _load_address _mt_buffer rsp add $BUFFER_SIZE, %rsp - pushq $0x23 + pushq SS_OFFSET(%rax) pushq SP_OFFSET(%rax) pushq FLAGS_OFFSET(%rax) - pushq $0x1b + pushq CS_OFFSET(%rax) pushq (%rax) /* Restore register values from client context */ diff --git a/repos/base-hw/src/lib/hw/page_flags.h b/repos/base-hw/src/lib/hw/page_flags.h index 9c8f1c5a0a..872118f3bb 100644 --- a/repos/base-hw/src/lib/hw/page_flags.h +++ b/repos/base-hw/src/lib/hw/page_flags.h @@ -58,15 +58,15 @@ struct Hw::Page_flags namespace Hw { static constexpr Page_flags PAGE_FLAGS_KERN_IO - { RW, NO_EXEC, USER, NO_GLOBAL, DEVICE, Genode::UNCACHED }; + { RW, NO_EXEC, KERN, GLOBAL, DEVICE, Genode::UNCACHED }; static constexpr Page_flags PAGE_FLAGS_KERN_DATA - { RW, EXEC, USER, NO_GLOBAL, RAM, Genode::CACHED }; + { RW, EXEC, KERN, GLOBAL, RAM, Genode::CACHED }; static constexpr Page_flags PAGE_FLAGS_KERN_TEXT - { RW, EXEC, USER, NO_GLOBAL, RAM, Genode::CACHED }; + { RW, EXEC, KERN, GLOBAL, RAM, Genode::CACHED }; static constexpr Page_flags PAGE_FLAGS_KERN_EXCEP - { RW, EXEC, USER, GLOBAL, RAM, Genode::CACHED }; + { RW, EXEC, KERN, GLOBAL, RAM, Genode::CACHED }; static constexpr Page_flags PAGE_FLAGS_UTCB - { RW, NO_EXEC, USER, NO_GLOBAL, RAM, Genode::CACHED }; + { RW, NO_EXEC, USER, NO_GLOBAL, RAM, Genode::CACHED }; } #endif /* _SRC__LIB__HW__PAGE_FLAGS_H_ */ diff --git a/repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc b/repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc index 48af72767f..c2bd2f8671 100644 --- a/repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc +++ b/repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc @@ -25,7 +25,7 @@ static constexpr addr_t USER_START = Genode::user_utcb_main_thread() static constexpr addr_t KERNEL_START = 0xffffffc000000000UL; Memory_region const Hw::Mm::user() { - return Memory_region(USER_START, KERNEL_START - USER_START); } + return Memory_region(USER_START, 0x800000000000 - USER_START); } Memory_region const Hw::Mm::core_heap() { return Memory_region(0xffffffd000000000UL, 0x1000000000UL); } diff --git a/repos/base-hw/src/lib/hw/spec/arm/cpu.h b/repos/base-hw/src/lib/hw/spec/arm/cpu.h index aaaebb2002..4b69d91b0d 100644 --- a/repos/base-hw/src/lib/hw/spec/arm/cpu.h +++ b/repos/base-hw/src/lib/hw/spec/arm/cpu.h @@ -230,6 +230,7 @@ struct Hw::Arm_cpu SVC = 19, MON = 22, HYP = 26, + SYS = 31, }; }; diff --git a/repos/base-hw/src/lib/hw/spec/riscv/cpu.h b/repos/base-hw/src/lib/hw/spec/riscv/cpu.h new file mode 100644 index 0000000000..b1d47ac191 --- /dev/null +++ b/repos/base-hw/src/lib/hw/spec/riscv/cpu.h @@ -0,0 +1,46 @@ +/* + * \brief CPU definitions for RiscV + * \author Stefan Kalkowski + * \date 2017-09-14 + */ + +/* + * 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 _SRC__LIB__HW__SPEC__RISCV__CPU_H_ +#define _SRC__LIB__HW__SPEC__RISCV__CPU_H_ + +#include + +namespace Hw { struct Riscv_cpu; } + +struct Hw::Riscv_cpu +{ + /************************** + ** Supervisor registers ** + **************************/ + + /* Supervisor-mode status Register */ + RISCV_SUPERVISOR_REGISTER(Sstatus, sstatus, + struct Spp : Bitfield<8,1> { }; /* prior privilege level */ + ); + + /* Supervisor Trap Vector Base Address Register */ + RISCV_SUPERVISOR_REGISTER(Stvec, stvec); + + /* Supervisor Bad Address Register */ + RISCV_SUPERVISOR_REGISTER(Sbadaddr, sbadaddr); + + /* Supervisor Page-Table Base Register */ + RISCV_SUPERVISOR_REGISTER(Sptbr, sptbr, + struct Ppn : Bitfield<0, 38> { }; + struct Asid : Bitfield<38, 26> { }; + ); +}; + +#endif /* _SRC__LIB__HW__SPEC__RISCV__CPU_H_ */ + diff --git a/repos/base-hw/src/lib/hw/spec/riscv/register_macros.h b/repos/base-hw/src/lib/hw/spec/riscv/register_macros.h new file mode 100644 index 0000000000..21f5817960 --- /dev/null +++ b/repos/base-hw/src/lib/hw/spec/riscv/register_macros.h @@ -0,0 +1,36 @@ +/* + * \brief CPU register macros for RiscV + * \author Stefan Kalkowski + * \date 2017-09-14 + */ + +/* + * 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 _SRC__LIB__HW__SPEC__RISCV__REGISTER_MACROS_H_ +#define _SRC__LIB__HW__SPEC__RISCV__REGISTER_MACROS_H_ + +#include + +#define RISCV_SUPERVISOR_REGISTER(name, reg, ...) \ + struct name : Genode::Register<64> \ + { \ + static access_t read() \ + { \ + access_t v; \ + asm volatile ("csrr %0, " #reg : "=r" (v) :: ); \ + return v; \ + } \ + \ + static void write(access_t const v) { \ + asm volatile ("csrw " #reg ", %0" :: "r" (v) : ); } \ + \ + __VA_ARGS__; \ + }; + +#endif /* _SRC__LIB__HW__SPEC__ARM__REGISTER_MACROS_H_ */ + diff --git a/repos/base/include/spec/x86_64/cpu/cpu_state.h b/repos/base/include/spec/x86_64/cpu/cpu_state.h index 5cedc272cc..f53aae8bf5 100644 --- a/repos/base/include/spec/x86_64/cpu/cpu_state.h +++ b/repos/base/include/spec/x86_64/cpu/cpu_state.h @@ -55,6 +55,8 @@ struct Genode::Cpu_state addr_t errcode = 0; addr_t eflags = 0; addr_t trapno = RESET; + addr_t cs = 0; + addr_t ds = 0; addr_t ss = 0; }; diff --git a/tool/run/boot_dir/hw b/tool/run/boot_dir/hw index 9cbdf29cea..a5d816e5f8 100644 --- a/tool/run/boot_dir/hw +++ b/tool/run/boot_dir/hw @@ -6,14 +6,14 @@ proc binary_name_timer { } { return "hw_timer_drv" } proc run_boot_string { } { return "\nkernel initialized" } proc bootstrap_link_address { } { - if {[have_spec "odroid_xu"]} { return "0x81000000" } + if {[have_spec "odroid_xu"]} { return "0x88000000" } if {[have_spec "pbxa9"]} { return "0x70000000" } if {[have_spec "usb_armory"]} { return "0x72000000" } if {[have_spec "x86_64"]} { return "0x00200000" } if {[have_spec "wand_quad"]} { return "0x10001000" } if {[have_spec "imx53_qsb"]} { return "0x70010000" } - if {[have_spec "arndale"]} { return "0x81000000" } - if {[have_spec "panda"]} { return "0x81000000" } + if {[have_spec "arndale"]} { return "0x88000000" } + if {[have_spec "panda"]} { return "0x88000000" } if {[have_spec "zynq"]} { return "0x00100000" } if {[have_spec "riscv"]} { return "0x81000000" } if {[have_spec "rpi"]} { return "0x00800000" }