The Pedigree Project 0.1
x86_common/ProcessorInformation.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/process/InfoBlock.h"
21#include "pedigree/kernel/process/PerProcessorScheduler.h"
22#include "pedigree/kernel/process/Process.h"
23#include "pedigree/kernel/process/Thread.h"
24#include "pedigree/kernel/processor/Processor.h"
25#include "pedigree/kernel/processor/VirtualAddressSpace.h"
26#include "pedigree/kernel/processor/state.h"
27#include "pedigree/kernel/processor/types.h"
28#include "pedigree/kernel/processor/x64/tss.h"
29#include "pedigree/kernel/processor/x86_common/ProcessorInformation.h"
30#include "pedigree/kernel/utilities/new"
31
43 VirtualAddressSpace& virtualAddressSpace) {
44 m_VirtualAddressSpace = &virtualAddressSpace;
45}
46
50 m_TssSelector = TssSelector;
51}
55 m_Tss = reinterpret_cast<TaskStateSegment*>(Tss);
56}
65 return reinterpret_cast<void*>(m_Tss);
66}
75
76uintptr_t X86CommonProcessorInformation::getKernelStack() const {
77 return m_Tss->rsp0;
78}
79void X86CommonProcessorInformation::setKernelStack(uintptr_t stack) {
80#if X64
81 // Event-stack retirement and scheduling must not leave a borrowed frame behind.
82 pedigree_materialize_user_entry();
83#endif
84 m_Tss->rsp0 = stack;
85#if X64
86 m_KernelGsAnchor.kernelStack = stack;
87#endif
88}
89
90#if X64
91void X86CommonProcessorInformation::activateKernelGsAnchor(size_t processorIndex) {
92 m_KernelGsAnchor.processorIndex = processorIndex;
93 const uintptr_t entry = reinterpret_cast<uintptr_t>(&m_KernelGsAnchor);
94 uint32_t eax = entry, edx = entry >> 32;
95 // Kernel GS stays local to the CPU; the alternate MSR belongs to userspace.
96 asm volatile("wrmsr" ::"a"(eax), "d"(edx), "c"(0xc0000101) : "memory");
97}
98#endif
99
100void X86CommonProcessorInformation::setCurrentThread(Thread* pThread) {
101 if (m_RcuState.active()) {
102 panic("Context switch inside an RCU read section.");
103 }
104#if X64
106 m_pCurrentThread->saveUserGsBase();
107#endif
108 m_pCurrentThread = pThread;
109#if X64
110 Processor::setUserGsBase(pThread->getUserGsBase());
111#endif
112 InfoBlockManager::instance().setPid(pThread->getParent()->getId());
113}
114
115PerProcessorScheduler& X86CommonProcessorInformation::getScheduler() {
116 // Allocate the scheduler lazily.
117 if (m_Scheduler == nullptr) {
119 }
120 return *m_Scheduler;
121}
122
123void X86CommonProcessorInformation::initialiseTscClockAnchor(uint64_t tsc, uint64_t nanoseconds) {
124 __atomic_store_n(&m_TscClockAnchor, tsc, __ATOMIC_RELAXED);
125 __atomic_store_n(&m_TscClockAnchorNanoseconds, nanoseconds, __ATOMIC_RELAXED);
126 __atomic_store_n(&m_TscClockAnchorInitialised, true, __ATOMIC_RELEASE);
127}
128
130 uint8_t apicId)
131 : m_ProcessorId(processorId),
132 m_TssSelector(0),
133 m_Tss(0),
134 m_VirtualAddressSpace(&VirtualAddressSpace::getKernelAddressSpace()),
135 m_LocalApicId(apicId),
136 m_pCurrentThread(0),
137 m_Scheduler(nullptr),
138 m_TlsSelector(0),
139 m_DeviceHardIrqDepth(0),
140 m_TscClockAnchor(0),
141 m_TscClockAnchorNanoseconds(0),
142 m_TscClockAnchorInitialised(false) {}
147
148void X86CommonProcessorInformation::setIds(ProcessorId processorId, uint8_t apicId) {
149 m_ProcessorId = processorId;
150 m_LocalApicId = apicId;
151}
size_t getId()
Definition Process.h:499
Process * getParent() const
Definition Thread.h:340
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
void initialiseTscClockAnchor(uint64_t tsc, uint64_t nanoseconds)
void setVirtualAddressSpace(VirtualAddressSpace &virtualAddressSpace)
VirtualAddressSpace & getVirtualAddressSpace() const
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
Definition panic.cc:118
size_t ProcessorId