mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 03:45:24 +00:00
parent
63f8a38b5a
commit
5dea0b40aa
@ -9,6 +9,9 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/arm
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/arm/kernel/thread_base.cc
|
||||
SRC_CC += spec/arm/kernel/thread.cc
|
||||
SRC_CC += spec/arm/kernel/cpu.cc
|
||||
SRC_CC += spec/arm/kernel/vm.cc
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += spec/arm/crt0.s
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define _KERNEL__CPU_H_
|
||||
|
||||
/* core includes */
|
||||
#include <translation_table.h>
|
||||
#include <timer.h>
|
||||
#include <cpu.h>
|
||||
#include <kernel/cpu_scheduler.h>
|
||||
@ -25,6 +26,11 @@
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* CPU context of a kernel stack
|
||||
*/
|
||||
class Cpu_context;
|
||||
|
||||
/**
|
||||
* Context of a job (thread, VM, idle) that shall be executed by a CPU
|
||||
*/
|
||||
@ -56,6 +62,28 @@ namespace Kernel
|
||||
Cpu_pool * cpu_pool();
|
||||
}
|
||||
|
||||
class Kernel::Cpu_context : Genode::Cpu::Context
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Hook for environment specific initializations
|
||||
*
|
||||
* \param stack_size size of kernel stack
|
||||
* \param table base of transit translation table
|
||||
*/
|
||||
void _init(size_t const stack_size, addr_t const table);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param table mode-transition table
|
||||
*/
|
||||
Cpu_context(Genode::Translation_table * const table);
|
||||
};
|
||||
|
||||
class Kernel::Cpu_domain_update : public Double_list_item
|
||||
{
|
||||
friend class Cpu_domain_update_list;
|
||||
@ -199,15 +227,7 @@ class Kernel::Cpu_idle : public Genode::Cpu::User_context, public Cpu_job
|
||||
* Cpu_job interface
|
||||
*/
|
||||
|
||||
void exception(unsigned const cpu)
|
||||
{
|
||||
switch (cpu_exception) {
|
||||
case INTERRUPT_REQUEST: _interrupt(cpu); return;
|
||||
case FAST_INTERRUPT_REQUEST: _interrupt(cpu); return;
|
||||
case RESET: return;
|
||||
default: assert(0); }
|
||||
}
|
||||
|
||||
void exception(unsigned const cpu);
|
||||
void proceed(unsigned const cpu_id);
|
||||
Cpu_job * helping_sink() { return this; }
|
||||
};
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <kernel/configuration.h>
|
||||
#include <kernel/object.h>
|
||||
#include <kernel/cpu.h>
|
||||
#include <translation_table.h>
|
||||
#include <kernel/vm_state.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* structure of the mode transition */
|
||||
@ -76,11 +76,6 @@ class Kernel::Lock
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* CPU context of the kernel
|
||||
*/
|
||||
class Cpu_context;
|
||||
|
||||
/**
|
||||
* Controls the mode-transition page
|
||||
*
|
||||
@ -112,28 +107,6 @@ namespace Kernel
|
||||
Lock & data_lock();
|
||||
}
|
||||
|
||||
class Kernel::Cpu_context : Cpu::Context
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Hook for environment specific initializations
|
||||
*
|
||||
* \param stack_size size of kernel stack
|
||||
* \param table base of transit translation table
|
||||
*/
|
||||
void _init(size_t const stack_size, addr_t const table);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param table mode-transition table
|
||||
*/
|
||||
Cpu_context(Genode::Translation_table * const table);
|
||||
};
|
||||
|
||||
class Kernel::Mode_transition_control
|
||||
{
|
||||
friend class Pd;
|
||||
@ -143,7 +116,6 @@ class Kernel::Mode_transition_control
|
||||
typedef Early_translations_allocator Allocator;
|
||||
typedef Early_translations_slab Slab;
|
||||
typedef Genode::Translation_table Table;
|
||||
typedef Genode::Cpu_state_modes Cpu_state_modes;
|
||||
typedef Genode::Page_flags Page_flags;
|
||||
|
||||
Allocator _allocator;
|
||||
@ -244,7 +216,7 @@ class Kernel::Mode_transition_control
|
||||
/**
|
||||
* Continue execution of 'vm' at 'cpu'
|
||||
*/
|
||||
void continue_vm(Cpu_state_modes * const vm, unsigned const cpu) {
|
||||
void continue_vm(Vm_state * const vm, unsigned const cpu) {
|
||||
_continue_client(vm, cpu, (addr_t)&_mt_vm_entry_pic); }
|
||||
|
||||
} __attribute__((aligned(Mode_transition_control::ALIGN)));
|
||||
|
@ -14,10 +14,8 @@
|
||||
#ifndef _KERNEL__VM_H_
|
||||
#define _KERNEL__VM_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <cpu/cpu_state.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/vm_state.h>
|
||||
#include <kernel/kernel.h>
|
||||
#include <kernel/pd.h>
|
||||
#include <kernel/signal_receiver.h>
|
||||
@ -41,11 +39,6 @@ class Kernel::Vm : public Object<Vm, MAX_VMS, Vm_ids, vm_ids, vm_pool>,
|
||||
{
|
||||
private:
|
||||
|
||||
struct Vm_state : Genode::Cpu_state_modes
|
||||
{
|
||||
Genode::addr_t dfar;
|
||||
};
|
||||
|
||||
Vm_state * const _state;
|
||||
Signal_context * const _context;
|
||||
|
||||
@ -76,21 +69,7 @@ class Kernel::Vm : public Object<Vm, MAX_VMS, Vm_ids, vm_ids, vm_pool>,
|
||||
** Cpu_job **
|
||||
*************/
|
||||
|
||||
void exception(unsigned const cpu)
|
||||
{
|
||||
switch(_state->cpu_exception) {
|
||||
case Genode::Cpu_state::INTERRUPT_REQUEST:
|
||||
case Genode::Cpu_state::FAST_INTERRUPT_REQUEST:
|
||||
_interrupt(cpu);
|
||||
return;
|
||||
case Genode::Cpu_state::DATA_ABORT:
|
||||
_state->dfar = Cpu::Dfar::read();
|
||||
default:
|
||||
Cpu_job::_deactivate_own_share();
|
||||
_context->submit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void exception(unsigned const cpu);
|
||||
void proceed(unsigned const cpu) { mtc()->continue_vm(_state, cpu); }
|
||||
Cpu_job * helping_sink() { return this; }
|
||||
};
|
||||
|
29
repos/base-hw/src/core/include/spec/arm/kernel/vm_state.h
Normal file
29
repos/base-hw/src/core/include/spec/arm/kernel/vm_state.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* \brief CPU context of a virtual machine
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
* \date 2013-10-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL__VM_STATE_H_
|
||||
#define _KERNEL__VM_STATE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <cpu/cpu_state.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* CPU context of a virtual machine
|
||||
*/
|
||||
struct Vm_state : Genode::Cpu_state_modes { Genode::addr_t dfar; };
|
||||
}
|
||||
|
||||
#endif /* _KERNEL__VM_STATE_H_ */
|
@ -124,15 +124,6 @@ void Cpu_job::affinity(Cpu * const cpu)
|
||||
** Cpu_idle **
|
||||
**************/
|
||||
|
||||
Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::min, 0)
|
||||
{
|
||||
Cpu_job::cpu(cpu);
|
||||
cpu_exception = RESET;
|
||||
ip = (addr_t)&_main;
|
||||
sp = (addr_t)&_stack[stack_size];
|
||||
init_thread((addr_t)core_pd()->translation_table(), core_pd()->id());
|
||||
}
|
||||
|
||||
void Cpu_idle::proceed(unsigned const cpu) { mtc()->continue_user(this, cpu); }
|
||||
|
||||
|
||||
|
@ -159,14 +159,6 @@ void Thread::_become_inactive(State const s)
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(unsigned const priority, unsigned const quota,
|
||||
char const * const label)
|
||||
:
|
||||
Thread_base(this), Cpu_job(priority, quota), _state(AWAITS_START), _pd(0),
|
||||
_utcb_phys(0), _signal_receiver(0), _label(label)
|
||||
{ cpu_exception = RESET; }
|
||||
|
||||
|
||||
void Thread::init(Cpu * const cpu, Pd * const pd,
|
||||
Native_utcb * const utcb_phys, bool const start)
|
||||
{
|
||||
@ -199,39 +191,6 @@ Cpu_job * Thread::helping_sink() {
|
||||
return static_cast<Thread *>(Ipc_node::helping_sink()); }
|
||||
|
||||
|
||||
void Thread::exception(unsigned const cpu)
|
||||
{
|
||||
switch (cpu_exception) {
|
||||
case SUPERVISOR_CALL:
|
||||
_call();
|
||||
return;
|
||||
case PREFETCH_ABORT:
|
||||
_mmu_exception();
|
||||
return;
|
||||
case DATA_ABORT:
|
||||
_mmu_exception();
|
||||
return;
|
||||
case INTERRUPT_REQUEST:
|
||||
_interrupt(cpu);
|
||||
return;
|
||||
case FAST_INTERRUPT_REQUEST:
|
||||
_interrupt(cpu);
|
||||
return;
|
||||
case UNDEFINED_INSTRUCTION:
|
||||
if (_cpu->retry_undefined_instr(&_lazy_state)) { return; }
|
||||
PWRN("undefined instruction");
|
||||
_stop();
|
||||
return;
|
||||
case RESET:
|
||||
return;
|
||||
default:
|
||||
PWRN("unknown exception");
|
||||
_stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Thread::_receive_yielded_cpu()
|
||||
{
|
||||
if (_state == AWAITS_RESUME) { _become_active(); }
|
||||
@ -822,26 +781,6 @@ void Thread::_call_bin_signal_receiver()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_new_vm()
|
||||
{
|
||||
/* lookup signal context */
|
||||
auto const context = Signal_context::pool()->object(user_arg_3());
|
||||
if (!context) {
|
||||
PWRN("failed to lookup signal context");
|
||||
user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
/* create virtual machine */
|
||||
typedef Genode::Cpu_state_modes Cpu_state_modes;
|
||||
auto const allocator = reinterpret_cast<void *>(user_arg_1());
|
||||
auto const state = reinterpret_cast<Cpu_state_modes *>(user_arg_2());
|
||||
Vm * const vm = new (allocator) Vm(state, context);
|
||||
|
||||
/* return kernel name of virtual machine */
|
||||
user_arg_0(vm->id());
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_run_vm()
|
||||
{
|
||||
/* lookup virtual machine */
|
||||
|
46
repos/base-hw/src/core/spec/arm/kernel/cpu.cc
Normal file
46
repos/base-hw/src/core/spec/arm/kernel/cpu.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Class for kernel data that is needed to manage a specific CPU
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/cpu.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
void Cpu_context::_init(size_t const stack_size, addr_t const table)
|
||||
{
|
||||
r12 = stack_size;
|
||||
cpu_exception = Genode::Cpu::Ttbr0::init(table);
|
||||
}
|
||||
|
||||
|
||||
Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::min, 0)
|
||||
{
|
||||
Cpu_job::cpu(cpu);
|
||||
cpu_exception = RESET;
|
||||
ip = (addr_t)&_main;
|
||||
sp = (addr_t)&_stack[stack_size];
|
||||
init_thread((addr_t)core_pd()->translation_table(), core_pd()->id());
|
||||
}
|
||||
|
||||
|
||||
void Cpu_idle::exception(unsigned const cpu)
|
||||
{
|
||||
switch (cpu_exception) {
|
||||
case INTERRUPT_REQUEST: _interrupt(cpu); return;
|
||||
case FAST_INTERRUPT_REQUEST: _interrupt(cpu); return;
|
||||
case RESET: return;
|
||||
default: assert(0); }
|
||||
}
|
143
repos/base-hw/src/core/spec/arm/kernel/thread.cc
Normal file
143
repos/base-hw/src/core/spec/arm/kernel/thread.cc
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* \brief Kernel backend for execution contexts in userland
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/pd.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Thread::Thread(unsigned const priority, unsigned const quota,
|
||||
char const * const label)
|
||||
:
|
||||
Thread_base(this), Cpu_job(priority, quota), _state(AWAITS_START), _pd(0),
|
||||
_utcb_phys(0), _signal_receiver(0), _label(label)
|
||||
{ cpu_exception = RESET; }
|
||||
|
||||
|
||||
void Thread::_call_new_vm()
|
||||
{
|
||||
/* lookup signal context */
|
||||
auto const context = Signal_context::pool()->object(user_arg_3());
|
||||
if (!context) {
|
||||
PWRN("failed to lookup signal context");
|
||||
user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
/* create virtual machine */
|
||||
typedef Genode::Cpu_state_modes Cpu_state_modes;
|
||||
auto const allocator = reinterpret_cast<void *>(user_arg_1());
|
||||
auto const state = reinterpret_cast<Cpu_state_modes *>(user_arg_2());
|
||||
Vm * const vm = new (allocator) Vm(state, context);
|
||||
|
||||
/* return kernel name of virtual machine */
|
||||
user_arg_0(vm->id());
|
||||
}
|
||||
|
||||
|
||||
void Thread::exception(unsigned const cpu)
|
||||
{
|
||||
switch (cpu_exception) {
|
||||
case SUPERVISOR_CALL:
|
||||
_call();
|
||||
return;
|
||||
case PREFETCH_ABORT:
|
||||
_mmu_exception();
|
||||
return;
|
||||
case DATA_ABORT:
|
||||
_mmu_exception();
|
||||
return;
|
||||
case INTERRUPT_REQUEST:
|
||||
_interrupt(cpu);
|
||||
return;
|
||||
case FAST_INTERRUPT_REQUEST:
|
||||
_interrupt(cpu);
|
||||
return;
|
||||
case UNDEFINED_INSTRUCTION:
|
||||
if (_cpu->retry_undefined_instr(&_lazy_state)) { return; }
|
||||
PWRN("undefined instruction");
|
||||
_stop();
|
||||
return;
|
||||
case RESET:
|
||||
return;
|
||||
default:
|
||||
PWRN("unknown exception");
|
||||
_stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addr_t Thread::* Thread::_reg(addr_t const id) const
|
||||
{
|
||||
static addr_t Thread::* const _regs[] = {
|
||||
/* [0] */ (addr_t Thread::*)&Thread::r0,
|
||||
/* [1] */ (addr_t Thread::*)&Thread::r1,
|
||||
/* [2] */ (addr_t Thread::*)&Thread::r2,
|
||||
/* [3] */ (addr_t Thread::*)&Thread::r3,
|
||||
/* [4] */ (addr_t Thread::*)&Thread::r4,
|
||||
/* [5] */ (addr_t Thread::*)&Thread::r5,
|
||||
/* [6] */ (addr_t Thread::*)&Thread::r6,
|
||||
/* [7] */ (addr_t Thread::*)&Thread::r7,
|
||||
/* [8] */ (addr_t Thread::*)&Thread::r8,
|
||||
/* [9] */ (addr_t Thread::*)&Thread::r9,
|
||||
/* [10] */ (addr_t Thread::*)&Thread::r10,
|
||||
/* [11] */ (addr_t Thread::*)&Thread::r11,
|
||||
/* [12] */ (addr_t Thread::*)&Thread::r12,
|
||||
/* [13] */ (addr_t Thread::*)&Thread::sp,
|
||||
/* [14] */ (addr_t Thread::*)&Thread::lr,
|
||||
/* [15] */ (addr_t Thread::*)&Thread::ip,
|
||||
/* [16] */ (addr_t Thread::*)&Thread::cpsr,
|
||||
/* [17] */ (addr_t Thread::*)&Thread::cpu_exception,
|
||||
/* [18] */ (addr_t Thread::*)&Thread::_fault_pd,
|
||||
/* [19] */ (addr_t Thread::*)&Thread::_fault_addr,
|
||||
/* [20] */ (addr_t Thread::*)&Thread::_fault_writes,
|
||||
/* [21] */ (addr_t Thread::*)&Thread::_fault_signal
|
||||
};
|
||||
return id < sizeof(_regs)/sizeof(_regs[0]) ? _regs[id] : 0;
|
||||
}
|
||||
|
||||
|
||||
Thread_event Thread::* Thread::_event(unsigned const id) const
|
||||
{
|
||||
static Thread_event Thread::* _events[] = {
|
||||
/* [0] */ &Thread::_fault
|
||||
};
|
||||
return id < sizeof(_events)/sizeof(_events[0]) ? _events[id] : 0;
|
||||
}
|
||||
|
||||
|
||||
void Thread::_mmu_exception()
|
||||
{
|
||||
_become_inactive(AWAITS_RESUME);
|
||||
if (in_fault(_fault_addr, _fault_writes)) {
|
||||
_fault_pd = (addr_t)_pd->platform_pd();
|
||||
_fault_signal = _fault.signal_context_id();
|
||||
|
||||
/**
|
||||
* core should never raise a page-fault,
|
||||
* if this happens print out an error message with debug information
|
||||
*/
|
||||
if (_pd == Kernel::core_pd())
|
||||
PERR("Pagefault in core thread (%s): ip=%p fault=%p",
|
||||
label(), (void*)ip, (void*)_fault_addr);
|
||||
|
||||
_fault.submit();
|
||||
return;
|
||||
}
|
||||
PERR("unknown MMU exception");
|
||||
}
|
@ -14,8 +14,6 @@
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/pd.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
@ -34,82 +32,6 @@ Thread_base::Thread_base(Thread * const t)
|
||||
{ }
|
||||
|
||||
|
||||
/********************
|
||||
** Kernel::Thread **
|
||||
********************/
|
||||
|
||||
addr_t Thread::* Thread::_reg(addr_t const id) const
|
||||
{
|
||||
static addr_t Thread::* const _regs[] = {
|
||||
/* [0] */ (addr_t Thread::*)&Thread::r0,
|
||||
/* [1] */ (addr_t Thread::*)&Thread::r1,
|
||||
/* [2] */ (addr_t Thread::*)&Thread::r2,
|
||||
/* [3] */ (addr_t Thread::*)&Thread::r3,
|
||||
/* [4] */ (addr_t Thread::*)&Thread::r4,
|
||||
/* [5] */ (addr_t Thread::*)&Thread::r5,
|
||||
/* [6] */ (addr_t Thread::*)&Thread::r6,
|
||||
/* [7] */ (addr_t Thread::*)&Thread::r7,
|
||||
/* [8] */ (addr_t Thread::*)&Thread::r8,
|
||||
/* [9] */ (addr_t Thread::*)&Thread::r9,
|
||||
/* [10] */ (addr_t Thread::*)&Thread::r10,
|
||||
/* [11] */ (addr_t Thread::*)&Thread::r11,
|
||||
/* [12] */ (addr_t Thread::*)&Thread::r12,
|
||||
/* [13] */ (addr_t Thread::*)&Thread::sp,
|
||||
/* [14] */ (addr_t Thread::*)&Thread::lr,
|
||||
/* [15] */ (addr_t Thread::*)&Thread::ip,
|
||||
/* [16] */ (addr_t Thread::*)&Thread::cpsr,
|
||||
/* [17] */ (addr_t Thread::*)&Thread::cpu_exception,
|
||||
/* [18] */ (addr_t Thread::*)&Thread::_fault_pd,
|
||||
/* [19] */ (addr_t Thread::*)&Thread::_fault_addr,
|
||||
/* [20] */ (addr_t Thread::*)&Thread::_fault_writes,
|
||||
/* [21] */ (addr_t Thread::*)&Thread::_fault_signal
|
||||
};
|
||||
return id < sizeof(_regs)/sizeof(_regs[0]) ? _regs[id] : 0;
|
||||
}
|
||||
|
||||
|
||||
Thread_event Thread::* Thread::_event(unsigned const id) const
|
||||
{
|
||||
static Thread_event Thread::* _events[] = {
|
||||
/* [0] */ &Thread::_fault
|
||||
};
|
||||
return id < sizeof(_events)/sizeof(_events[0]) ? _events[id] : 0;
|
||||
}
|
||||
|
||||
|
||||
void Thread::_mmu_exception()
|
||||
{
|
||||
_become_inactive(AWAITS_RESUME);
|
||||
if (in_fault(_fault_addr, _fault_writes)) {
|
||||
_fault_pd = (addr_t)_pd->platform_pd();
|
||||
_fault_signal = _fault.signal_context_id();
|
||||
|
||||
/**
|
||||
* core should never raise a page-fault,
|
||||
* if this happens print out an error message with debug information
|
||||
*/
|
||||
if (_pd == Kernel::core_pd())
|
||||
PERR("Pagefault in core thread (%s): ip=%p fault=%p",
|
||||
label(), (void*)ip, (void*)_fault_addr);
|
||||
|
||||
_fault.submit();
|
||||
return;
|
||||
}
|
||||
PERR("unknown MMU exception");
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** Kernel::Cpu_context **
|
||||
*************************/
|
||||
|
||||
void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table)
|
||||
{
|
||||
r12 = stack_size;
|
||||
cpu_exception = Genode::Cpu::Ttbr0::init(table);
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** CPU-state utilities **
|
||||
*************************/
|
||||
|
33
repos/base-hw/src/core/spec/arm/kernel/vm.cc
Normal file
33
repos/base-hw/src/core/spec/arm/kernel/vm.cc
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* \brief Kernel backend for virtual machines
|
||||
* \author Martin Stein
|
||||
* \date 2013-10-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/vm.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
void Vm::exception(unsigned const cpu)
|
||||
{
|
||||
switch(_state->cpu_exception) {
|
||||
case Genode::Cpu_state::INTERRUPT_REQUEST:
|
||||
case Genode::Cpu_state::FAST_INTERRUPT_REQUEST:
|
||||
_interrupt(cpu);
|
||||
return;
|
||||
case Genode::Cpu_state::DATA_ABORT:
|
||||
_state->dfar = Cpu::Dfar::read();
|
||||
default:
|
||||
Cpu_job::_deactivate_own_share();
|
||||
_context->submit(1);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user