20#include "pedigree/kernel/LockGuard.h"
21#include "pedigree/kernel/Log.h"
22#include "pedigree/kernel/Version.h"
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/machine/Machine.h"
25#include "pedigree/kernel/machine/Timer.h"
26#include "pedigree/kernel/machine/TimerHandler.h"
27#include "pedigree/kernel/process/InfoBlock.h"
28#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
29#include "pedigree/kernel/processor/Processor.h"
30#include "pedigree/kernel/processor/VirtualAddressSpace.h"
31#include "pedigree/kernel/processor/state_forward.h"
32#include "pedigree/kernel/processor/types.h"
33#include "pedigree/kernel/time/Time.h"
34#include "pedigree/kernel/utilities/utility.h"
36InfoBlockManager InfoBlockManager::m_Instance;
38InfoBlockManager::InfoBlockManager()
40 m_bInitialised(false),
41 m_UpdateLock(false, true),
45InfoBlockManager::~InfoBlockManager() {
47 FATAL(
"InfoBlockManager could not drain its timer callback");
51InfoBlockManager& InfoBlockManager::instance() {
55bool InfoBlockManager::initialise() {
62 NOTICE(
"InfoBlockManager: Setting up global info block at " <<
Hex << infoBlock);
66 va.
map(page, infoBlock, 0);
74 ByteSet(m_pInfoBlock, 0,
sizeof(
InfoBlock));
75 StringCopy(m_pInfoBlock->sysname,
"Pedigree");
76 StringCopy(m_pInfoBlock->release,
"Foster");
77 StringCopy(m_pInfoBlock->version, g_pBuildRevision);
79 StringCopy(m_pInfoBlock->machine, g_pBuildTarget);
80 m_pInfoBlock->now = Time::getTimeNanoseconds();
81 m_pInfoBlock->now_s = Time::getTime();
82 m_pInfoBlock->monotonic = Time::getTicks();
85 uint32_t maxLeaf, eax, ebx, ecx, edx;
87 if (maxLeaf >= 0x80000001) {
89 if (edx & (1u << 27)) {
90 m_pInfoBlock->vdso_features |= INFO_BLOCK_VDSO_GETCPU_RDTSCP;
96 __atomic_store_n(&m_bInitialised,
true, __ATOMIC_RELEASE);
98 if (timer && timer->registerHandler(
this)) {
105bool InfoBlockManager::shutdown() {
106 if (m_pTimer && !m_pTimer->unregisterHandler(
this)) {
111 __atomic_store_n(&m_bInitialised,
false, __ATOMIC_RELEASE);
115void InfoBlockManager::timer(uint64_t) {
119void InfoBlockManager::refreshTime() {
120 if (!__atomic_load_n(&m_bInitialised, __ATOMIC_ACQUIRE)) {
126 const Time::Timestamp now = Time::getTimeNanoseconds();
127 m_pInfoBlock->now = now;
128 m_pInfoBlock->now_s = now / Time::Multiplier::Second;
129 m_pInfoBlock->monotonic = Time::getTicks();
132void InfoBlockManager::setPid(
size_t value) {
133 if (
LIKELY(__atomic_load_n(&m_bInitialised, __ATOMIC_ACQUIRE)))
134 m_pInfoBlock->pid = value;
virtual Timer * getTimer()=0
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
static PhysicalMemoryManager & instance()
static constexpr size_t getPageSize() PURE
virtual uintptr_t getGlobalInfoBlock() const
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
static const size_t KernelMode
static const size_t Write
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
static void cpuid(uint32_t inEax, uint32_t inEcx, uint32_t &eax, uint32_t &ebx, uint32_t &ecx, uint32_t &edx)