forked from BSB-WS23/mpstubs
87 lines
2.0 KiB
C++
87 lines
2.0 KiB
C++
#include "startup.h"
|
|
|
|
#include "types.h"
|
|
#include "compiler/libc.h"
|
|
#include "debug/output.h"
|
|
#include "debug/kernelpanic.h"
|
|
#include "interrupt/handler.h"
|
|
#include "machine/acpi.h"
|
|
#include "machine/apic.h"
|
|
#include "machine/core.h"
|
|
#include "machine/idt.h"
|
|
#include "machine/pic.h"
|
|
|
|
/*! \brief The first processor is the Bootstrap Processor (BSP)
|
|
*/
|
|
static bool is_bootstrap_processor = true;
|
|
|
|
extern "C" [[noreturn]] void kernel_init() {
|
|
if (is_bootstrap_processor) {
|
|
is_bootstrap_processor = false;
|
|
/* Setup and load Interrupt Descriptor Table (IDT)
|
|
*
|
|
* On the first call to \ref kernel_init(), we have to assign the
|
|
* addresses of the entry functions for each interrupt
|
|
* (called 'interrupt_entry_VECTOR', defined in `interrupt/handler.asm`)
|
|
* to the IDT. These entry functions save the context and call the C++
|
|
* \ref interrupt_handler(). As the \ref IDT is used by all CPUs,
|
|
* it is sufficient to do this initialization on only the BSP (first core).
|
|
*/
|
|
for (int i = 0; i < Core::Interrupt::VECTORS ; i++) {
|
|
IDT::handle(i, interrupt_entry[i]);
|
|
}
|
|
IDT::load();
|
|
|
|
// Initialize PICs
|
|
PIC::initialize();
|
|
|
|
// Call global constructors
|
|
CSU::initializer();
|
|
|
|
// Initialize ACPI
|
|
if (!ACPI::init()) {
|
|
DBG_VERBOSE << "No ACPI!";
|
|
Core::die();
|
|
}
|
|
// Initialize APIC (using ACPI)
|
|
if (!APIC::init()) {
|
|
DBG_VERBOSE << "APIC Initialization failed";
|
|
Core::die();
|
|
}
|
|
|
|
// Initialize the Bootstrap Processor
|
|
Core::init();
|
|
|
|
// Go to main function
|
|
main();
|
|
|
|
// Exit CPU
|
|
DBG_VERBOSE << "CPU core " << Core::getID() << " (BSP) shutdown." << endl;
|
|
Core::exit();
|
|
} else {
|
|
// Load Interrupt Descriptor Table (IDT)
|
|
IDT::load();
|
|
|
|
// Initialize this application processor
|
|
Core::init();
|
|
|
|
// And call the AP main
|
|
main_ap();
|
|
|
|
// Exit CPU
|
|
DBG_VERBOSE << "CPU core " << Core::getID() << " (AP) shutdown." << endl;
|
|
Core::exit();
|
|
}
|
|
|
|
// Only on last core
|
|
if (Core::countOnline() == 1) {
|
|
// Call global destructors
|
|
CSU::finalizer();
|
|
}
|
|
|
|
// wait forever
|
|
while (true) {
|
|
Core::die();
|
|
}
|
|
}
|