Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

381 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. cpumain.c
  5. Abstract:
  6. This module implements the public interface to the CPU.
  7. Author:
  8. 03-Jul-1995 BarryBo
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #define _WX86CPUAPI_
  17. #include "wx86nt.h"
  18. #include "wx86cpu.h"
  19. #include "cpuassrt.h"
  20. #include "config.h"
  21. #include "instr.h"
  22. #include "threadst.h"
  23. #include "cpunotif.h"
  24. #include "cpuregs.h"
  25. #include "entrypt.h"
  26. #include "compiler.h"
  27. #include "instr.h"
  28. #include "frag.h"
  29. #include "entrypt.h"
  30. #include "mrsw.h"
  31. #include "tc.h"
  32. #include "cpumain.h"
  33. #include "wx86.h"
  34. #include "atomic.h"
  35. #ifdef CODEGEN_PROFILE
  36. #include <coded.h>
  37. #endif
  38. #include "wow64t.h"
  39. #include <wow64.h>
  40. ASSERTNAME;
  41. //
  42. // Identify the CPU type for the debugger extensions
  43. //
  44. WX86_CPUTYPE Wx86CpuType = Wx86CpuCpu;
  45. //
  46. // Per-process CpuNotify bits. These are different than the per-thread
  47. // bits.
  48. //
  49. DWORD ProcessCpuNotify;
  50. NTSTATUS
  51. MsCpuProcessInit(
  52. VOID
  53. )
  54. /*++
  55. Routine Description:
  56. Initialize the CPU. Must be called once at process initialization.
  57. Arguments:
  58. None
  59. Return Value:
  60. None
  61. --*/
  62. {
  63. #if 0
  64. DbgBreakPoint();
  65. #endif
  66. //
  67. // Read all configuration data from the registry
  68. //
  69. GetConfigurationData();
  70. MrswInitializeObject(&MrswEP);
  71. MrswInitializeObject(&MrswTC);
  72. MrswInitializeObject(&MrswIndirTable);
  73. if (!InitializeTranslationCache()) {
  74. return STATUS_UNSUCCESSFUL;
  75. }
  76. if (!initEPAlloc()) {
  77. #if DBG
  78. LOGPRINT((TRACELOG, "CpuProcessInit: Entry Point allocator initialization failed"));
  79. #endif
  80. return STATUS_UNSUCCESSFUL;
  81. }
  82. if (!initializeEntryPointModule()) {
  83. #if DBG
  84. LOGPRINT((TRACELOG, "CpuProcessInit: Entry Point module initialization failed"));
  85. #endif
  86. return STATUS_UNSUCCESSFUL;
  87. }
  88. #if 0
  89. if (!(Wx86LockSynchMutexHandle = CreateMutex(NULL, FALSE, "Wx86LockSynchMutex"))) {
  90. #if DBG
  91. LOGPRINT((TRACELOG, "CpuProcessInit: Cannot create Wx86LockSynchMutex"));
  92. #endif
  93. return STATUS_UNSUCCESSFUL;
  94. }
  95. #endif
  96. RtlInitializeCriticalSection(&Wx86LockSynchCriticalSection);
  97. SynchObjectType = USECRITICALSECTION;
  98. #ifdef CODEGEN_PROFILE
  99. InitCodegenProfile();
  100. #endif
  101. return STATUS_SUCCESS;
  102. }
  103. BOOL
  104. MsCpuProcessTerm(
  105. BOOL OFlyInit
  106. )
  107. {
  108. #if 0
  109. NtClose(Wx86LockSynchMutexHandle);
  110. termEPAlloc();
  111. #endif
  112. return TRUE;
  113. }
  114. BOOL
  115. MsCpuThreadInit(
  116. VOID
  117. )
  118. /*++
  119. Routine Description:
  120. Initialize the CPU. Must be called once for each thread.
  121. Arguments:
  122. None.
  123. Return Value:
  124. TRUE if successful initialization, FALSE if init failed.
  125. --*/
  126. {
  127. DWORD StackBase;
  128. PTEB32 Teb32 = WOW64_GET_TEB32(NtCurrentTeb());
  129. DECLARE_CPU;
  130. if (!FragLibInit(cpu, Teb32->NtTib.StackBase)) {
  131. return FALSE;
  132. }
  133. //
  134. // Mark the callstack as valid
  135. //
  136. cpu->CSTimestamp = TranslationCacheTimestamp;
  137. //
  138. // Mark the TC as being unlocked
  139. //
  140. cpu->fTCUnlocked = TRUE;
  141. //
  142. // All done.
  143. //
  144. return TRUE;
  145. }
  146. VOID
  147. CpuResetToConsistentState(
  148. PEXCEPTION_POINTERS pExceptionPointers
  149. )
  150. /*++
  151. Routine Description:
  152. Called by WX86 when the exception filter around CpuSimulate() fires.
  153. Arguments:
  154. pExceptionPointers - state of the thread at the time the exception
  155. occurred.
  156. Return Value:
  157. None
  158. --*/
  159. {
  160. DECLARE_CPU;
  161. if (!cpu->fTCUnlocked) {
  162. //
  163. // We must unlock the TC before continuing
  164. //
  165. MrswReaderExit(&MrswTC);
  166. cpu->fTCUnlocked = TRUE;
  167. //
  168. // Call the compiler to deduce where Eip should be pointing
  169. // based on the RISC exception record. It is called with
  170. // the Entrypoint write lock because it calls the compiler.
  171. // The compiler's global vars are usable only with EP write.
  172. //
  173. MrswWriterEnter(&MrswEP);
  174. GetEipFromException(cpu, pExceptionPointers);
  175. MrswWriterExit(&MrswEP);
  176. }
  177. Wow64TlsSetValue(WOW64_TLS_EXCEPTIONADDR, LongToPtr(cpu->eipReg.i4));
  178. }
  179. VOID
  180. CpuPrepareToContinue(
  181. PEXCEPTION_POINTERS pExceptionPointers
  182. )
  183. /*++
  184. Routine Description:
  185. Called by WX86 prior to resuming execution on EXCEPTION_CONTINUE_EXECUTION
  186. Arguments:
  187. pExceptionPointers - alpha context with which execution will be resumed.
  188. Return Value:
  189. None
  190. --*/
  191. {
  192. }
  193. BOOLEAN
  194. CpuMapNotify(
  195. PVOID DllBase,
  196. BOOLEAN Mapped
  197. )
  198. /*++
  199. Routine Description:
  200. Called by WX86 when an x86 DLL is loaded or unloaded.
  201. Arguments:
  202. DllBase -- address where x86 DLL was loaded.
  203. Mapped -- TRUE if x86 DLL was just mapped in, FALSE if DLL is just about
  204. to be unmapped.
  205. Return Value:
  206. TRUE on success, FALSE on failure.
  207. --*/
  208. {
  209. if (Mapped) {
  210. NTSTATUS st;
  211. MEMORY_BASIC_INFORMATION mbi;
  212. ULONG Length;
  213. st = NtQueryVirtualMemory(NtCurrentProcess(),
  214. DllBase,
  215. MemoryBasicInformation,
  216. &mbi,
  217. sizeof(mbi),
  218. NULL);
  219. if (NT_SUCCESS(st)) {
  220. Length = (ULONG)mbi.RegionSize;
  221. } else {
  222. // Flush the whole translation cache
  223. DllBase = 0;
  224. Length = 0xffffffff;
  225. }
  226. CpuFlushInstructionCache(DllBase, Length);
  227. }
  228. return TRUE;
  229. }
  230. VOID
  231. CpuEnterIdle(
  232. BOOL OFly
  233. )
  234. /*++
  235. Routine Description:
  236. Called by WX86 when Wx86 ofly is going idle, or when Wx86 is out of
  237. memory and needs some pages. The CPU must free as many resources
  238. as possible.
  239. Arguments:
  240. OFly - TRUE if called from on-the-fly, FALSE if called due to
  241. out of memory.
  242. Return Value:
  243. None.
  244. --*/
  245. {
  246. CpuFlushInstructionCache(0, 0xffffffff);
  247. }
  248. BOOL
  249. CpuIsProcessorFeaturePresent(
  250. DWORD ProcessorFeature
  251. )
  252. /*++
  253. Routine Description:
  254. Called by whkrnl32!whIsProcessorFeaturePresent(). The CPU gets to
  255. fill in its own feature set.
  256. Arguments:
  257. ProcessorFeature -- feature to query (see winnt.h PF_*)
  258. Return Value:
  259. TRUE if feature present, FALSE if not.
  260. --*/
  261. {
  262. BOOL fRet;
  263. switch (ProcessorFeature) {
  264. case PF_FLOATING_POINT_PRECISION_ERRATA:
  265. case PF_COMPARE_EXCHANGE_DOUBLE:
  266. case PF_MMX_INSTRUCTIONS_AVAILABLE:
  267. fRet = FALSE;
  268. break;
  269. case PF_FLOATING_POINT_EMULATED:
  270. //
  271. // TRUE when winpxem.dll used to emulate floating-point with x86
  272. // integer instructions.
  273. //
  274. fRet = fUseNPXEM;
  275. break;
  276. default:
  277. //
  278. // Look up the native feature set
  279. //
  280. fRet = ProxyIsProcessorFeaturePresent(ProcessorFeature);
  281. }
  282. return fRet;
  283. }