mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +00:00
base-hw: kernel CPU-pool as Main member
Let the kernel CPU-pool be a member of the one Kernel::Main object instead of having it as global static variable. Ref #4217
This commit is contained in:
parent
be3d5232c8
commit
2b89cd66cb
@ -22,7 +22,8 @@ namespace Board {
|
||||
|
||||
using namespace Hw::Imx6q_sabrelite_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
class Pic : public Hw::Gicv2 { };
|
||||
|
||||
using L2_cache = Hw::Pl310;
|
||||
|
||||
L2_cache & l2_cache();
|
||||
|
@ -22,7 +22,8 @@ namespace Board {
|
||||
|
||||
using namespace Hw::Nit6_solox_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
class Pic : public Hw::Gicv2 { };
|
||||
|
||||
using L2_cache = Hw::Pl310;
|
||||
|
||||
L2_cache & l2_cache();
|
||||
|
@ -22,7 +22,7 @@ namespace Board {
|
||||
|
||||
using namespace Hw::Pbxa9_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
class Pic : public Hw::Gicv2 { };
|
||||
|
||||
L2_cache & l2_cache();
|
||||
}
|
||||
|
@ -51,13 +51,21 @@ namespace Kernel {
|
||||
|
||||
struct Board::Vcpu_context
|
||||
{
|
||||
struct Vm_irq : Kernel::Irq
|
||||
class Vm_irq : public Kernel::Irq
|
||||
{
|
||||
Vm_irq(unsigned const irq, Kernel::Cpu &);
|
||||
virtual ~Vm_irq() {};
|
||||
private:
|
||||
|
||||
virtual void handle(Kernel::Cpu &, Kernel::Vm & vm, unsigned irq);
|
||||
void occurred() override;
|
||||
Kernel::Cpu &_cpu;
|
||||
|
||||
public:
|
||||
|
||||
Vm_irq(unsigned const irq, Kernel::Cpu &cpu);
|
||||
|
||||
virtual ~Vm_irq() {};
|
||||
|
||||
virtual void handle(Kernel::Vm &vm, unsigned irq);
|
||||
|
||||
void occurred() override;
|
||||
};
|
||||
|
||||
|
||||
@ -65,7 +73,7 @@ struct Board::Vcpu_context
|
||||
{
|
||||
Pic_maintainance_irq(Kernel::Cpu &);
|
||||
|
||||
void handle(Kernel::Cpu &, Kernel::Vm &, unsigned) override { }
|
||||
void handle(Kernel::Vm &, unsigned) override { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -24,8 +24,9 @@ namespace Board {
|
||||
using namespace Hw::Wand_quad_board;
|
||||
|
||||
using L2_cache = Hw::Pl310;
|
||||
using Pic = Hw::Gicv2;
|
||||
|
||||
|
||||
class Pic : public Hw::Gicv2 { };
|
||||
|
||||
L2_cache & l2_cache();
|
||||
|
||||
enum {
|
||||
|
@ -24,7 +24,7 @@ namespace Board {
|
||||
|
||||
using namespace Hw::Zynq_qemu_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
class Pic : public Hw::Gicv2 { };
|
||||
|
||||
L2_cache & l2_cache();
|
||||
}
|
||||
|
@ -22,15 +22,9 @@
|
||||
#include <hw/assert.h>
|
||||
#include <hw/boot_info.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Kernel::Cpu_pool &Kernel::cpu_pool() { return *unmanaged_singleton<Cpu_pool>(); }
|
||||
|
||||
|
||||
/*************
|
||||
** Cpu_job **
|
||||
*************/
|
||||
@ -110,9 +104,10 @@ Cpu_job::~Cpu_job()
|
||||
extern "C" void idle_thread_main(void);
|
||||
|
||||
|
||||
Cpu::Idle_thread::Idle_thread(Cpu &cpu)
|
||||
Cpu::Idle_thread::Idle_thread(Cpu_pool &cpu_pool,
|
||||
Cpu &cpu)
|
||||
:
|
||||
Thread("idle")
|
||||
Thread { cpu_pool, "idle" }
|
||||
{
|
||||
regs->ip = (addr_t)&idle_thread_main;
|
||||
|
||||
@ -177,12 +172,15 @@ addr_t Cpu::stack_start()
|
||||
}
|
||||
|
||||
|
||||
Cpu::Cpu(unsigned const id, Inter_processor_work_list & global_work_list)
|
||||
Cpu::Cpu(unsigned const id,
|
||||
Cpu_pool &cpu_pool)
|
||||
:
|
||||
_id(id), _timer(*this),
|
||||
_scheduler(_idle, _quota(), _fill()), _idle(*this),
|
||||
_ipi_irq(*this),
|
||||
_global_work_list(global_work_list)
|
||||
_id { id },
|
||||
_timer { *this },
|
||||
_scheduler { _idle, _quota(), _fill() },
|
||||
_idle { cpu_pool, *this },
|
||||
_ipi_irq { *this },
|
||||
_global_work_list { cpu_pool.work_list() }
|
||||
{
|
||||
_arch_init();
|
||||
}
|
||||
@ -195,7 +193,7 @@ Cpu::Cpu(unsigned const id, Inter_processor_work_list & global_work_list)
|
||||
bool Cpu_pool::initialize()
|
||||
{
|
||||
unsigned id = Cpu::executing_id();
|
||||
_cpus[id].construct(id, _global_work_list);
|
||||
_cpus[id].construct(id, *this);
|
||||
return --_initialized == 0;
|
||||
}
|
||||
|
||||
|
@ -35,11 +35,6 @@ namespace Kernel {
|
||||
* Provides a CPU object for every available CPU
|
||||
*/
|
||||
class Cpu_pool;
|
||||
|
||||
/**
|
||||
* Return singleton of CPU pool
|
||||
*/
|
||||
Cpu_pool &cpu_pool();
|
||||
}
|
||||
|
||||
|
||||
@ -107,7 +102,8 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
||||
/**
|
||||
* Construct idle context for CPU 'cpu'
|
||||
*/
|
||||
Idle_thread(Cpu &cpu);
|
||||
Idle_thread(Cpu_pool &cpu_pool,
|
||||
Cpu &cpu);
|
||||
};
|
||||
|
||||
|
||||
@ -132,8 +128,8 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
||||
/**
|
||||
* Construct object for CPU 'id'
|
||||
*/
|
||||
Cpu(unsigned const id,
|
||||
Inter_processor_work_list & global_work_list);
|
||||
Cpu(unsigned const id,
|
||||
Cpu_pool &cpu_pool);
|
||||
|
||||
static inline unsigned primary_id() { return 0; }
|
||||
|
||||
|
@ -50,7 +50,7 @@ void Cpu::trigger_ip_interrupt()
|
||||
|
||||
Cpu::Ipi::Ipi(Cpu & cpu)
|
||||
:
|
||||
Irq(Board::Pic::IPI, cpu), cpu(cpu)
|
||||
Irq(Board::Pic::IPI, cpu, cpu.pic()), cpu(cpu)
|
||||
{
|
||||
cpu.pic().unmask(Board::Pic::IPI, cpu.id());
|
||||
}
|
||||
|
@ -19,4 +19,7 @@ void Kernel::Cpu::Ipi::occurred() { }
|
||||
void Kernel::Cpu::trigger_ip_interrupt() { }
|
||||
|
||||
|
||||
Kernel::Cpu::Ipi::Ipi(Kernel::Cpu & cpu) : Irq(~0U, cpu), cpu(cpu) { }
|
||||
Kernel::Cpu::Ipi::Ipi(Kernel::Cpu & cpu)
|
||||
:
|
||||
Irq(~0U, cpu, cpu.pic()), cpu(cpu)
|
||||
{ }
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
void Kernel::Irq::disable() const
|
||||
{
|
||||
cpu_pool().executing_cpu().pic().mask(_irq_nr);
|
||||
_pic.mask(_irq_nr);
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Irq::enable() const
|
||||
{
|
||||
cpu_pool().executing_cpu().pic().unmask(_irq_nr, Cpu::executing_id());
|
||||
_pic.unmask(_irq_nr, Cpu::executing_id());
|
||||
}
|
||||
|
||||
|
||||
@ -36,13 +36,15 @@ Kernel::Irq::Pool &Kernel::User_irq::_pool()
|
||||
}
|
||||
|
||||
|
||||
Kernel::User_irq::User_irq(unsigned const irq,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context & context)
|
||||
Kernel::User_irq::User_irq(unsigned const irq,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context &context,
|
||||
Board::Pic &pic)
|
||||
:
|
||||
Irq(irq, _pool()), _context(context)
|
||||
Irq { irq, _pool(), pic },
|
||||
_context { context }
|
||||
{
|
||||
disable();
|
||||
cpu_pool().executing_cpu().pic().irq_mode(_irq_nr, trigger, polarity);
|
||||
_pic.irq_mode(_irq_nr, trigger, polarity);
|
||||
}
|
||||
|
@ -19,12 +19,15 @@
|
||||
#include <irq_session/irq_session.h>
|
||||
#include <util/avl_tree.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/signal_receiver.h>
|
||||
|
||||
namespace Board {
|
||||
|
||||
class Pic;
|
||||
}
|
||||
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
/**
|
||||
@ -67,8 +70,9 @@ class Kernel::Irq : Genode::Avl_node<Irq>
|
||||
|
||||
protected:
|
||||
|
||||
unsigned _irq_nr; /* kernel name of the interrupt */
|
||||
Pool &_pool;
|
||||
unsigned _irq_nr; /* kernel name of the interrupt */
|
||||
Pool &_pool;
|
||||
Board::Pic &_pic;
|
||||
|
||||
public:
|
||||
|
||||
@ -78,9 +82,13 @@ class Kernel::Irq : Genode::Avl_node<Irq>
|
||||
* \param irq interrupt number
|
||||
* \param pool pool this interrupt shall belong to
|
||||
*/
|
||||
Irq(unsigned const irq, Pool &pool)
|
||||
Irq(unsigned const irq,
|
||||
Pool &pool,
|
||||
Board::Pic &pic)
|
||||
:
|
||||
_irq_nr(irq), _pool(pool)
|
||||
_irq_nr { irq },
|
||||
_pool { pool },
|
||||
_pic { pic }
|
||||
{
|
||||
_pool.insert(this);
|
||||
}
|
||||
@ -141,10 +149,11 @@ class Kernel::User_irq : public Kernel::Irq
|
||||
/**
|
||||
* Construct object that signals interrupt 'irq' via signal 'context'
|
||||
*/
|
||||
User_irq(unsigned const irq,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context & context);
|
||||
User_irq(unsigned const irq,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context &context,
|
||||
Board::Pic &pic);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
@ -33,10 +33,12 @@ class Kernel::Main
|
||||
|
||||
friend void main_handle_kernel_entry();
|
||||
friend void main_initialize_and_handle_kernel_entry();
|
||||
friend time_t main_read_idle_thread_execution_time(unsigned cpu_idx);
|
||||
|
||||
static Main *_instance;
|
||||
|
||||
Lock _data_lock { };
|
||||
Lock _data_lock { };
|
||||
Cpu_pool _cpu_pool { };
|
||||
|
||||
void _handle_kernel_entry();
|
||||
};
|
||||
@ -47,7 +49,7 @@ Kernel::Main *Kernel::Main::_instance;
|
||||
|
||||
void Kernel::Main::_handle_kernel_entry()
|
||||
{
|
||||
Cpu &cpu = cpu_pool().cpu(Cpu::executing_id());
|
||||
Cpu &cpu = _cpu_pool.cpu(Cpu::executing_id());
|
||||
Cpu_job * new_job;
|
||||
|
||||
{
|
||||
@ -98,7 +100,7 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
instance_initialized = true;
|
||||
|
||||
/* initialize current cpu */
|
||||
pool_ready = cpu_pool().initialize();
|
||||
pool_ready = Main::_instance->_cpu_pool.initialize();
|
||||
};
|
||||
|
||||
/* wait until all cpus have initialized their corresponding cpu object */
|
||||
@ -112,7 +114,7 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
Boot_info &boot_info {
|
||||
*reinterpret_cast<Boot_info*>(Hw::Mm::boot_info().base) };
|
||||
|
||||
cpu_pool().for_each_cpu([&] (Kernel::Cpu &cpu) {
|
||||
Main::_instance->_cpu_pool.for_each_cpu([&] (Kernel::Cpu &cpu) {
|
||||
boot_info.kernel_irqs.add(cpu.timer().interrupt_id());
|
||||
});
|
||||
boot_info.kernel_irqs.add((unsigned)Board::Pic::IPI);
|
||||
@ -120,7 +122,7 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
Genode::log("");
|
||||
Genode::log("kernel initialized");
|
||||
|
||||
Core_main_thread::singleton();
|
||||
Core_main_thread::initialize_instance(Main::_instance->_cpu_pool);
|
||||
kernel_ready = true;
|
||||
} else {
|
||||
/* secondary cpus spin until the kernel is initialized */
|
||||
@ -133,5 +135,5 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
|
||||
Kernel::time_t Kernel::main_read_idle_thread_execution_time(unsigned cpu_idx)
|
||||
{
|
||||
return cpu_pool().cpu(cpu_idx).idle_thread().execution_time();
|
||||
return Main::_instance->_cpu_pool.cpu(cpu_idx).idle_thread().execution_time();
|
||||
}
|
||||
|
@ -111,13 +111,22 @@ void Thread::ipc_copy_msg(Thread &sender)
|
||||
}
|
||||
|
||||
|
||||
Thread::Tlb_invalidation::Tlb_invalidation(Thread & caller, Pd & pd,
|
||||
addr_t addr, size_t size,
|
||||
unsigned cnt)
|
||||
Thread::
|
||||
Tlb_invalidation::Tlb_invalidation(Inter_processor_work_list &global_work_list,
|
||||
Thread &caller,
|
||||
Pd &pd,
|
||||
addr_t addr,
|
||||
size_t size,
|
||||
unsigned cnt)
|
||||
:
|
||||
caller(caller), pd(pd), addr(addr), size(size), cnt(cnt)
|
||||
global_work_list { global_work_list },
|
||||
caller { caller },
|
||||
pd { pd },
|
||||
addr { addr },
|
||||
size { size },
|
||||
cnt { cnt }
|
||||
{
|
||||
cpu_pool().work_list().insert(&_le);
|
||||
global_work_list.insert(&_le);
|
||||
caller._become_inactive(AWAITS_RESTART);
|
||||
}
|
||||
|
||||
@ -131,10 +140,11 @@ Thread::Destroy::Destroy(Thread & caller, Genode::Kernel_object<Thread> & to_del
|
||||
}
|
||||
|
||||
|
||||
void Thread::Destroy::execute()
|
||||
void
|
||||
Thread::Destroy::execute()
|
||||
{
|
||||
thread_to_destroy->_cpu->work_list().remove(&_le);
|
||||
thread_to_destroy.destruct();
|
||||
cpu_pool().executing_cpu().work_list().remove(&_le);
|
||||
caller._restart();
|
||||
}
|
||||
|
||||
@ -280,7 +290,7 @@ void Thread::_call_thread_quota()
|
||||
void Thread::_call_start_thread()
|
||||
{
|
||||
/* lookup CPU */
|
||||
Cpu & cpu = cpu_pool().cpu(user_arg_2());
|
||||
Cpu & cpu = _cpu_pool.cpu(user_arg_2());
|
||||
user_arg_0(0);
|
||||
Thread &thread = *(Thread*)user_arg_1();
|
||||
|
||||
@ -648,7 +658,9 @@ void Thread::_call_new_irq()
|
||||
Genode::Irq_session::Polarity polarity =
|
||||
(Genode::Irq_session::Polarity) (user_arg_3() & 0b11);
|
||||
|
||||
_call_new<User_irq>((unsigned)user_arg_2(), trigger, polarity, *c);
|
||||
_call_new<User_irq>(
|
||||
(unsigned)user_arg_2(), trigger, polarity, *c,
|
||||
_cpu_pool.executing_cpu().pic());
|
||||
}
|
||||
|
||||
|
||||
@ -709,12 +721,15 @@ void Kernel::Thread::_call_invalidate_tlb()
|
||||
size_t size = (size_t) user_arg_3();
|
||||
unsigned cnt = 0;
|
||||
|
||||
cpu_pool().for_each_cpu([&] (Cpu & cpu) {
|
||||
_cpu_pool.for_each_cpu([&] (Cpu & cpu) {
|
||||
/* if a cpu needs to update increase the counter */
|
||||
if (pd->invalidate_tlb(cpu, addr, size)) cnt++; });
|
||||
|
||||
/* insert the work item in the list if there are outstanding cpus */
|
||||
if (cnt) _tlb_invalidation.construct(*this, *pd, addr, size, cnt);
|
||||
if (cnt) {
|
||||
_tlb_invalidation.construct(
|
||||
_cpu_pool.work_list(), *this, *pd, addr, size, cnt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -759,12 +774,12 @@ void Thread::_call()
|
||||
/* switch over kernel calls that are restricted to core */
|
||||
switch (call_id) {
|
||||
case call_id_new_thread():
|
||||
_call_new<Thread>((unsigned) user_arg_2(),
|
||||
_call_new<Thread>(_cpu_pool, (unsigned) user_arg_2(),
|
||||
(unsigned) _core_to_kernel_quota(user_arg_3()),
|
||||
(char const *) user_arg_4());
|
||||
return;
|
||||
case call_id_new_core_thread():
|
||||
_call_new<Thread>((char const *) user_arg_2());
|
||||
_call_new<Thread>(_cpu_pool, (char const *) user_arg_2());
|
||||
return;
|
||||
case call_id_thread_quota(): _call_thread_quota(); return;
|
||||
case call_id_delete_thread(): _call_delete_thread(); return;
|
||||
@ -821,12 +836,20 @@ void Thread::_mmu_exception()
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(unsigned const priority, unsigned const quota,
|
||||
char const * const label, bool core)
|
||||
Thread::Thread(Cpu_pool &cpu_pool,
|
||||
unsigned const priority,
|
||||
unsigned const quota,
|
||||
char const *const label,
|
||||
bool core)
|
||||
:
|
||||
Kernel::Object { *this },
|
||||
Cpu_job(priority, quota), _ipc_node(*this), _state(AWAITS_START),
|
||||
_label(label), _core(core), regs(core)
|
||||
Cpu_job { priority, quota },
|
||||
_cpu_pool { cpu_pool },
|
||||
_ipc_node { *this },
|
||||
_state { AWAITS_START },
|
||||
_label { label },
|
||||
_core { core },
|
||||
regs { core }
|
||||
{ }
|
||||
|
||||
|
||||
@ -848,9 +871,9 @@ Genode::uint8_t __initial_stack_base[DEFAULT_STACK_SIZE];
|
||||
** Core_main_thread **
|
||||
**********************/
|
||||
|
||||
Core_main_thread::Core_main_thread()
|
||||
Core_main_thread::Core_main_thread(Cpu_pool &cpu_pool)
|
||||
:
|
||||
Core_object<Thread>("core")
|
||||
Core_object<Thread>(cpu_pool, "core")
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -870,15 +893,18 @@ Core_main_thread::Core_main_thread()
|
||||
regs->sp = (addr_t)&__initial_stack_base[0] + DEFAULT_STACK_SIZE;
|
||||
regs->ip = (addr_t)&_core_start;
|
||||
|
||||
affinity(cpu_pool().primary_cpu());
|
||||
affinity(_cpu_pool.primary_cpu());
|
||||
_utcb = utcb;
|
||||
Thread::_pd = &core_pd();
|
||||
_become_active();
|
||||
}
|
||||
|
||||
|
||||
Thread & Core_main_thread::singleton()
|
||||
Core_main_thread *Core_main_thread::_instance;
|
||||
|
||||
|
||||
void Core_main_thread::initialize_instance(Cpu_pool &cpu_pool)
|
||||
{
|
||||
static Core_main_thread cmt;
|
||||
return cmt;
|
||||
static Core_main_thread instance { cpu_pool };
|
||||
_instance = &instance;
|
||||
}
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include <base/internal/native_utcb.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class Cpu_pool;
|
||||
struct Thread_fault;
|
||||
class Thread;
|
||||
class Core_main_thread;
|
||||
@ -69,14 +71,19 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
||||
*/
|
||||
struct Tlb_invalidation : Inter_processor_work
|
||||
{
|
||||
Thread & caller; /* the caller gets blocked until all finished */
|
||||
Pd & pd; /* the corresponding pd */
|
||||
addr_t addr;
|
||||
size_t size;
|
||||
unsigned cnt; /* count of cpus left */
|
||||
Inter_processor_work_list &global_work_list;
|
||||
Thread &caller; /* the caller gets blocked until all finished */
|
||||
Pd &pd; /* the corresponding pd */
|
||||
addr_t addr;
|
||||
size_t size;
|
||||
unsigned cnt; /* count of cpus left */
|
||||
|
||||
Tlb_invalidation(Thread & caller, Pd & pd, addr_t addr, size_t size,
|
||||
unsigned cnt);
|
||||
Tlb_invalidation(Inter_processor_work_list &global_work_list,
|
||||
Thread &caller,
|
||||
Pd &pd,
|
||||
addr_t addr,
|
||||
size_t size,
|
||||
unsigned cnt);
|
||||
|
||||
/************************************
|
||||
** Inter_processor_work interface **
|
||||
@ -124,6 +131,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
||||
|
||||
enum { MAX_RCV_CAPS = Genode::Msgbuf_base::MAX_CAPS_PER_MSG };
|
||||
|
||||
Cpu_pool &_cpu_pool;
|
||||
void *_obj_id_ref_ptr[MAX_RCV_CAPS] { nullptr };
|
||||
Ipc_node _ipc_node;
|
||||
capid_t _ipc_capid { cap_id_invalid() };
|
||||
@ -284,16 +292,22 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
||||
* \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, bool core = false);
|
||||
Thread(Cpu_pool &cpu_pool,
|
||||
unsigned const priority,
|
||||
unsigned const quota,
|
||||
char const *const label,
|
||||
bool core = false);
|
||||
|
||||
/**
|
||||
* Constructor for core/kernel thread
|
||||
*
|
||||
* \param label debugging label
|
||||
*/
|
||||
Thread(char const * const label)
|
||||
: Thread(Cpu_priority::min(), 0, label, true) { }
|
||||
Thread(Cpu_pool &cpu_pool,
|
||||
char const *const label)
|
||||
:
|
||||
Thread(cpu_pool, Cpu_priority::min(), 0, label, true)
|
||||
{ }
|
||||
|
||||
~Thread();
|
||||
|
||||
@ -422,11 +436,19 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
||||
/**
|
||||
* The first core thread in the system bootstrapped by the Kernel
|
||||
*/
|
||||
struct Kernel::Core_main_thread : Core_object<Kernel::Thread>
|
||||
class Kernel::Core_main_thread : public Core_object<Kernel::Thread>
|
||||
{
|
||||
Core_main_thread();
|
||||
private:
|
||||
|
||||
static Thread & singleton();
|
||||
static Core_main_thread *_instance;
|
||||
|
||||
public:
|
||||
|
||||
Core_main_thread(Cpu_pool &cpu_pool);
|
||||
|
||||
static void initialize_instance(Cpu_pool &cpu_pool);
|
||||
|
||||
static Thread &instance() { return *_instance; };
|
||||
};
|
||||
|
||||
#endif /* _CORE__KERNEL__THREAD_H_ */
|
||||
|
@ -25,7 +25,8 @@ void Timer::Irq::occurred() { _cpu.scheduler().timeout(); }
|
||||
|
||||
Timer::Irq::Irq(unsigned id, Cpu &cpu)
|
||||
:
|
||||
Kernel::Irq(id, cpu.irq_pool()), _cpu(cpu)
|
||||
Kernel::Irq { id, cpu.irq_pool(), cpu.pic() },
|
||||
_cpu { cpu }
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -71,7 +71,7 @@ class Kernel::Vm : private Kernel::Object, public Cpu_job
|
||||
* \param state initial CPU state
|
||||
* \param context signal for VM exceptions other than interrupts
|
||||
*/
|
||||
Vm(unsigned cpu,
|
||||
Vm(Cpu & cpu,
|
||||
State & state,
|
||||
Signal_context & context,
|
||||
Identity & id);
|
||||
|
@ -14,6 +14,7 @@
|
||||
/* core includes */
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <kernel/cpu.h>
|
||||
|
||||
void Kernel::Thread::_call_new_vm()
|
||||
{
|
||||
@ -24,7 +25,8 @@ void Kernel::Thread::_call_new_vm()
|
||||
return;
|
||||
}
|
||||
|
||||
_call_new<Vm>((unsigned)user_arg_2(), *(Board::Vm_state*)user_arg_3(),
|
||||
_call_new<Vm>(_cpu_pool.cpu((unsigned)user_arg_2()),
|
||||
*(Board::Vm_state*)user_arg_3(),
|
||||
*context, *(Vm::Identity*)user_arg_4());
|
||||
}
|
||||
|
||||
|
@ -38,13 +38,21 @@ namespace Kernel {
|
||||
|
||||
struct Board::Vcpu_context
|
||||
{
|
||||
struct Vm_irq : Kernel::Irq
|
||||
class Vm_irq : public Kernel::Irq
|
||||
{
|
||||
Vm_irq(unsigned const irq, Kernel::Cpu &);
|
||||
virtual ~Vm_irq() {};
|
||||
private:
|
||||
|
||||
virtual void handle(Kernel::Cpu &, Kernel::Vm & vm, unsigned irq);
|
||||
void occurred() override;
|
||||
Kernel::Cpu &_cpu;
|
||||
|
||||
public:
|
||||
|
||||
Vm_irq(unsigned const irq, Kernel::Cpu &cpu);
|
||||
|
||||
virtual ~Vm_irq() { };
|
||||
|
||||
virtual void handle(Kernel::Vm &vm, unsigned irq);
|
||||
|
||||
void occurred() override;
|
||||
};
|
||||
|
||||
|
||||
@ -52,7 +60,7 @@ struct Board::Vcpu_context
|
||||
{
|
||||
Pic_maintainance_irq(Kernel::Cpu &);
|
||||
|
||||
void handle(Kernel::Cpu &, Kernel::Vm &, unsigned) override { }
|
||||
void handle(Kernel::Vm &, unsigned) override { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Kernel::Vm::Vm(unsigned,
|
||||
Kernel::Vm::Vm(Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
@ -30,9 +30,9 @@ Kernel::Vm::Vm(unsigned,
|
||||
_state(state),
|
||||
_context(context),
|
||||
_id(id),
|
||||
_vcpu_context(cpu_pool().primary_cpu())
|
||||
_vcpu_context(cpu)
|
||||
{
|
||||
affinity(cpu_pool().primary_cpu());
|
||||
affinity(cpu);
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,20 +91,20 @@ static Host_context & host_context(Cpu & cpu)
|
||||
|
||||
Board::Vcpu_context::Vm_irq::Vm_irq(unsigned const irq, Cpu & cpu)
|
||||
:
|
||||
Kernel::Irq(irq, cpu.irq_pool())
|
||||
Kernel::Irq { irq, cpu.irq_pool(), cpu.pic() },
|
||||
_cpu { cpu }
|
||||
{ }
|
||||
|
||||
|
||||
void Board::Vcpu_context::Vm_irq::handle(Cpu &, Vm & vm, unsigned irq) {
|
||||
void Board::Vcpu_context::Vm_irq::handle(Vm & vm, unsigned irq) {
|
||||
vm.inject_irq(irq); }
|
||||
|
||||
|
||||
void Board::Vcpu_context::Vm_irq::occurred()
|
||||
{
|
||||
Cpu & cpu = Kernel::cpu_pool().executing_cpu();
|
||||
Vm *vm = dynamic_cast<Vm*>(&cpu.scheduled_job());
|
||||
Vm *vm = dynamic_cast<Vm*>(&_cpu.scheduled_job());
|
||||
if (!vm) Genode::raw("VM interrupt while VM is not runnning!");
|
||||
else handle(cpu, *vm, _irq_nr);
|
||||
else handle(*vm, _irq_nr);
|
||||
}
|
||||
|
||||
|
||||
@ -134,7 +134,7 @@ void Board::Vcpu_context::Virtual_timer_irq::disable()
|
||||
}
|
||||
|
||||
|
||||
Kernel::Vm::Vm(unsigned cpu,
|
||||
Kernel::Vm::Vm(Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
@ -144,9 +144,9 @@ Kernel::Vm::Vm(unsigned cpu,
|
||||
_state(state),
|
||||
_context(context),
|
||||
_id(id),
|
||||
_vcpu_context(cpu_pool().cpu(cpu))
|
||||
_vcpu_context(cpu)
|
||||
{
|
||||
affinity(cpu_pool().cpu(cpu));
|
||||
affinity(cpu);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,11 +11,17 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* base includes */
|
||||
#include <util/bit_allocator.h>
|
||||
#include <cpu/memory_barrier.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
|
||||
/* base-hw Core includes */
|
||||
#include <board.h>
|
||||
#include <cpu.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <cpu/memory_barrier.h>
|
||||
#include <util/bit_allocator.h>
|
||||
|
||||
|
||||
Genode::Cpu::Context::Context(bool privileged)
|
||||
|
@ -66,20 +66,20 @@ static Genode::Vm_state & host_context(Cpu & cpu)
|
||||
|
||||
Board::Vcpu_context::Vm_irq::Vm_irq(unsigned const irq, Cpu & cpu)
|
||||
:
|
||||
Kernel::Irq(irq, cpu.irq_pool())
|
||||
Kernel::Irq { irq, cpu.irq_pool(), cpu.pic() },
|
||||
_cpu { cpu }
|
||||
{ }
|
||||
|
||||
|
||||
void Board::Vcpu_context::Vm_irq::handle(Cpu &, Vm & vm, unsigned irq) {
|
||||
void Board::Vcpu_context::Vm_irq::handle(Vm & vm, unsigned irq) {
|
||||
vm.inject_irq(irq); }
|
||||
|
||||
|
||||
void Board::Vcpu_context::Vm_irq::occurred()
|
||||
{
|
||||
Cpu & cpu = Kernel::cpu_pool().executing_cpu();
|
||||
Vm *vm = dynamic_cast<Vm*>(&cpu.scheduled_job());
|
||||
Vm *vm = dynamic_cast<Vm*>(&_cpu.scheduled_job());
|
||||
if (!vm) Genode::raw("VM interrupt while VM is not runnning!");
|
||||
else handle(cpu, *vm, _irq_nr);
|
||||
else handle(*vm, _irq_nr);
|
||||
}
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ void Board::Vcpu_context::Virtual_timer_irq::disable()
|
||||
}
|
||||
|
||||
|
||||
Vm::Vm(unsigned cpu,
|
||||
Vm::Vm(Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
@ -119,9 +119,9 @@ Vm::Vm(unsigned cpu,
|
||||
_state(state),
|
||||
_context(context),
|
||||
_id(id),
|
||||
_vcpu_context(cpu_pool().cpu(cpu))
|
||||
_vcpu_context(cpu)
|
||||
{
|
||||
affinity(cpu_pool().cpu(cpu));
|
||||
affinity(cpu);
|
||||
|
||||
_state.id_aa64isar0_el1 = Cpu::Id_aa64isar0_el1::read();
|
||||
_state.id_aa64isar1_el1 = Cpu::Id_aa64isar1_el1::read();
|
||||
|
@ -26,7 +26,7 @@ void Kernel::Thread::Tlb_invalidation::execute()
|
||||
|
||||
/* if this is the last cpu, wake up the caller thread */
|
||||
if (--cnt == 0) {
|
||||
cpu_pool().work_list().remove(&_le);
|
||||
global_work_list.remove(&_le);
|
||||
caller._restart();
|
||||
}
|
||||
};
|
||||
|
@ -93,7 +93,7 @@ void Thread::_init_platform_thread(size_t, Type type)
|
||||
}
|
||||
|
||||
/* remap initial main-thread UTCB according to stack-area spec */
|
||||
Genode::map_local(Platform::core_phys_addr((addr_t)Kernel::Core_main_thread::singleton().utcb()),
|
||||
Genode::map_local(Platform::core_phys_addr((addr_t)Kernel::Core_main_thread::instance().utcb()),
|
||||
(addr_t)&_stack->utcb(),
|
||||
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user