From 5dd8ee584064fd3393a58263d3fc9a440f7962af Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 13 Jul 2021 16:37:00 +0200 Subject: [PATCH] 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 --- repos/base-hw/src/core/kernel/cpu.cc | 30 ++++++++++--------- repos/base-hw/src/core/kernel/cpu.h | 10 ++++--- repos/base-hw/src/core/kernel/cpu_context.h | 2 +- repos/base-hw/src/core/kernel/irq.cc | 12 ++------ repos/base-hw/src/core/kernel/irq.h | 26 +++++++--------- repos/base-hw/src/core/kernel/main.cc | 6 +++- repos/base-hw/src/core/kernel/thread.cc | 15 ++++++---- repos/base-hw/src/core/kernel/thread.h | 11 ++++--- repos/base-hw/src/core/kernel/vm.h | 10 ++++--- repos/base-hw/src/core/kernel/vm_thread_on.cc | 2 +- .../src/core/spec/arm/kernel/thread.cc | 2 +- .../core/spec/arm_v7/trustzone/kernel/vm.cc | 12 ++++---- .../spec/arm_v7/virtualization/kernel/vm.cc | 6 ++-- .../src/core/spec/arm_v8/kernel/thread.cc | 2 +- .../spec/arm_v8/virtualization/kernel/vm.cc | 6 ++-- .../src/core/spec/riscv/kernel/thread.cc | 4 +-- .../spec/x86_64/kernel/thread_exception.cc | 2 +- 17 files changed, 85 insertions(+), 73 deletions(-) diff --git a/repos/base-hw/src/core/kernel/cpu.cc b/repos/base-hw/src/core/kernel/cpu.cc index 8335354b59..b87d98e9e8 100644 --- a/repos/base-hw/src/core/kernel/cpu.cc +++ b/repos/base-hw/src/core/kernel/cpu.cc @@ -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); } diff --git a/repos/base-hw/src/core/kernel/cpu.h b/repos/base-hw/src/core/kernel/cpu.h index 9508663d9e..468ee47102 100644 --- a/repos/base-hw/src/core/kernel/cpu.h +++ b/repos/base-hw/src/core/kernel/cpu.h @@ -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' diff --git a/repos/base-hw/src/core/kernel/cpu_context.h b/repos/base-hw/src/core/kernel/cpu_context.h index 188260ec47..472dc12900 100644 --- a/repos/base-hw/src/core/kernel/cpu_context.h +++ b/repos/base-hw/src/core/kernel/cpu_context.h @@ -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 diff --git a/repos/base-hw/src/core/kernel/irq.cc b/repos/base-hw/src/core/kernel/irq.cc index 73ce6304e0..c1147a0f52 100644 --- a/repos/base-hw/src/core/kernel/irq.cc +++ b/repos/base-hw/src/core/kernel/irq.cc @@ -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(); diff --git a/repos/base-hw/src/core/kernel/irq.h b/repos/base-hw/src/core/kernel/irq.h index a86db53a78..b7096e31e7 100644 --- a/repos/base-hw/src/core/kernel/irq.h +++ b/repos/base-hw/src/core/kernel/irq.h @@ -71,7 +71,7 @@ class Kernel::Irq : Genode::Avl_node 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 * \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(_pool().object(irq)); } + static User_irq * object(Irq::Pool &user_irq_pool, unsigned const irq) { + return dynamic_cast(user_irq_pool.object(irq)); } /** * Syscall to create user irq object diff --git a/repos/base-hw/src/core/kernel/main.cc b/repos/base-hw/src/core/kernel/main.cc index 25558eb530..f1f6f8fc25 100644 --- a/repos/base-hw/src/core/kernel/main.cc +++ b/repos/base-hw/src/core/kernel/main.cc @@ -42,6 +42,7 @@ class Kernel::Main Lock _data_lock { }; Cpu_pool _cpu_pool; + Irq::Pool _user_irq_pool { }; Genode::Constructible _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 = diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 3578cffaf8..0da012948c 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -660,7 +660,7 @@ void Thread::_call_new_irq() _call_new( (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(_cpu_pool, (unsigned) user_arg_2(), + _call_new(_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(_cpu_pool, (char const *) user_arg_2()); + _call_new(_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(cpu_pool, "core") + Core_object(user_irq_pool, cpu_pool, "core") { using namespace Genode; diff --git a/repos/base-hw/src/core/kernel/thread.h b/repos/base-hw/src/core/kernel/thread.h index 23b916e5d8..fa1f49ad8c 100644 --- a/repos/base-hw/src/core/kernel/thread.h +++ b/repos/base-hw/src/core/kernel/thread.h @@ -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 { 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_ */ diff --git a/repos/base-hw/src/core/kernel/vm.h b/repos/base-hw/src/core/kernel/vm.h index eb65f1678e..99c54f8f69 100644 --- a/repos/base-hw/src/core/kernel/vm.h +++ b/repos/base-hw/src/core/kernel/vm.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 diff --git a/repos/base-hw/src/core/kernel/vm_thread_on.cc b/repos/base-hw/src/core/kernel/vm_thread_on.cc index 6cc41fb77d..cdbb202939 100644 --- a/repos/base-hw/src/core/kernel/vm_thread_on.cc +++ b/repos/base-hw/src/core/kernel/vm_thread_on.cc @@ -25,7 +25,7 @@ void Kernel::Thread::_call_new_vm() return; } - _call_new(_cpu_pool.cpu((unsigned)user_arg_2()), + _call_new(_user_irq_pool, _cpu_pool.cpu((unsigned)user_arg_2()), *(Board::Vm_state*)user_arg_3(), *context, *(Vm::Identity*)user_arg_4()); } diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread.cc b/repos/base-hw/src/core/spec/arm/kernel/thread.cc index 1f0496e375..6dc5560dc9 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread.cc @@ -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=", diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc index 4b6214f464..968786b6d2 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc @@ -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(); diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc index 1a3980fedb..d73b76a22e 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc @@ -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(); diff --git a/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc b/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc index 9e86689a66..9faf8f099c 100644 --- a/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc @@ -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: diff --git a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc index a7437db8bc..6db8317560 100644 --- a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc @@ -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]]; diff --git a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc index f6aa7df361..15f568af26 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc @@ -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; } diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc b/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc index b16371d3ac..25ccaeae65 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc @@ -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; }