The Pedigree Project 0.1
x86_common/ProcessorInformation.h
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#ifndef KERNEL_PROCESSOR_X86_COMMON_PROCESSORINFORMATION_H
21#define KERNEL_PROCESSOR_X86_COMMON_PROCESSORINFORMATION_H
22#include <config.h>
23
24#define _PROCESSOR_INFORMATION_ONLY_WANT_PROCESSORID
25
26#include "pedigree/kernel/compiler.h"
27#include "pedigree/kernel/process/RcuReadState.h"
28#include "pedigree/kernel/processor/ProcessorInformation.h"
29#include "pedigree/kernel/processor/types.h"
30
33class Thread;
36
41class EXPORTED_PUBLIC X86CommonProcessorInformation {
42 friend class ProcessorBase;
43 friend class Multiprocessor;
44
45 public:
47
48#if X64
50 uintptr_t kernelStack;
51 uintptr_t userStack;
53 size_t processorIndex;
54 void* pendingUserEntry;
55#if PEDIGREE_LATENCY_ACCOUNTING
56 size_t latencyNmiDepth = 0;
57#endif
58 };
59 static_assert(__builtin_offsetof(KernelGsAnchor, kernelStack) == 0);
60 static_assert(__builtin_offsetof(KernelGsAnchor, userStack) == 8);
61 static_assert(__builtin_offsetof(KernelGsAnchor, information) == 16);
62 static_assert(__builtin_offsetof(KernelGsAnchor, processorIndex) == 24);
63 static_assert(__builtin_offsetof(KernelGsAnchor, pendingUserEntry) == 32);
64#if PEDIGREE_LATENCY_ACCOUNTING
65 static_assert(__builtin_offsetof(KernelGsAnchor, latencyNmiDepth) == 40);
66 static_assert(sizeof(KernelGsAnchor) == 48);
67#else
68 static_assert(sizeof(KernelGsAnchor) == 40);
69#endif
70
71 KernelGsAnchor* kernelGsAnchor() {
72 return &m_KernelGsAnchor;
73 }
74 void activateKernelGsAnchor(size_t processorIndex);
75#endif
76
79 VirtualAddressSpace& getVirtualAddressSpace() const;
82 void setVirtualAddressSpace(VirtualAddressSpace& virtualAddressSpace);
83
86 void setTssSelector(uint16_t TssSelector);
89 void setTss(void* Tss);
92 uint16_t getTssSelector() const;
95 void* getTss() const;
97 uint16_t getTlsSelector();
99 void setTlsSelector(uint16_t tls);
100
101 uintptr_t getKernelStack() const;
102 void setKernelStack(uintptr_t stack);
103 Thread* getCurrentThread() const {
104 return m_pCurrentThread;
105 }
106 void setCurrentThread(Thread* pThread);
107
108 PerProcessorScheduler& getScheduler();
109
110 RcuReadState& rcuState() {
111 return m_RcuState;
112 }
113
114 ProcessorId processorId() const {
115 return m_ProcessorId;
116 }
117 uint8_t localApicId() const {
118 return m_LocalApicId;
119 }
120
122 void initialiseTscClockAnchor(uint64_t tsc, uint64_t nanoseconds);
123
125 ALWAYS_INLINE bool getTscClockAnchor(uint64_t& tsc, uint64_t& nanoseconds) const {
126 if (!__atomic_load_n(&m_TscClockAnchorInitialised, __ATOMIC_ACQUIRE)) {
127 return false;
128 }
129
130 tsc = __atomic_load_n(&m_TscClockAnchor, __ATOMIC_RELAXED);
131 nanoseconds = __atomic_load_n(&m_TscClockAnchorNanoseconds, __ATOMIC_RELAXED);
132 return true;
133 }
134
135 protected:
138 X86CommonProcessorInformation(ProcessorId processorId, uint8_t apicId = 0);
141
142 void setIds(ProcessorId processorId, uint8_t apicId = 0);
143
144 private:
145 friend class DeviceHardIrqContext;
146 friend class SuspendDeviceHardIrqContext;
147
157
182 RcuReadState m_RcuState;
183
184#if X64
185 KernelGsAnchor m_KernelGsAnchor{0, 0, this, 0, nullptr};
186#endif
187};
188
191#endif
X86CommonProcessorInformation & operator=(const X86CommonProcessorInformation &)
ALWAYS_INLINE bool getTscClockAnchor(uint64_t &tsc, uint64_t &nanoseconds) const
X86CommonProcessorInformation(const X86CommonProcessorInformation &)
size_t ProcessorId