mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 03:45:24 +00:00
base-hw: global IRQ pool as Main member
Let the global kernel IRQ-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
c49db16762
commit
5dd8ee5840
@ -46,22 +46,22 @@ void Cpu_job::_yield()
|
||||
}
|
||||
|
||||
|
||||
void Cpu_job::_interrupt(unsigned const /* cpu_id */)
|
||||
void Cpu_job::_interrupt(Irq::Pool &user_irq_pool, unsigned const /* cpu_id */)
|
||||
{
|
||||
/* determine handling for specific interrupt */
|
||||
/* let the IRQ controller take a pending IRQ for handling, if any */
|
||||
unsigned irq_id;
|
||||
if (_cpu->pic().take_request(irq_id))
|
||||
|
||||
/* is the interrupt a cpu-local one */
|
||||
if (!_cpu->interrupt(irq_id)) {
|
||||
/* let the CPU of this job handle the IRQ if it is a CPU-local one */
|
||||
if (!_cpu->handle_if_cpu_local_interrupt(irq_id)) {
|
||||
|
||||
/* it needs to be a user interrupt */
|
||||
User_irq * irq = User_irq::object(irq_id);
|
||||
/* it isn't a CPU-local IRQ, so, it must be a user IRQ */
|
||||
User_irq * irq = User_irq::object(user_irq_pool, irq_id);
|
||||
if (irq) irq->occurred();
|
||||
else Genode::raw("Unknown interrupt ", irq_id);
|
||||
}
|
||||
|
||||
/* end interrupt request at controller */
|
||||
/* let the IRQ controller finish the currently taken IRQ */
|
||||
_cpu->pic().finish_request();
|
||||
}
|
||||
|
||||
@ -104,10 +104,11 @@ Cpu_job::~Cpu_job()
|
||||
extern "C" void idle_thread_main(void);
|
||||
|
||||
|
||||
Cpu::Idle_thread::Idle_thread(Cpu_pool &cpu_pool,
|
||||
Cpu &cpu)
|
||||
Cpu::Idle_thread::Idle_thread(Irq::Pool &user_irq_pool,
|
||||
Cpu_pool &cpu_pool,
|
||||
Cpu &cpu)
|
||||
:
|
||||
Thread { cpu_pool, "idle" }
|
||||
Thread { user_irq_pool, cpu_pool, "idle" }
|
||||
{
|
||||
regs->ip = (addr_t)&idle_thread_main;
|
||||
|
||||
@ -129,7 +130,7 @@ void Cpu::schedule(Job * const job)
|
||||
}
|
||||
|
||||
|
||||
bool Cpu::interrupt(unsigned const irq_id)
|
||||
bool Cpu::handle_if_cpu_local_interrupt(unsigned const irq_id)
|
||||
{
|
||||
Irq * const irq = object(irq_id);
|
||||
|
||||
@ -173,12 +174,13 @@ addr_t Cpu::stack_start()
|
||||
|
||||
|
||||
Cpu::Cpu(unsigned const id,
|
||||
Irq::Pool &user_irq_pool,
|
||||
Cpu_pool &cpu_pool)
|
||||
:
|
||||
_id { id },
|
||||
_timer { *this },
|
||||
_scheduler { _idle, _quota(), _fill() },
|
||||
_idle { cpu_pool, *this },
|
||||
_idle { user_irq_pool, cpu_pool, *this },
|
||||
_ipi_irq { *this },
|
||||
_global_work_list { cpu_pool.work_list() }
|
||||
{
|
||||
@ -190,10 +192,10 @@ Cpu::Cpu(unsigned const id,
|
||||
** Cpu_pool **
|
||||
**************/
|
||||
|
||||
void Cpu_pool::initialize_executing_cpu()
|
||||
void Cpu_pool::initialize_executing_cpu(Irq::Pool &user_irq_pool)
|
||||
{
|
||||
unsigned id = Cpu::executing_id();
|
||||
_cpus[id].construct(id, *this);
|
||||
_cpus[id].construct(id, user_irq_pool, *this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,8 +102,9 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
||||
/**
|
||||
* Construct idle context for CPU 'cpu'
|
||||
*/
|
||||
Idle_thread(Cpu_pool &cpu_pool,
|
||||
Cpu &cpu);
|
||||
Idle_thread(Irq::Pool &user_irq_pool,
|
||||
Cpu_pool &cpu_pool,
|
||||
Cpu &cpu);
|
||||
};
|
||||
|
||||
|
||||
@ -129,6 +130,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
||||
* Construct object for CPU 'id'
|
||||
*/
|
||||
Cpu(unsigned const id,
|
||||
Irq::Pool &user_irq_pool,
|
||||
Cpu_pool &cpu_pool);
|
||||
|
||||
static inline unsigned primary_id() { return 0; }
|
||||
@ -144,7 +146,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
||||
* \param irq_id id of the interrupt that occured
|
||||
* \returns true if the interrupt belongs to this CPU, otherwise false
|
||||
*/
|
||||
bool interrupt(unsigned const irq_id);
|
||||
bool handle_if_cpu_local_interrupt(unsigned const irq_id);
|
||||
|
||||
/**
|
||||
* Schedule 'job' at this CPU
|
||||
@ -200,7 +202,7 @@ class Kernel::Cpu_pool
|
||||
|
||||
Cpu_pool(unsigned nr_of_cpus);
|
||||
|
||||
void initialize_executing_cpu();
|
||||
void initialize_executing_cpu(Irq::Pool &user_irq_pool);
|
||||
|
||||
/**
|
||||
* Return object of CPU 'id'
|
||||
|
@ -51,7 +51,7 @@ class Kernel::Cpu_job : private Cpu_share
|
||||
/**
|
||||
* Handle interrupt exception that occured during execution on CPU 'id'
|
||||
*/
|
||||
void _interrupt(unsigned const id);
|
||||
void _interrupt(Irq::Pool &user_irq_pool, unsigned const id);
|
||||
|
||||
/**
|
||||
* Activate our own CPU-share
|
||||
|
@ -29,20 +29,14 @@ void Kernel::Irq::enable() const
|
||||
}
|
||||
|
||||
|
||||
Kernel::Irq::Pool &Kernel::User_irq::_pool()
|
||||
{
|
||||
static Irq::Pool p;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
Kernel::User_irq::User_irq(unsigned const irq,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context &context,
|
||||
Board::Pic &pic)
|
||||
Board::Pic &pic,
|
||||
Irq::Pool &user_irq_pool)
|
||||
:
|
||||
Irq { irq, _pool(), pic },
|
||||
Irq { irq, user_irq_pool, pic },
|
||||
_context { context }
|
||||
{
|
||||
disable();
|
||||
|
@ -71,7 +71,7 @@ class Kernel::Irq : Genode::Avl_node<Irq>
|
||||
protected:
|
||||
|
||||
unsigned _irq_nr; /* kernel name of the interrupt */
|
||||
Pool &_pool;
|
||||
Pool &_irq_pool;
|
||||
Board::Pic &_pic;
|
||||
|
||||
public:
|
||||
@ -83,17 +83,17 @@ class Kernel::Irq : Genode::Avl_node<Irq>
|
||||
* \param pool pool this interrupt shall belong to
|
||||
*/
|
||||
Irq(unsigned const irq,
|
||||
Pool &pool,
|
||||
Pool &irq_pool,
|
||||
Board::Pic &pic)
|
||||
:
|
||||
_irq_nr { irq },
|
||||
_pool { pool },
|
||||
_pic { pic }
|
||||
_irq_nr { irq },
|
||||
_irq_pool { irq_pool },
|
||||
_pic { pic }
|
||||
{
|
||||
_pool.insert(this);
|
||||
_irq_pool.insert(this);
|
||||
}
|
||||
|
||||
virtual ~Irq() { _pool.remove(this); }
|
||||
virtual ~Irq() { _irq_pool.remove(this); }
|
||||
|
||||
/**
|
||||
* Handle occurence of the interrupt
|
||||
@ -139,11 +139,6 @@ class Kernel::User_irq : public Kernel::Irq
|
||||
Kernel::Object _kernel_object { *this };
|
||||
Signal_context &_context;
|
||||
|
||||
/**
|
||||
* Get map that provides all user interrupts by their kernel names
|
||||
*/
|
||||
static Irq::Pool &_pool();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -153,7 +148,8 @@ class Kernel::User_irq : public Kernel::Irq
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context &context,
|
||||
Board::Pic &pic);
|
||||
Board::Pic &pic,
|
||||
Irq::Pool &user_irq_pool);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -174,8 +170,8 @@ class Kernel::User_irq : public Kernel::Irq
|
||||
/**
|
||||
* Handle occurence of interrupt 'irq'
|
||||
*/
|
||||
static User_irq * object(unsigned const irq) {
|
||||
return dynamic_cast<User_irq*>(_pool().object(irq)); }
|
||||
static User_irq * object(Irq::Pool &user_irq_pool, unsigned const irq) {
|
||||
return dynamic_cast<User_irq*>(user_irq_pool.object(irq)); }
|
||||
|
||||
/**
|
||||
* Syscall to create user irq object
|
||||
|
@ -42,6 +42,7 @@ class Kernel::Main
|
||||
|
||||
Lock _data_lock { };
|
||||
Cpu_pool _cpu_pool;
|
||||
Irq::Pool _user_irq_pool { };
|
||||
Genode::Constructible<Core_main_thread> _core_main_thread { };
|
||||
|
||||
void _handle_kernel_entry();
|
||||
@ -119,7 +120,9 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
*/
|
||||
Lock::Guard guard(Main::_instance->_data_lock);
|
||||
instance_initialized = true;
|
||||
Main::_instance->_cpu_pool.initialize_executing_cpu();
|
||||
Main::_instance->_cpu_pool.initialize_executing_cpu(
|
||||
Main::_instance->_user_irq_pool);
|
||||
|
||||
nr_of_initialized_cpus++;
|
||||
};
|
||||
|
||||
@ -144,6 +147,7 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
boot_info.kernel_irqs.add((unsigned)Board::Pic::IPI);
|
||||
|
||||
Main::_instance->_core_main_thread.construct(
|
||||
Main::_instance->_user_irq_pool,
|
||||
Main::_instance->_cpu_pool);
|
||||
|
||||
boot_info.core_main_thread_utcb =
|
||||
|
@ -660,7 +660,7 @@ void Thread::_call_new_irq()
|
||||
|
||||
_call_new<User_irq>(
|
||||
(unsigned)user_arg_2(), trigger, polarity, *c,
|
||||
_cpu_pool.executing_cpu().pic());
|
||||
_cpu_pool.executing_cpu().pic(), _user_irq_pool);
|
||||
}
|
||||
|
||||
|
||||
@ -774,12 +774,13 @@ void Thread::_call()
|
||||
/* switch over kernel calls that are restricted to core */
|
||||
switch (call_id) {
|
||||
case call_id_new_thread():
|
||||
_call_new<Thread>(_cpu_pool, (unsigned) user_arg_2(),
|
||||
_call_new<Thread>(_user_irq_pool, _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>(_cpu_pool, (char const *) user_arg_2());
|
||||
_call_new<Thread>(_user_irq_pool, _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;
|
||||
@ -836,7 +837,8 @@ void Thread::_mmu_exception()
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(Cpu_pool &cpu_pool,
|
||||
Thread::Thread(Irq::Pool &user_irq_pool,
|
||||
Cpu_pool &cpu_pool,
|
||||
unsigned const priority,
|
||||
unsigned const quota,
|
||||
char const *const label,
|
||||
@ -844,6 +846,7 @@ Thread::Thread(Cpu_pool &cpu_pool,
|
||||
:
|
||||
Kernel::Object { *this },
|
||||
Cpu_job { priority, quota },
|
||||
_user_irq_pool { user_irq_pool },
|
||||
_cpu_pool { cpu_pool },
|
||||
_ipc_node { *this },
|
||||
_state { AWAITS_START },
|
||||
@ -871,9 +874,9 @@ Genode::uint8_t __initial_stack_base[DEFAULT_STACK_SIZE];
|
||||
** Core_main_thread **
|
||||
**********************/
|
||||
|
||||
Core_main_thread::Core_main_thread(Cpu_pool &cpu_pool)
|
||||
Core_main_thread::Core_main_thread(Irq::Pool &user_irq_pool, Cpu_pool &cpu_pool)
|
||||
:
|
||||
Core_object<Thread>(cpu_pool, "core")
|
||||
Core_object<Thread>(user_irq_pool, cpu_pool, "core")
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
|
@ -131,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 };
|
||||
|
||||
Irq::Pool &_user_irq_pool;
|
||||
Cpu_pool &_cpu_pool;
|
||||
void *_obj_id_ref_ptr[MAX_RCV_CAPS] { nullptr };
|
||||
Ipc_node _ipc_node;
|
||||
@ -292,7 +293,8 @@ 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(Cpu_pool &cpu_pool,
|
||||
Thread(Irq::Pool &user_irq_pool,
|
||||
Cpu_pool &cpu_pool,
|
||||
unsigned const priority,
|
||||
unsigned const quota,
|
||||
char const *const label,
|
||||
@ -303,10 +305,11 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
||||
*
|
||||
* \param label debugging label
|
||||
*/
|
||||
Thread(Cpu_pool &cpu_pool,
|
||||
Thread(Irq::Pool &user_irq_pool,
|
||||
Cpu_pool &cpu_pool,
|
||||
char const *const label)
|
||||
:
|
||||
Thread(cpu_pool, Cpu_priority::min(), 0, label, true)
|
||||
Thread(user_irq_pool, cpu_pool, Cpu_priority::min(), 0, label, true)
|
||||
{ }
|
||||
|
||||
~Thread();
|
||||
@ -440,7 +443,7 @@ class Kernel::Core_main_thread : public Core_object<Kernel::Thread>
|
||||
{
|
||||
public:
|
||||
|
||||
Core_main_thread(Cpu_pool &cpu_pool);
|
||||
Core_main_thread(Irq::Pool &user_irq_pool, Cpu_pool &cpu_pool);
|
||||
};
|
||||
|
||||
#endif /* _CORE__KERNEL__THREAD_H_ */
|
||||
|
@ -55,6 +55,7 @@ class Kernel::Vm : private Kernel::Object, public Cpu_job
|
||||
|
||||
enum Scheduler_state { ACTIVE, INACTIVE };
|
||||
|
||||
Irq::Pool & _user_irq_pool;
|
||||
Object _kernel_object { *this };
|
||||
State & _state;
|
||||
Signal_context & _context;
|
||||
@ -71,10 +72,11 @@ class Kernel::Vm : private Kernel::Object, public Cpu_job
|
||||
* \param state initial CPU state
|
||||
* \param context signal for VM exceptions other than interrupts
|
||||
*/
|
||||
Vm(Cpu & cpu,
|
||||
State & state,
|
||||
Signal_context & context,
|
||||
Identity & id);
|
||||
Vm(Irq::Pool & user_irq_pool,
|
||||
Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id);
|
||||
|
||||
/**
|
||||
* Inject an interrupt to this VM
|
||||
|
@ -25,7 +25,7 @@ void Kernel::Thread::_call_new_vm()
|
||||
return;
|
||||
}
|
||||
|
||||
_call_new<Vm>(_cpu_pool.cpu((unsigned)user_arg_2()),
|
||||
_call_new<Vm>(_user_irq_pool, _cpu_pool.cpu((unsigned)user_arg_2()),
|
||||
*(Board::Vm_state*)user_arg_3(),
|
||||
*context, *(Vm::Identity*)user_arg_4());
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ void Thread::exception(Cpu & cpu)
|
||||
return;
|
||||
case Cpu::Context::INTERRUPT_REQUEST:
|
||||
case Cpu::Context::FAST_INTERRUPT_REQUEST:
|
||||
_interrupt(cpu.id());
|
||||
_interrupt(_user_irq_pool, cpu.id());
|
||||
return;
|
||||
case Cpu::Context::UNDEFINED_INSTRUCTION:
|
||||
Genode::raw(*this, ": undefined instruction at ip=",
|
||||
|
@ -20,13 +20,15 @@
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Kernel::Vm::Vm(Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
Vm::Vm(Irq::Pool & user_irq_pool,
|
||||
Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
:
|
||||
Kernel::Object { *this },
|
||||
Cpu_job(Cpu_priority::min(), 0),
|
||||
_user_irq_pool(user_irq_pool),
|
||||
_state(state),
|
||||
_context(context),
|
||||
_id(id),
|
||||
@ -41,7 +43,7 @@ void Vm::exception(Cpu & cpu)
|
||||
switch(_state.cpu_exception) {
|
||||
case Genode::Cpu_state::INTERRUPT_REQUEST: [[fallthrough]];
|
||||
case Genode::Cpu_state::FAST_INTERRUPT_REQUEST:
|
||||
_interrupt(cpu.id());
|
||||
_interrupt(_user_irq_pool, cpu.id());
|
||||
return;
|
||||
case Genode::Cpu_state::DATA_ABORT:
|
||||
_state.dfar = Cpu::Dfar::read();
|
||||
|
@ -134,13 +134,15 @@ void Board::Vcpu_context::Virtual_timer_irq::disable()
|
||||
}
|
||||
|
||||
|
||||
Kernel::Vm::Vm(Cpu & cpu,
|
||||
Kernel::Vm::Vm(Irq::Pool & user_irq_pool,
|
||||
Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
:
|
||||
Kernel::Object { *this },
|
||||
Cpu_job(Cpu_priority::min(), 0),
|
||||
_user_irq_pool(user_irq_pool),
|
||||
_state(state),
|
||||
_context(context),
|
||||
_id(id),
|
||||
@ -155,7 +157,7 @@ void Kernel::Vm::exception(Cpu & cpu)
|
||||
switch(_state.cpu_exception) {
|
||||
case Genode::Cpu_state::INTERRUPT_REQUEST:
|
||||
case Genode::Cpu_state::FAST_INTERRUPT_REQUEST:
|
||||
_interrupt(cpu.id());
|
||||
_interrupt(_user_irq_pool, cpu.id());
|
||||
break;
|
||||
default:
|
||||
pause();
|
||||
|
@ -33,7 +33,7 @@ void Thread::exception(Cpu & cpu)
|
||||
case Cpu::IRQ_LEVEL_EL1: [[fallthrough]];
|
||||
case Cpu::FIQ_LEVEL_EL0: [[fallthrough]];
|
||||
case Cpu::FIQ_LEVEL_EL1:
|
||||
_interrupt(cpu.id());
|
||||
_interrupt(_user_irq_pool, cpu.id());
|
||||
return;
|
||||
case Cpu::SYNC_LEVEL_EL0: [[fallthrough]];
|
||||
case Cpu::SYNC_LEVEL_EL1:
|
||||
|
@ -109,13 +109,15 @@ void Board::Vcpu_context::Virtual_timer_irq::disable()
|
||||
}
|
||||
|
||||
|
||||
Vm::Vm(Cpu & cpu,
|
||||
Vm::Vm(Irq::Pool & user_irq_pool,
|
||||
Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
:
|
||||
Kernel::Object { *this },
|
||||
Cpu_job(Cpu_priority::min(), 0),
|
||||
_user_irq_pool(user_irq_pool),
|
||||
_state(state),
|
||||
_context(context),
|
||||
_id(id),
|
||||
@ -159,7 +161,7 @@ void Vm::exception(Cpu & cpu)
|
||||
case Cpu::IRQ_LEVEL_EL1: [[fallthrough]];
|
||||
case Cpu::FIQ_LEVEL_EL0: [[fallthrough]];
|
||||
case Cpu::FIQ_LEVEL_EL1:
|
||||
_interrupt(cpu.id());
|
||||
_interrupt(_user_irq_pool, cpu.id());
|
||||
break;
|
||||
case Cpu::SYNC_LEVEL_EL0: [[fallthrough]];
|
||||
case Cpu::SYNC_LEVEL_EL1: [[fallthrough]];
|
||||
|
@ -30,10 +30,10 @@ void Thread::exception(Cpu & cpu)
|
||||
if (regs->is_irq()) {
|
||||
/* cpu-local timer interrupt */
|
||||
if (regs->irq() == cpu.timer().interrupt_id()) {
|
||||
cpu.interrupt(cpu.timer().interrupt_id());
|
||||
cpu.handle_if_cpu_local_interrupt(cpu.timer().interrupt_id());
|
||||
} else {
|
||||
/* interrupt controller */
|
||||
_interrupt(0);
|
||||
_interrupt(_user_irq_pool, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ void Thread::exception(Cpu & cpu)
|
||||
|
||||
if (regs->trapno >= Cpu_state::INTERRUPTS_START &&
|
||||
regs->trapno <= Cpu_state::INTERRUPTS_END) {
|
||||
_interrupt(cpu.id());
|
||||
_interrupt(_user_irq_pool, cpu.id());
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user