mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-12 05:55:37 +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 namespace Hw::Imx6q_sabrelite_board;
|
||||||
|
|
||||||
using Pic = Hw::Gicv2;
|
class Pic : public Hw::Gicv2 { };
|
||||||
|
|
||||||
using L2_cache = Hw::Pl310;
|
using L2_cache = Hw::Pl310;
|
||||||
|
|
||||||
L2_cache & l2_cache();
|
L2_cache & l2_cache();
|
||||||
|
@ -22,7 +22,8 @@ namespace Board {
|
|||||||
|
|
||||||
using namespace Hw::Nit6_solox_board;
|
using namespace Hw::Nit6_solox_board;
|
||||||
|
|
||||||
using Pic = Hw::Gicv2;
|
class Pic : public Hw::Gicv2 { };
|
||||||
|
|
||||||
using L2_cache = Hw::Pl310;
|
using L2_cache = Hw::Pl310;
|
||||||
|
|
||||||
L2_cache & l2_cache();
|
L2_cache & l2_cache();
|
||||||
|
@ -22,7 +22,7 @@ namespace Board {
|
|||||||
|
|
||||||
using namespace Hw::Pbxa9_board;
|
using namespace Hw::Pbxa9_board;
|
||||||
|
|
||||||
using Pic = Hw::Gicv2;
|
class Pic : public Hw::Gicv2 { };
|
||||||
|
|
||||||
L2_cache & l2_cache();
|
L2_cache & l2_cache();
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,20 @@ namespace Kernel {
|
|||||||
|
|
||||||
struct Board::Vcpu_context
|
struct Board::Vcpu_context
|
||||||
{
|
{
|
||||||
struct Vm_irq : Kernel::Irq
|
class Vm_irq : public Kernel::Irq
|
||||||
{
|
{
|
||||||
Vm_irq(unsigned const irq, Kernel::Cpu &);
|
private:
|
||||||
|
|
||||||
|
Kernel::Cpu &_cpu;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Vm_irq(unsigned const irq, Kernel::Cpu &cpu);
|
||||||
|
|
||||||
virtual ~Vm_irq() {};
|
virtual ~Vm_irq() {};
|
||||||
|
|
||||||
virtual void handle(Kernel::Cpu &, Kernel::Vm & vm, unsigned irq);
|
virtual void handle(Kernel::Vm &vm, unsigned irq);
|
||||||
|
|
||||||
void occurred() override;
|
void occurred() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,7 +73,7 @@ struct Board::Vcpu_context
|
|||||||
{
|
{
|
||||||
Pic_maintainance_irq(Kernel::Cpu &);
|
Pic_maintainance_irq(Kernel::Cpu &);
|
||||||
|
|
||||||
void handle(Kernel::Cpu &, Kernel::Vm &, unsigned) override { }
|
void handle(Kernel::Vm &, unsigned) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ namespace Board {
|
|||||||
using namespace Hw::Wand_quad_board;
|
using namespace Hw::Wand_quad_board;
|
||||||
|
|
||||||
using L2_cache = Hw::Pl310;
|
using L2_cache = Hw::Pl310;
|
||||||
using Pic = Hw::Gicv2;
|
|
||||||
|
class Pic : public Hw::Gicv2 { };
|
||||||
|
|
||||||
L2_cache & l2_cache();
|
L2_cache & l2_cache();
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ namespace Board {
|
|||||||
|
|
||||||
using namespace Hw::Zynq_qemu_board;
|
using namespace Hw::Zynq_qemu_board;
|
||||||
|
|
||||||
using Pic = Hw::Gicv2;
|
class Pic : public Hw::Gicv2 { };
|
||||||
|
|
||||||
L2_cache & l2_cache();
|
L2_cache & l2_cache();
|
||||||
}
|
}
|
||||||
|
@ -22,15 +22,9 @@
|
|||||||
#include <hw/assert.h>
|
#include <hw/assert.h>
|
||||||
#include <hw/boot_info.h>
|
#include <hw/boot_info.h>
|
||||||
|
|
||||||
/* base-internal includes */
|
|
||||||
#include <base/internal/unmanaged_singleton.h>
|
|
||||||
|
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
|
|
||||||
Kernel::Cpu_pool &Kernel::cpu_pool() { return *unmanaged_singleton<Cpu_pool>(); }
|
|
||||||
|
|
||||||
|
|
||||||
/*************
|
/*************
|
||||||
** Cpu_job **
|
** Cpu_job **
|
||||||
*************/
|
*************/
|
||||||
@ -110,9 +104,10 @@ Cpu_job::~Cpu_job()
|
|||||||
extern "C" void idle_thread_main(void);
|
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;
|
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),
|
_id { id },
|
||||||
_scheduler(_idle, _quota(), _fill()), _idle(*this),
|
_timer { *this },
|
||||||
_ipi_irq(*this),
|
_scheduler { _idle, _quota(), _fill() },
|
||||||
_global_work_list(global_work_list)
|
_idle { cpu_pool, *this },
|
||||||
|
_ipi_irq { *this },
|
||||||
|
_global_work_list { cpu_pool.work_list() }
|
||||||
{
|
{
|
||||||
_arch_init();
|
_arch_init();
|
||||||
}
|
}
|
||||||
@ -195,7 +193,7 @@ Cpu::Cpu(unsigned const id, Inter_processor_work_list & global_work_list)
|
|||||||
bool Cpu_pool::initialize()
|
bool Cpu_pool::initialize()
|
||||||
{
|
{
|
||||||
unsigned id = Cpu::executing_id();
|
unsigned id = Cpu::executing_id();
|
||||||
_cpus[id].construct(id, _global_work_list);
|
_cpus[id].construct(id, *this);
|
||||||
return --_initialized == 0;
|
return --_initialized == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +35,6 @@ namespace Kernel {
|
|||||||
* Provides a CPU object for every available CPU
|
* Provides a CPU object for every available CPU
|
||||||
*/
|
*/
|
||||||
class Cpu_pool;
|
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'
|
* Construct idle context for CPU 'cpu'
|
||||||
*/
|
*/
|
||||||
Idle_thread(Cpu &cpu);
|
Idle_thread(Cpu_pool &cpu_pool,
|
||||||
|
Cpu &cpu);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -133,7 +129,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
|||||||
* Construct object for CPU 'id'
|
* Construct object for CPU 'id'
|
||||||
*/
|
*/
|
||||||
Cpu(unsigned const id,
|
Cpu(unsigned const id,
|
||||||
Inter_processor_work_list & global_work_list);
|
Cpu_pool &cpu_pool);
|
||||||
|
|
||||||
static inline unsigned primary_id() { return 0; }
|
static inline unsigned primary_id() { return 0; }
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ void Cpu::trigger_ip_interrupt()
|
|||||||
|
|
||||||
Cpu::Ipi::Ipi(Cpu & cpu)
|
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());
|
cpu.pic().unmask(Board::Pic::IPI, cpu.id());
|
||||||
}
|
}
|
||||||
|
@ -19,4 +19,7 @@ void Kernel::Cpu::Ipi::occurred() { }
|
|||||||
void Kernel::Cpu::trigger_ip_interrupt() { }
|
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
|
void Kernel::Irq::disable() const
|
||||||
{
|
{
|
||||||
cpu_pool().executing_cpu().pic().mask(_irq_nr);
|
_pic.mask(_irq_nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Kernel::Irq::enable() const
|
void Kernel::Irq::enable() const
|
||||||
{
|
{
|
||||||
cpu_pool().executing_cpu().pic().unmask(_irq_nr, Cpu::executing_id());
|
_pic.unmask(_irq_nr, Cpu::executing_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,10 +39,12 @@ Kernel::Irq::Pool &Kernel::User_irq::_pool()
|
|||||||
Kernel::User_irq::User_irq(unsigned const irq,
|
Kernel::User_irq::User_irq(unsigned const irq,
|
||||||
Genode::Irq_session::Trigger trigger,
|
Genode::Irq_session::Trigger trigger,
|
||||||
Genode::Irq_session::Polarity polarity,
|
Genode::Irq_session::Polarity polarity,
|
||||||
Signal_context & context)
|
Signal_context &context,
|
||||||
|
Board::Pic &pic)
|
||||||
:
|
:
|
||||||
Irq(irq, _pool()), _context(context)
|
Irq { irq, _pool(), pic },
|
||||||
|
_context { context }
|
||||||
{
|
{
|
||||||
disable();
|
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 <irq_session/irq_session.h>
|
||||||
#include <util/avl_tree.h>
|
#include <util/avl_tree.h>
|
||||||
|
|
||||||
/* base-internal includes */
|
|
||||||
#include <base/internal/unmanaged_singleton.h>
|
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <kernel/signal_receiver.h>
|
#include <kernel/signal_receiver.h>
|
||||||
|
|
||||||
|
namespace Board {
|
||||||
|
|
||||||
|
class Pic;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,6 +72,7 @@ class Kernel::Irq : Genode::Avl_node<Irq>
|
|||||||
|
|
||||||
unsigned _irq_nr; /* kernel name of the interrupt */
|
unsigned _irq_nr; /* kernel name of the interrupt */
|
||||||
Pool &_pool;
|
Pool &_pool;
|
||||||
|
Board::Pic &_pic;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -78,9 +82,13 @@ class Kernel::Irq : Genode::Avl_node<Irq>
|
|||||||
* \param irq interrupt number
|
* \param irq interrupt number
|
||||||
* \param pool pool this interrupt shall belong to
|
* \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);
|
_pool.insert(this);
|
||||||
}
|
}
|
||||||
@ -144,7 +152,8 @@ class Kernel::User_irq : public Kernel::Irq
|
|||||||
User_irq(unsigned const irq,
|
User_irq(unsigned const irq,
|
||||||
Genode::Irq_session::Trigger trigger,
|
Genode::Irq_session::Trigger trigger,
|
||||||
Genode::Irq_session::Polarity polarity,
|
Genode::Irq_session::Polarity polarity,
|
||||||
Signal_context & context);
|
Signal_context &context,
|
||||||
|
Board::Pic &pic);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
|
@ -33,10 +33,12 @@ class Kernel::Main
|
|||||||
|
|
||||||
friend void main_handle_kernel_entry();
|
friend void main_handle_kernel_entry();
|
||||||
friend void main_initialize_and_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;
|
static Main *_instance;
|
||||||
|
|
||||||
Lock _data_lock { };
|
Lock _data_lock { };
|
||||||
|
Cpu_pool _cpu_pool { };
|
||||||
|
|
||||||
void _handle_kernel_entry();
|
void _handle_kernel_entry();
|
||||||
};
|
};
|
||||||
@ -47,7 +49,7 @@ Kernel::Main *Kernel::Main::_instance;
|
|||||||
|
|
||||||
void Kernel::Main::_handle_kernel_entry()
|
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;
|
Cpu_job * new_job;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -98,7 +100,7 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
|||||||
instance_initialized = true;
|
instance_initialized = true;
|
||||||
|
|
||||||
/* initialize current cpu */
|
/* 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 */
|
/* 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 {
|
Boot_info &boot_info {
|
||||||
*reinterpret_cast<Boot_info*>(Hw::Mm::boot_info().base) };
|
*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(cpu.timer().interrupt_id());
|
||||||
});
|
});
|
||||||
boot_info.kernel_irqs.add((unsigned)Board::Pic::IPI);
|
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("");
|
||||||
Genode::log("kernel initialized");
|
Genode::log("kernel initialized");
|
||||||
|
|
||||||
Core_main_thread::singleton();
|
Core_main_thread::initialize_instance(Main::_instance->_cpu_pool);
|
||||||
kernel_ready = true;
|
kernel_ready = true;
|
||||||
} else {
|
} else {
|
||||||
/* secondary cpus spin until the kernel is initialized */
|
/* 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)
|
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,
|
Thread::
|
||||||
addr_t addr, size_t size,
|
Tlb_invalidation::Tlb_invalidation(Inter_processor_work_list &global_work_list,
|
||||||
|
Thread &caller,
|
||||||
|
Pd &pd,
|
||||||
|
addr_t addr,
|
||||||
|
size_t size,
|
||||||
unsigned cnt)
|
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);
|
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();
|
thread_to_destroy.destruct();
|
||||||
cpu_pool().executing_cpu().work_list().remove(&_le);
|
|
||||||
caller._restart();
|
caller._restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +290,7 @@ void Thread::_call_thread_quota()
|
|||||||
void Thread::_call_start_thread()
|
void Thread::_call_start_thread()
|
||||||
{
|
{
|
||||||
/* lookup CPU */
|
/* lookup CPU */
|
||||||
Cpu & cpu = cpu_pool().cpu(user_arg_2());
|
Cpu & cpu = _cpu_pool.cpu(user_arg_2());
|
||||||
user_arg_0(0);
|
user_arg_0(0);
|
||||||
Thread &thread = *(Thread*)user_arg_1();
|
Thread &thread = *(Thread*)user_arg_1();
|
||||||
|
|
||||||
@ -648,7 +658,9 @@ void Thread::_call_new_irq()
|
|||||||
Genode::Irq_session::Polarity polarity =
|
Genode::Irq_session::Polarity polarity =
|
||||||
(Genode::Irq_session::Polarity) (user_arg_3() & 0b11);
|
(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();
|
size_t size = (size_t) user_arg_3();
|
||||||
unsigned cnt = 0;
|
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 a cpu needs to update increase the counter */
|
||||||
if (pd->invalidate_tlb(cpu, addr, size)) cnt++; });
|
if (pd->invalidate_tlb(cpu, addr, size)) cnt++; });
|
||||||
|
|
||||||
/* insert the work item in the list if there are outstanding cpus */
|
/* 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 over kernel calls that are restricted to core */
|
||||||
switch (call_id) {
|
switch (call_id) {
|
||||||
case call_id_new_thread():
|
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()),
|
(unsigned) _core_to_kernel_quota(user_arg_3()),
|
||||||
(char const *) user_arg_4());
|
(char const *) user_arg_4());
|
||||||
return;
|
return;
|
||||||
case call_id_new_core_thread():
|
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;
|
return;
|
||||||
case call_id_thread_quota(): _call_thread_quota(); return;
|
case call_id_thread_quota(): _call_thread_quota(); return;
|
||||||
case call_id_delete_thread(): _call_delete_thread(); 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,
|
Thread::Thread(Cpu_pool &cpu_pool,
|
||||||
char const * const label, bool core)
|
unsigned const priority,
|
||||||
|
unsigned const quota,
|
||||||
|
char const *const label,
|
||||||
|
bool core)
|
||||||
:
|
:
|
||||||
Kernel::Object { *this },
|
Kernel::Object { *this },
|
||||||
Cpu_job(priority, quota), _ipc_node(*this), _state(AWAITS_START),
|
Cpu_job { priority, quota },
|
||||||
_label(label), _core(core), regs(core)
|
_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::Core_main_thread(Cpu_pool &cpu_pool)
|
||||||
:
|
:
|
||||||
Core_object<Thread>("core")
|
Core_object<Thread>(cpu_pool, "core")
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
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->sp = (addr_t)&__initial_stack_base[0] + DEFAULT_STACK_SIZE;
|
||||||
regs->ip = (addr_t)&_core_start;
|
regs->ip = (addr_t)&_core_start;
|
||||||
|
|
||||||
affinity(cpu_pool().primary_cpu());
|
affinity(_cpu_pool.primary_cpu());
|
||||||
_utcb = utcb;
|
_utcb = utcb;
|
||||||
Thread::_pd = &core_pd();
|
Thread::_pd = &core_pd();
|
||||||
_become_active();
|
_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;
|
static Core_main_thread instance { cpu_pool };
|
||||||
return cmt;
|
_instance = &instance;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include <base/internal/native_utcb.h>
|
#include <base/internal/native_utcb.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
class Cpu_pool;
|
||||||
struct Thread_fault;
|
struct Thread_fault;
|
||||||
class Thread;
|
class Thread;
|
||||||
class Core_main_thread;
|
class Core_main_thread;
|
||||||
@ -69,13 +71,18 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
|||||||
*/
|
*/
|
||||||
struct Tlb_invalidation : Inter_processor_work
|
struct Tlb_invalidation : Inter_processor_work
|
||||||
{
|
{
|
||||||
|
Inter_processor_work_list &global_work_list;
|
||||||
Thread &caller; /* the caller gets blocked until all finished */
|
Thread &caller; /* the caller gets blocked until all finished */
|
||||||
Pd &pd; /* the corresponding pd */
|
Pd &pd; /* the corresponding pd */
|
||||||
addr_t addr;
|
addr_t addr;
|
||||||
size_t size;
|
size_t size;
|
||||||
unsigned cnt; /* count of cpus left */
|
unsigned cnt; /* count of cpus left */
|
||||||
|
|
||||||
Tlb_invalidation(Thread & caller, Pd & pd, addr_t addr, size_t size,
|
Tlb_invalidation(Inter_processor_work_list &global_work_list,
|
||||||
|
Thread &caller,
|
||||||
|
Pd &pd,
|
||||||
|
addr_t addr,
|
||||||
|
size_t size,
|
||||||
unsigned cnt);
|
unsigned cnt);
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
@ -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 };
|
enum { MAX_RCV_CAPS = Genode::Msgbuf_base::MAX_CAPS_PER_MSG };
|
||||||
|
|
||||||
|
Cpu_pool &_cpu_pool;
|
||||||
void *_obj_id_ref_ptr[MAX_RCV_CAPS] { nullptr };
|
void *_obj_id_ref_ptr[MAX_RCV_CAPS] { nullptr };
|
||||||
Ipc_node _ipc_node;
|
Ipc_node _ipc_node;
|
||||||
capid_t _ipc_capid { cap_id_invalid() };
|
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 label debugging label
|
||||||
* \param core whether it is a core thread or not
|
* \param core whether it is a core thread or not
|
||||||
*/
|
*/
|
||||||
Thread(unsigned const priority, unsigned const quota,
|
Thread(Cpu_pool &cpu_pool,
|
||||||
char const * const label, bool core = false);
|
unsigned const priority,
|
||||||
|
unsigned const quota,
|
||||||
|
char const *const label,
|
||||||
|
bool core = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for core/kernel thread
|
* Constructor for core/kernel thread
|
||||||
*
|
*
|
||||||
* \param label debugging label
|
* \param label debugging label
|
||||||
*/
|
*/
|
||||||
Thread(char const * const label)
|
Thread(Cpu_pool &cpu_pool,
|
||||||
: Thread(Cpu_priority::min(), 0, label, true) { }
|
char const *const label)
|
||||||
|
:
|
||||||
|
Thread(cpu_pool, Cpu_priority::min(), 0, label, true)
|
||||||
|
{ }
|
||||||
|
|
||||||
~Thread();
|
~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
|
* 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_ */
|
#endif /* _CORE__KERNEL__THREAD_H_ */
|
||||||
|
@ -25,7 +25,8 @@ void Timer::Irq::occurred() { _cpu.scheduler().timeout(); }
|
|||||||
|
|
||||||
Timer::Irq::Irq(unsigned id, Cpu &cpu)
|
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 state initial CPU state
|
||||||
* \param context signal for VM exceptions other than interrupts
|
* \param context signal for VM exceptions other than interrupts
|
||||||
*/
|
*/
|
||||||
Vm(unsigned cpu,
|
Vm(Cpu & cpu,
|
||||||
State & state,
|
State & state,
|
||||||
Signal_context & context,
|
Signal_context & context,
|
||||||
Identity & id);
|
Identity & id);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
/* core includes */
|
/* core includes */
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
|
#include <kernel/cpu.h>
|
||||||
|
|
||||||
void Kernel::Thread::_call_new_vm()
|
void Kernel::Thread::_call_new_vm()
|
||||||
{
|
{
|
||||||
@ -24,7 +25,8 @@ void Kernel::Thread::_call_new_vm()
|
|||||||
return;
|
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());
|
*context, *(Vm::Identity*)user_arg_4());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,12 +38,20 @@ namespace Kernel {
|
|||||||
|
|
||||||
struct Board::Vcpu_context
|
struct Board::Vcpu_context
|
||||||
{
|
{
|
||||||
struct Vm_irq : Kernel::Irq
|
class Vm_irq : public Kernel::Irq
|
||||||
{
|
{
|
||||||
Vm_irq(unsigned const irq, Kernel::Cpu &);
|
private:
|
||||||
|
|
||||||
|
Kernel::Cpu &_cpu;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Vm_irq(unsigned const irq, Kernel::Cpu &cpu);
|
||||||
|
|
||||||
virtual ~Vm_irq() { };
|
virtual ~Vm_irq() { };
|
||||||
|
|
||||||
virtual void handle(Kernel::Cpu &, Kernel::Vm & vm, unsigned irq);
|
virtual void handle(Kernel::Vm &vm, unsigned irq);
|
||||||
|
|
||||||
void occurred() override;
|
void occurred() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,7 +60,7 @@ struct Board::Vcpu_context
|
|||||||
{
|
{
|
||||||
Pic_maintainance_irq(Kernel::Cpu &);
|
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;
|
using namespace Kernel;
|
||||||
|
|
||||||
|
|
||||||
Kernel::Vm::Vm(unsigned,
|
Kernel::Vm::Vm(Cpu & cpu,
|
||||||
Genode::Vm_state & state,
|
Genode::Vm_state & state,
|
||||||
Kernel::Signal_context & context,
|
Kernel::Signal_context & context,
|
||||||
Identity & id)
|
Identity & id)
|
||||||
@ -30,9 +30,9 @@ Kernel::Vm::Vm(unsigned,
|
|||||||
_state(state),
|
_state(state),
|
||||||
_context(context),
|
_context(context),
|
||||||
_id(id),
|
_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)
|
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); }
|
vm.inject_irq(irq); }
|
||||||
|
|
||||||
|
|
||||||
void Board::Vcpu_context::Vm_irq::occurred()
|
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!");
|
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,
|
Genode::Vm_state & state,
|
||||||
Kernel::Signal_context & context,
|
Kernel::Signal_context & context,
|
||||||
Identity & id)
|
Identity & id)
|
||||||
@ -144,9 +144,9 @@ Kernel::Vm::Vm(unsigned cpu,
|
|||||||
_state(state),
|
_state(state),
|
||||||
_context(context),
|
_context(context),
|
||||||
_id(id),
|
_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.
|
* 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 <board.h>
|
||||||
#include <cpu.h>
|
#include <cpu.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <cpu/memory_barrier.h>
|
|
||||||
#include <util/bit_allocator.h>
|
|
||||||
|
|
||||||
|
|
||||||
Genode::Cpu::Context::Context(bool privileged)
|
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)
|
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); }
|
vm.inject_irq(irq); }
|
||||||
|
|
||||||
|
|
||||||
void Board::Vcpu_context::Vm_irq::occurred()
|
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!");
|
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,
|
Genode::Vm_state & state,
|
||||||
Kernel::Signal_context & context,
|
Kernel::Signal_context & context,
|
||||||
Identity & id)
|
Identity & id)
|
||||||
@ -119,9 +119,9 @@ Vm::Vm(unsigned cpu,
|
|||||||
_state(state),
|
_state(state),
|
||||||
_context(context),
|
_context(context),
|
||||||
_id(id),
|
_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_aa64isar0_el1 = Cpu::Id_aa64isar0_el1::read();
|
||||||
_state.id_aa64isar1_el1 = Cpu::Id_aa64isar1_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 this is the last cpu, wake up the caller thread */
|
||||||
if (--cnt == 0) {
|
if (--cnt == 0) {
|
||||||
cpu_pool().work_list().remove(&_le);
|
global_work_list.remove(&_le);
|
||||||
caller._restart();
|
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 */
|
/* 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(),
|
(addr_t)&_stack->utcb(),
|
||||||
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
|
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user