The Pedigree Project  0.1
Processor.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_PROCESSOR_H
21 #define KERNEL_PROCESSOR_PROCESSOR_H
22 
23 #include "pedigree/kernel/compiler.h"
24 #include "pedigree/kernel/processor/ProcessorInformation.h" // exported
25 #include "pedigree/kernel/processor/state_forward.h"
26 #include "pedigree/kernel/processor/types.h"
27 #include "pedigree/kernel/utilities/StaticString.h"
28 #if defined(MULTIPROCESSOR)
29 template <class T>
30 class Vector;
31 #endif
32 
34 #ifdef MULTIBOOT
35 class BootstrapStruct_t;
36 #else
37 struct BootstrapStruct_t;
38 #endif
39 
43 namespace DebugFlags
44 {
45 enum FaultType
46 {
47  InstructionFetch = 0,
48  DataWrite = 1,
49  IOReadWrite = 2,
50  DataReadWrite = 3
51 };
52 }
53 
55 #define DEBUG_BREAKPOINT_0 0x01
56 #define DEBUG_BREAKPOINT_1 0x02
57 #define DEBUG_BREAKPOINT_2 0x04
58 #define DEBUG_BREAKPOINT_3 0x08
59 #define DEBUG_REG_ACCESS \
60  0x2000
61 #define DEBUG_SINGLE_STEP \
63  0x4000
64 #define DEBUG_TASK_SWITCH \
66  0x8000
67 
68 #ifdef MULTIPROCESSOR
69 
74 extern void apMain() NORETURN;
75 #endif
76 
81 {
82  friend class Multiprocessor;
83  friend class X86GdtManager;
84  friend class X64GdtManager;
85 #ifdef THREADS
86  friend class Scheduler;
87 #endif
88  public:
96  static void initialise1(const BootstrapStruct_t &Info) INITIALISATION_ONLY;
103  static void initialise2(const BootstrapStruct_t &Info) INITIALISATION_ONLY;
106  static void initialisationDone();
109  static void deinitialise();
114  static size_t isInitialised();
115 
118  static uintptr_t getBasePointer();
121  static uintptr_t getStackPointer();
124  static uintptr_t getInstructionPointer();
125 
128  static void switchAddressSpace(VirtualAddressSpace &AddressSpace);
129 
134  static bool saveState(SchedulerState &state)
135 #ifdef SYSTEM_REQUIRES_ATOMIC_CONTEXT_SWITCH
136  DEPRECATED
137 #endif
138  ;
142  static void
143  restoreState(SchedulerState &state, volatile uintptr_t *pLock = 0) NORETURN;
147  static void
148  restoreState(SyscallState &state, volatile uintptr_t *pLock = 0) NORETURN;
149 #ifdef SYSTEM_REQUIRES_ATOMIC_CONTEXT_SWITCH
150 
151  static void switchState(
152  bool bInterrupts, SchedulerState &a, SchedulerState &b,
153  volatile uintptr_t *pLock = 0);
155  static void switchState(
156  bool bInterrupts, SchedulerState &a, SyscallState &b,
157  volatile uintptr_t *pLock = 0);
168  static void saveAndJumpKernel(
169  bool bInterrupts, SchedulerState &s, volatile uintptr_t *pLock,
170  uintptr_t address, uintptr_t stack, uintptr_t p1 = 0, uintptr_t p2 = 0,
171  uintptr_t p3 = 0, uintptr_t p4 = 0);
182  static void saveAndJumpUser(
183  bool bInterrupts, SchedulerState &s, volatile uintptr_t *pLock,
184  uintptr_t address, uintptr_t stack, uintptr_t p1 = 0, uintptr_t p2 = 0,
185  uintptr_t p3 = 0, uintptr_t p4 = 0);
186 #endif // SYSTEM_REQUIRES_ATOMIC_CONTEXT_SWITCH
187 
196  static void jumpKernel(
197  volatile uintptr_t *pLock, uintptr_t address, uintptr_t stack,
198  uintptr_t p1 = 0, uintptr_t p2 = 0, uintptr_t p3 = 0,
199  uintptr_t p4 = 0) NORETURN;
209  static void jumpUser(
210  volatile uintptr_t *pLock, uintptr_t address, uintptr_t stack,
211  uintptr_t p1 = 0, uintptr_t p2 = 0, uintptr_t p3 = 0,
212  uintptr_t p4 = 0) NORETURN;
213 
215  static void breakpoint();
217  static void halt();
219  static void reset();
220 
223  static size_t getDebugBreakpointCount();
229  static uintptr_t getDebugBreakpoint(
230  size_t nBpNumber, DebugFlags::FaultType &nFaultType, size_t &nLength,
231  bool &bEnabled);
238  static void enableDebugBreakpoint(
239  size_t nBpNumber, uintptr_t nLinearAddress,
240  DebugFlags::FaultType nFaultType, size_t nLength);
244  static void disableDebugBreakpoint(size_t nBpNumber);
248  static uintptr_t getDebugStatus();
249 
251  static void haltUntilInterrupt();
253  static void pause();
254 
257  static void setInterrupts(bool bEnable);
260  static bool getInterrupts();
264  static void setSingleStep(bool bEnable, InterruptState &state);
265 
266 #if defined(X86_COMMON)
267 
270  static uint64_t readMachineSpecificRegister(uint32_t index);
274  static void writeMachineSpecificRegister(uint32_t index, uint64_t value);
282  static void cpuid(
283  uint32_t inEax, uint32_t inEcx, uint32_t &eax, uint32_t &ebx,
284  uint32_t &ecx, uint32_t &edx);
285 #endif
286 
290 #ifdef PPC_COMMON
291  inline
292 #endif
293  static void
294  invalidate(void *pAddress);
295 
296 #if defined(X86_COMMON)
297  static physical_uintptr_t readCr3();
298 #endif
299 
300 #if defined(ARMV7)
301 
302  static physical_uintptr_t readTTBR0();
304  static physical_uintptr_t readTTBR1();
306  static uint32_t readTTBCR();
308  static void writeTTBR0(physical_uintptr_t value);
310  static void writeTTBR1(physical_uintptr_t value);
312  static void writeTTBCR(uint32_t value);
313 #endif
314 
315 #if defined(MIPS_COMMON) || defined(PPC_COMMON)
316 
319  static void invalidateICache(uintptr_t nAddr);
323  static void invalidateDCache(uintptr_t nAddr);
327  static void flushDCache(uintptr_t nAddr);
333  static void
334  flushDCacheAndInvalidateICache(uintptr_t startAddr, uintptr_t endAddr);
335 #endif
336 
339  static void identify(HugeStaticString &str);
340 
343 #if !defined(MULTIPROCESSOR)
344  static ProcessorId id();
345 #else
346  static ProcessorId id();
347 #endif
348 
350 #if !defined(MULTIPROCESSOR)
351  static ProcessorInformation &information();
352 #else
353  static ProcessorInformation &information();
354 #endif
355 
356 #if !defined(MULTIPROCESSOR)
357  static size_t getCount();
358 #else
359  static size_t getCount();
360 #endif
361 
362 #ifdef PPC_COMMON
363  static void
364  setSegmentRegisters(uint32_t segmentBase, bool supervisorKey, bool userKey);
365 #endif
366 
368  static void setTlsBase(uintptr_t newBase);
369 
371  static size_t m_Initialised;
372 
373  private:
374 #if defined(HOSTED)
375 
376  static void _breakpoint();
377  static void _reset() NORETURN;
378  static void _haltUntilInterrupt();
379 
380  static bool m_bInterrupts;
381 #endif
382 
385 #if !defined(MULTIPROCESSOR)
386  static ProcessorInformation m_ProcessorInformation;
387 #else
388  static Vector<ProcessorInformation *> m_ProcessorInformation;
389 
392  static ProcessorInformation m_SafeBspProcessorInformation;
393 #endif
394 
395  static size_t m_nProcessors;
396 };
397 
400 #if defined(X86_COMMON)
401 #include "pedigree/kernel/processor/x86_common/Processor.h" // IWYU pragma: export
402 #elif defined(MIPS_COMMON)
403 #include "pedigree/kernel/processor/mips_common/Processor.h" // IWYU pragma: export
404 #elif defined(ARM_COMMON)
405 #include "pedigree/kernel/processor/arm_common/Processor.h" // IWYU pragma: export
406 #elif defined(PPC_COMMON)
407 #include "pedigree/kernel/processor/ppc_common/Processor.h" // IWYU pragma: export
408 #elif defined(HOSTED)
409 #include "pedigree/kernel/processor/hosted/Processor.h" // IWYU pragma: export
410 #endif
411 
412 #ifdef X86
413 #include "pedigree/kernel/processor/x86/Processor.h" // IWYU pragma: export
414 #endif
415 #ifdef X64
416 #include "pedigree/kernel/processor/x64/Processor.h" // IWYU pragma: export
417 #endif
418 
424 {
425  public:
426  EnsureInterrupts(bool desired);
427  virtual ~EnsureInterrupts();
428 
429  private:
430  bool m_bPrevious;
431 };
432 
433 #endif
Bootstrap structure passed to the kernel entry point.
This class manages how processes and threads are scheduled across processors.
Definition: Scheduler.h:44
A vector / dynamic array.
static size_t m_Initialised
Definition: Processor.h:371
The exception was caused by a hardware task switch.
Definition: Processor.h:80
size_t ProcessorId
static ProcessorInformation m_ProcessorInformation
Definition: Processor.h:386