mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-01 23:20:55 +00:00
hw: add IPI type to flush and stop CPUs
as preparation before powering off the CPU Issue #4669
This commit is contained in:
parent
80453236c4
commit
a20a26b41b
@ -19,12 +19,12 @@ using namespace Kernel;
|
|||||||
void Cpu::Ipi::occurred()
|
void Cpu::Ipi::occurred()
|
||||||
{
|
{
|
||||||
/* lambda to iterate over a work-list and execute all work items */
|
/* lambda to iterate over a work-list and execute all work items */
|
||||||
auto iterate = [] (Genode::List<Genode::List_element<Inter_processor_work>> & li) {
|
auto iterate = [&] (Genode::List<Genode::List_element<Inter_processor_work>> & li) {
|
||||||
Genode::List_element<Inter_processor_work> const *e = li.first();
|
Genode::List_element<Inter_processor_work> const *e = li.first();
|
||||||
Genode::List_element<Inter_processor_work> const *next = nullptr;
|
Genode::List_element<Inter_processor_work> const *next = nullptr;
|
||||||
for ( ; e; e = next) {
|
for ( ; e; e = next) {
|
||||||
next = e->next();
|
next = e->next();
|
||||||
e->object()->execute();
|
e->object()->execute(cpu);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class Kernel::Inter_processor_work : Genode::Interface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void execute() = 0;
|
virtual void execute(Cpu &) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ Thread::Destroy::Destroy(Thread & caller, Genode::Kernel_object<Thread> & to_del
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread::Destroy::execute()
|
Thread::Destroy::execute(Cpu &)
|
||||||
{
|
{
|
||||||
thread_to_destroy->_cpu->work_list().remove(&_le);
|
thread_to_destroy->_cpu->work_list().remove(&_le);
|
||||||
thread_to_destroy.destruct();
|
thread_to_destroy.destruct();
|
||||||
|
@ -92,7 +92,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
|||||||
** Inter_processor_work interface **
|
** Inter_processor_work interface **
|
||||||
************************************/
|
************************************/
|
||||||
|
|
||||||
void execute() override;
|
void execute(Cpu &) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,11 +112,40 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
|||||||
** Inter_processor_work interface **
|
** Inter_processor_work interface **
|
||||||
************************************/
|
************************************/
|
||||||
|
|
||||||
void execute() override;
|
void execute(Cpu &) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
friend void Tlb_invalidation::execute();
|
/**
|
||||||
friend void Destroy::execute();
|
* Flush and stop CPU, e.g. before suspending or powering off the CPU
|
||||||
|
*/
|
||||||
|
struct Flush_and_stop_cpu : Inter_processor_work
|
||||||
|
{
|
||||||
|
Inter_processor_work_list &global_work_list;
|
||||||
|
unsigned cpus_left;
|
||||||
|
Hw::Suspend_type suspend;
|
||||||
|
|
||||||
|
Flush_and_stop_cpu(Inter_processor_work_list &global_work_list,
|
||||||
|
unsigned cpus, Hw::Suspend_type suspend)
|
||||||
|
:
|
||||||
|
global_work_list(global_work_list),
|
||||||
|
cpus_left(cpus),
|
||||||
|
suspend(suspend)
|
||||||
|
{
|
||||||
|
global_work_list.insert(&_le);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Flush_and_stop_cpu() { global_work_list.remove(&_le); }
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Inter_processor_work interface **
|
||||||
|
************************************/
|
||||||
|
|
||||||
|
void execute(Cpu &) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
friend void Tlb_invalidation::execute(Cpu &);
|
||||||
|
friend void Destroy::execute(Cpu &);
|
||||||
|
friend void Flush_and_stop_cpu::execute(Cpu &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -155,8 +184,9 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
|||||||
bool _cancel_next_await_signal { false };
|
bool _cancel_next_await_signal { false };
|
||||||
Type const _type;
|
Type const _type;
|
||||||
|
|
||||||
Genode::Constructible<Tlb_invalidation> _tlb_invalidation {};
|
Genode::Constructible<Tlb_invalidation> _tlb_invalidation {};
|
||||||
Genode::Constructible<Destroy> _destroy {};
|
Genode::Constructible<Destroy> _destroy {};
|
||||||
|
Genode::Constructible<Flush_and_stop_cpu> _stop_cpu {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notice that another thread yielded the CPU to this thread
|
* Notice that another thread yielded the CPU to this thread
|
||||||
|
@ -62,7 +62,10 @@ void Thread::exception(Cpu & cpu)
|
|||||||
* coprocessor registers (there might be ARM SoCs where this is not valid,
|
* coprocessor registers (there might be ARM SoCs where this is not valid,
|
||||||
* with several shareability domains, but until now we do not support them)
|
* with several shareability domains, but until now we do not support them)
|
||||||
*/
|
*/
|
||||||
void Kernel::Thread::Tlb_invalidation::execute() { };
|
void Kernel::Thread::Tlb_invalidation::execute(Cpu &) { }
|
||||||
|
|
||||||
|
|
||||||
|
void Thread::Flush_and_stop_cpu::execute(Cpu &) { }
|
||||||
|
|
||||||
|
|
||||||
void Thread::proceed(Cpu & cpu)
|
void Thread::proceed(Cpu & cpu)
|
||||||
|
@ -82,7 +82,10 @@ void Thread::exception(Cpu & cpu)
|
|||||||
* coprocessor registers (there might be ARM SoCs where this is not valid,
|
* coprocessor registers (there might be ARM SoCs where this is not valid,
|
||||||
* with several shareability domains, but until now we do not support them)
|
* with several shareability domains, but until now we do not support them)
|
||||||
*/
|
*/
|
||||||
void Kernel::Thread::Tlb_invalidation::execute() { };
|
void Kernel::Thread::Tlb_invalidation::execute(Cpu &) { }
|
||||||
|
|
||||||
|
|
||||||
|
void Thread::Flush_and_stop_cpu::execute(Cpu &) { }
|
||||||
|
|
||||||
|
|
||||||
bool Kernel::Pd::invalidate_tlb(Cpu & cpu, addr_t addr, size_t size)
|
bool Kernel::Pd::invalidate_tlb(Cpu & cpu, addr_t addr, size_t size)
|
||||||
|
@ -19,7 +19,10 @@
|
|||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
|
|
||||||
void Thread::Tlb_invalidation::execute() {}
|
void Thread::Tlb_invalidation::execute(Cpu &) { }
|
||||||
|
|
||||||
|
|
||||||
|
void Thread::Flush_and_stop_cpu::execute(Cpu &) { }
|
||||||
|
|
||||||
|
|
||||||
void Thread::exception(Cpu & cpu)
|
void Thread::exception(Cpu & cpu)
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include <kernel/pd.h>
|
#include <kernel/pd.h>
|
||||||
|
|
||||||
|
|
||||||
void Kernel::Thread::Tlb_invalidation::execute()
|
void Kernel::Thread::Tlb_invalidation::execute(Cpu &)
|
||||||
{
|
{
|
||||||
/* invalidate cpu-local TLB */
|
/* invalidate cpu-local TLB */
|
||||||
Cpu::invalidate_tlb();
|
Cpu::invalidate_tlb();
|
||||||
@ -32,6 +32,9 @@ void Kernel::Thread::Tlb_invalidation::execute()
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Kernel::Thread::Flush_and_stop_cpu::execute(Cpu &) { }
|
||||||
|
|
||||||
|
|
||||||
void Kernel::Thread::_call_cache_coherent_region() { }
|
void Kernel::Thread::_call_cache_coherent_region() { }
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,10 @@
|
|||||||
|
|
||||||
#include <hw/spec/arm/register_macros.h>
|
#include <hw/spec/arm/register_macros.h>
|
||||||
|
|
||||||
namespace Hw { struct Arm_cpu; }
|
namespace Hw { struct Arm_cpu; struct Suspend_type; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Hw::Suspend_type { };
|
||||||
|
|
||||||
|
|
||||||
struct Hw::Arm_cpu
|
struct Hw::Arm_cpu
|
||||||
|
@ -31,7 +31,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace Hw { struct Arm_64_cpu; }
|
namespace Hw { struct Arm_64_cpu; struct Suspend_type; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Hw::Suspend_type { };
|
||||||
|
|
||||||
|
|
||||||
struct Hw::Arm_64_cpu
|
struct Hw::Arm_64_cpu
|
||||||
|
@ -16,7 +16,10 @@
|
|||||||
|
|
||||||
#include <hw/spec/riscv/register_macros.h>
|
#include <hw/spec/riscv/register_macros.h>
|
||||||
|
|
||||||
namespace Hw { struct Riscv_cpu; }
|
namespace Hw { struct Riscv_cpu; struct Suspend_type; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Hw::Suspend_type { };
|
||||||
|
|
||||||
|
|
||||||
struct Hw::Riscv_cpu
|
struct Hw::Riscv_cpu
|
||||||
|
@ -16,7 +16,19 @@
|
|||||||
|
|
||||||
#include <hw/spec/x86_64/register_macros.h>
|
#include <hw/spec/x86_64/register_macros.h>
|
||||||
|
|
||||||
namespace Hw { struct X86_64_cpu; }
|
namespace Hw { struct X86_64_cpu; struct Suspend_type; }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The intended sleep state S0 ... S5. The values are read out by an
|
||||||
|
* ACPI AML component and are of type TYP_SLPx as described in the
|
||||||
|
* ACPI specification, e.g. TYP_SLPa and TYP_SLPb. The values differ
|
||||||
|
* between different PC systems/boards.
|
||||||
|
*/
|
||||||
|
struct Hw::Suspend_type {
|
||||||
|
Genode::uint8_t typ_a;
|
||||||
|
Genode::uint8_t typ_b;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Hw::X86_64_cpu
|
struct Hw::X86_64_cpu
|
||||||
@ -95,6 +107,8 @@ struct Hw::X86_64_cpu
|
|||||||
X86_64_CPUID_REGISTER(Cpuid_1_edx, 1, edx,
|
X86_64_CPUID_REGISTER(Cpuid_1_edx, 1, edx,
|
||||||
struct Pat : Bitfield<16, 1> { };
|
struct Pat : Bitfield<16, 1> { };
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Suspend_type suspend;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _SRC__LIB__HW__SPEC__X86_64__CPU_H_ */
|
#endif /* _SRC__LIB__HW__SPEC__X86_64__CPU_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user