Handout
This commit is contained in:
118
kernel/arch/core.h
Normal file
118
kernel/arch/core.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/*! \file
|
||||
* \brief Access to internals of a CPU \ref Core
|
||||
*/
|
||||
|
||||
/*! \defgroup sync CPU Synchronization
|
||||
*
|
||||
* The synchronization module houses functions useful for orchestrating multiple
|
||||
* processors and their activities. Synchronisation, in this case, means
|
||||
* handling the resource contention between multiple participants, running on
|
||||
* either the same or different cores.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "core_cr.h"
|
||||
#include "core_interrupt.h"
|
||||
#include "core_msr.h"
|
||||
|
||||
/*! \brief Implements an abstraction for CPU internals.
|
||||
*
|
||||
* These internals include functions to \ref Core::Interrupt "allow or deny
|
||||
* interrupts", access \ref Core::CR "control registers" TEMPLATE(10-){ as well
|
||||
* as \ref Core::MSR "model specific registers"}.
|
||||
*/
|
||||
namespace Core {
|
||||
|
||||
/*! \brief Maximum number of supported CPUs
|
||||
*/
|
||||
constexpr unsigned MAX = 1;
|
||||
|
||||
/*! \brief Get the ID of the current CPU core
|
||||
* using \ref LAPIC::getID() with an internal lookup table.
|
||||
*
|
||||
* \return ID of current Core (a number between 0 and \ref Core::MAX)
|
||||
*/
|
||||
unsigned getID();
|
||||
|
||||
/*! \brief Initialize this CPU core
|
||||
*
|
||||
* Mark this core as *online* and setup the cores \ref LAPIC by assigning it a
|
||||
* unique \ref APIC::getLogicalAPICID() "logical APIC ID"
|
||||
*
|
||||
* \note Should only be called from \ref kernel_init() during startup.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*! \brief Deinitialize this CPU core
|
||||
*
|
||||
* Mark this Core as *offline*
|
||||
*
|
||||
* \note Should only be called from \ref kernel_init() after returning from
|
||||
* `main()` or `main_ap()`.
|
||||
*/
|
||||
void exit();
|
||||
|
||||
/*! \brief Get number of available CPU cores
|
||||
*
|
||||
* \return total number of cores
|
||||
*/
|
||||
unsigned count();
|
||||
|
||||
/*! \brief Get number of successfully started (and currently active) CPU cores
|
||||
*
|
||||
* \return total number of online cores
|
||||
*/
|
||||
unsigned countOnline();
|
||||
|
||||
/*! \brief Check if CPU core is currently active
|
||||
* \param core_id ID of the CPU core
|
||||
* \return `true` if successfully started and is currently active
|
||||
*/
|
||||
bool isOnline(uint8_t core_id);
|
||||
|
||||
/*! \brief Gives the core a hint that it is executing a spinloop and should
|
||||
* sleep "shortly"
|
||||
*
|
||||
* Improves the over-all performance when executing a spinloop by waiting a
|
||||
* short moment reduce the load on the memory.
|
||||
*
|
||||
* \see [ISDMv2, Chapter 4. PAUSE - Spin Loop
|
||||
* Hint](intel_manual_vol2.pdf#page=887)
|
||||
*/
|
||||
inline void pause() { asm volatile("pause\n\t" : : : "memory"); }
|
||||
|
||||
/*! \brief Halt the CPU core until the next interrupt.
|
||||
*
|
||||
* Halts the current CPU core such that it will wake up on the next interrupt.
|
||||
* Internally, this function first enables the interrupts via `sti` and then
|
||||
* halts the core using `hlt`. Halted cores can only be woken by interrupts. The
|
||||
* effect of `sti` is delayed by one instruction, making the sequence `sti hlt`
|
||||
* atomic (if interrupts were disabled previously).
|
||||
*
|
||||
* \see [ISDMv2, Chapter 4. STI - Set Interrupt
|
||||
* Flag](intel_manual_vol2.pdf#page=1297)
|
||||
* \see [ISDMv2, Chapter 3. HLT - Halt](intel_manual_vol2.pdf#page=539)
|
||||
*/
|
||||
inline void idle() { asm volatile("sti\n\t hlt\n\t" : : : "memory"); }
|
||||
|
||||
/*! \brief Permanently halts the core.
|
||||
*
|
||||
* Permanently halts the current CPU core. Internally, this function first
|
||||
* disables the interrupts via `cli` and then halts the CPU core using `hlt`. As
|
||||
* halted CPU cores can only be woken by interrupts, it is guaranteed that this
|
||||
* core will be halted until the next reboot. The execution of die never
|
||||
* returns. On multicore systems, only the executing CPU core will be halted
|
||||
* permanently, other cores will continue execution.
|
||||
*
|
||||
* \see [ISDMv2, Chapter 3. CLI - Clear Interrupt
|
||||
* Flag](intel_manual_vol2.pdf#page=245)
|
||||
* \see [ISDMv2, Chapter 3. HLT - Halt](intel_manual_vol2.pdf#page=539)
|
||||
*/
|
||||
[[noreturn]] inline void die() {
|
||||
while (true) {
|
||||
asm volatile("cli\n\t hlt\n\t" : : : "memory");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
Reference in New Issue
Block a user