mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 03:45:24 +00:00
base-hw: don't use boot_info() outside main.cc
It's sufficient to access the boot info only on kernel initialization time. Therfore, it can remain completely hidden to the rest of the kernel inside kernel/main.cc in the initialization function. Ref #4217
This commit is contained in:
parent
b247def09a
commit
c49db16762
@ -190,17 +190,16 @@ Cpu::Cpu(unsigned const id,
|
||||
** Cpu_pool **
|
||||
**************/
|
||||
|
||||
bool Cpu_pool::initialize()
|
||||
void Cpu_pool::initialize_executing_cpu()
|
||||
{
|
||||
unsigned id = Cpu::executing_id();
|
||||
_cpus[id].construct(id, *this);
|
||||
return --_initialized == 0;
|
||||
}
|
||||
|
||||
|
||||
Cpu & Cpu_pool::cpu(unsigned const id)
|
||||
{
|
||||
assert(id < _count && _cpus[id].constructed());
|
||||
assert(id < _nr_of_cpus && _cpus[id].constructed());
|
||||
return *_cpus[id];
|
||||
}
|
||||
|
||||
@ -208,7 +207,7 @@ Cpu & Cpu_pool::cpu(unsigned const id)
|
||||
using Boot_info = Hw::Boot_info<Board::Boot_info>;
|
||||
|
||||
|
||||
Cpu_pool::Cpu_pool()
|
||||
Cpu_pool::Cpu_pool(unsigned nr_of_cpus)
|
||||
:
|
||||
_count(reinterpret_cast<Boot_info*>(Hw::Mm::boot_info().base)->cpus)
|
||||
_nr_of_cpus(nr_of_cpus)
|
||||
{ }
|
||||
|
@ -193,15 +193,14 @@ class Kernel::Cpu_pool
|
||||
private:
|
||||
|
||||
Inter_processor_work_list _global_work_list {};
|
||||
unsigned _count;
|
||||
unsigned _initialized { _count };
|
||||
unsigned _nr_of_cpus;
|
||||
Genode::Constructible<Cpu> _cpus[NR_OF_CPUS];
|
||||
|
||||
public:
|
||||
|
||||
Cpu_pool();
|
||||
Cpu_pool(unsigned nr_of_cpus);
|
||||
|
||||
bool initialize();
|
||||
void initialize_executing_cpu();
|
||||
|
||||
/**
|
||||
* Return object of CPU 'id'
|
||||
@ -221,11 +220,13 @@ class Kernel::Cpu_pool
|
||||
template <typename FUNC>
|
||||
void for_each_cpu(FUNC const &func)
|
||||
{
|
||||
for (unsigned i = 0; i < _count; i++) func(cpu(i));
|
||||
for (unsigned i = 0; i < _nr_of_cpus; i++) func(cpu(i));
|
||||
}
|
||||
|
||||
Inter_processor_work_list & work_list() {
|
||||
return _global_work_list; }
|
||||
|
||||
unsigned nr_of_cpus() { return _nr_of_cpus; }
|
||||
};
|
||||
|
||||
#endif /* _CORE__KERNEL__CPU_H_ */
|
||||
|
@ -41,16 +41,24 @@ class Kernel::Main
|
||||
static Main *_instance;
|
||||
|
||||
Lock _data_lock { };
|
||||
Cpu_pool _cpu_pool { };
|
||||
Cpu_pool _cpu_pool;
|
||||
Genode::Constructible<Core_main_thread> _core_main_thread { };
|
||||
|
||||
void _handle_kernel_entry();
|
||||
|
||||
Main(unsigned nr_of_cpus);
|
||||
};
|
||||
|
||||
|
||||
Kernel::Main *Kernel::Main::_instance;
|
||||
|
||||
|
||||
Kernel::Main::Main(unsigned nr_of_cpus)
|
||||
:
|
||||
_cpu_pool { nr_of_cpus }
|
||||
{ }
|
||||
|
||||
|
||||
void Kernel::Main::_handle_kernel_entry()
|
||||
{
|
||||
Cpu &cpu = _cpu_pool.cpu(Cpu::executing_id());
|
||||
@ -74,11 +82,17 @@ void Kernel::main_handle_kernel_entry()
|
||||
|
||||
void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
{
|
||||
static volatile bool instance_initialized = false;
|
||||
static volatile bool pool_ready = false;
|
||||
static volatile bool kernel_ready = false;
|
||||
using Boot_info = Hw::Boot_info<Board::Boot_info>;
|
||||
|
||||
bool const primary_cpu { Cpu::executing_id() == Cpu::primary_id() };
|
||||
static volatile bool instance_initialized { false };
|
||||
static volatile unsigned nr_of_initialized_cpus { 0 };
|
||||
static volatile bool kernel_initialized { false };
|
||||
|
||||
Boot_info &boot_info {
|
||||
*reinterpret_cast<Boot_info*>(Hw::Mm::boot_info().base) };
|
||||
|
||||
unsigned const nr_of_cpus { boot_info.cpus };
|
||||
bool const primary_cpu { Cpu::executing_id() == Cpu::primary_id() };
|
||||
|
||||
if (primary_cpu) {
|
||||
|
||||
@ -86,7 +100,7 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
* Let the primary CPU create a Main object and initialize the static
|
||||
* reference to it.
|
||||
*/
|
||||
static Main instance { };
|
||||
static Main instance { nr_of_cpus };
|
||||
Main::_instance = &instance;
|
||||
|
||||
} else {
|
||||
@ -99,43 +113,53 @@ void Kernel::main_initialize_and_handle_kernel_entry()
|
||||
}
|
||||
|
||||
{
|
||||
/**
|
||||
* Let each CPU initialize its corresponding CPU object in the
|
||||
* CPU pool.
|
||||
*/
|
||||
Lock::Guard guard(Main::_instance->_data_lock);
|
||||
|
||||
instance_initialized = true;
|
||||
|
||||
/* initialize current cpu */
|
||||
pool_ready = Main::_instance->_cpu_pool.initialize();
|
||||
Main::_instance->_cpu_pool.initialize_executing_cpu();
|
||||
nr_of_initialized_cpus++;
|
||||
};
|
||||
|
||||
/* wait until all cpus have initialized their corresponding cpu object */
|
||||
while (!pool_ready) { ; }
|
||||
/**
|
||||
* Let all CPUs block until each CPU object in the CPU pool has been
|
||||
* initialized by the corresponding CPU.
|
||||
*/
|
||||
while (nr_of_initialized_cpus < nr_of_cpus) { }
|
||||
|
||||
/* the boot-cpu initializes the rest of the kernel */
|
||||
if (primary_cpu) {
|
||||
Lock::Guard guard(Main::_instance->_data_lock);
|
||||
|
||||
using Boot_info = Hw::Boot_info<Board::Boot_info>;
|
||||
Boot_info &boot_info {
|
||||
*reinterpret_cast<Boot_info*>(Hw::Mm::boot_info().base) };
|
||||
/**
|
||||
* Let the primary CPU initialize the core main thread and finish
|
||||
* initialization of the boot info.
|
||||
*/
|
||||
|
||||
Lock::Guard guard(Main::_instance->_data_lock);
|
||||
|
||||
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);
|
||||
|
||||
Genode::log("");
|
||||
Genode::log("kernel initialized");
|
||||
|
||||
Main::_instance->_core_main_thread.construct(
|
||||
Main::_instance->_cpu_pool);
|
||||
|
||||
boot_info.core_main_thread_utcb =
|
||||
(addr_t)Main::_instance->_core_main_thread->utcb();
|
||||
|
||||
kernel_ready = true;
|
||||
Genode::log("");
|
||||
Genode::log("kernel initialized");
|
||||
kernel_initialized = true;
|
||||
|
||||
} else {
|
||||
/* secondary cpus spin until the kernel is initialized */
|
||||
while (!kernel_ready) {;}
|
||||
|
||||
/**
|
||||
* Let secondary CPUs block until the primary CPU has initialized the
|
||||
* core main thread and finished initialization of the boot info.
|
||||
*/
|
||||
while (!kernel_initialized) {;}
|
||||
}
|
||||
|
||||
Main::_instance->_handle_kernel_entry();
|
||||
|
Loading…
x
Reference in New Issue
Block a user