mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
hw: run core threads in privileged mode
* introduce new syscall (core-only) to create privileged threads * take the privilege level of the thread into account when doing a context switch * map kernel segment as accessable for privileged code only Ref #2091
This commit is contained in:
parent
7e47fa58b3
commit
ca60e24ad9
@ -1 +1 @@
|
||||
10f40152b12a9fd068f88a587e84e342b707698e
|
||||
30243a733d49c8545adbb230df7e01f8a8fc12a0
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -12,6 +12,7 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
#include <platform.h>
|
||||
#include <hw/spec/riscv/cpu.h>
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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<Thread> * co =
|
||||
Genode::construct_at<Core_object<Thread> >(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<Thread>(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<Thread>(); 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<Thread>(Cpu_priority::MAX, 0, "core")
|
||||
: Core_object<Thread>("core")
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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)
|
||||
|
@ -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<Kernel::Thread>(true, Kernel::Cpu_priority::MAX, 0, _label),
|
||||
: Kernel_object<Kernel::Thread>(true, _label),
|
||||
_pd(Kernel::core_pd()->platform_pd()),
|
||||
_pager(nullptr),
|
||||
_utcb_core_addr(utcb),
|
||||
|
@ -13,12 +13,12 @@
|
||||
|
||||
#include <spec/arm/cpu_support.h>
|
||||
|
||||
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;
|
||||
|
@ -13,12 +13,12 @@
|
||||
|
||||
#include <spec/arm/cpu_support.h>
|
||||
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <cpu/cpu_state.h>
|
||||
#include <util/register.h>
|
||||
|
||||
#include <kernel/interface.h>
|
||||
#include <hw/spec/riscv/cpu.h>
|
||||
|
||||
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_ */
|
||||
|
@ -18,6 +18,8 @@
|
||||
.set CPU_SP, 3*8
|
||||
.set CPU_SPTBR, 33*8
|
||||
|
||||
.section ".text.crt0"
|
||||
|
||||
.p2align 12
|
||||
.global _mt_begin
|
||||
_mt_begin:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
@ -15,13 +15,11 @@
|
||||
#define _CORE__SPEC__RISCV__TRANSLATION_TABLE_H_
|
||||
|
||||
#include <hw/spec/riscv/page_table.h>
|
||||
#include <kernel/interface.h>
|
||||
#include <cpu.h>
|
||||
|
||||
template <typename E, unsigned B, unsigned S>
|
||||
void Sv39::Level_x_translation_table<E, B, S>::_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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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_ */
|
||||
|
@ -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); }
|
||||
|
@ -230,6 +230,7 @@ struct Hw::Arm_cpu
|
||||
SVC = 19,
|
||||
MON = 22,
|
||||
HYP = 26,
|
||||
SYS = 31,
|
||||
};
|
||||
};
|
||||
|
||||
|
46
repos/base-hw/src/lib/hw/spec/riscv/cpu.h
Normal file
46
repos/base-hw/src/lib/hw/spec/riscv/cpu.h
Normal file
@ -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 <hw/spec/riscv/register_macros.h>
|
||||
|
||||
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_ */
|
||||
|
36
repos/base-hw/src/lib/hw/spec/riscv/register_macros.h
Normal file
36
repos/base-hw/src/lib/hw/spec/riscv/register_macros.h
Normal file
@ -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 <util/register.h>
|
||||
|
||||
#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_ */
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user