Source code of Windows XP (NT5)
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.

186 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. platform.h
  5. Abstract:
  6. Platform specific macros and functions.
  7. Author:
  8. Matthew D Hendel (math) 28-Aug-1999
  9. Revision History:
  10. --*/
  11. // Some processors use both a stack and a backing store.
  12. // If a particular processor supports backing store add
  13. // DUMP_BACKING_STORE.
  14. #if defined (i386)
  15. #define PROGRAM_COUNTER(_context) ((_context)->Eip)
  16. #define STACK_POINTER(_context) ((_context)->Esp)
  17. #define INSTRUCTION_WINDOW_SIZE 256
  18. #define PAGE_SIZE 4096
  19. //
  20. // The CONTEXT_FULL definition on x86 doesn't really get all
  21. // the registers. Use ALL_REGISTERS to get the compelte
  22. // context.
  23. //
  24. #define ALL_REGISTERS (CONTEXT_CONTROL |\
  25. CONTEXT_INTEGER |\
  26. CONTEXT_SEGMENTS |\
  27. CONTEXT_FLOATING_POINT |\
  28. CONTEXT_DEBUG_REGISTERS |\
  29. CONTEXT_EXTENDED_REGISTERS)
  30. //
  31. // The following are flags specific to the CPUID instruction on x86 only.
  32. //
  33. #define CPUID_VENDOR_ID (0)
  34. #define CPUID_VERSION_FEATURES (1)
  35. #define CPUID_AMD_EXTENDED_FEATURES (0x80000001)
  36. // X86 doesn't have function entries but it makes the code
  37. // cleaner to provide placeholder types to avoid some ifdefs in the code
  38. // itself.
  39. typedef struct _DYNAMIC_FUNCTION_TABLE {
  40. LIST_ENTRY Links;
  41. ULONG64 MinimumAddress;
  42. ULONG64 MaximumAddress;
  43. ULONG64 BaseAddress;
  44. ULONG EntryCount;
  45. PVOID FunctionTable;
  46. } DYNAMIC_FUNCTION_TABLE, *PDYNAMIC_FUNCTION_TABLE;
  47. typedef struct _RUNTIME_FUNCTION {
  48. ULONG64 Unused;
  49. } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
  50. typedef struct _UNWIND_INFO {
  51. ULONG64 Unused;
  52. } UNWIND_INFO, *PUNWIND_INFO;
  53. #elif defined(_AMD64_)
  54. #define PROGRAM_COUNTER(_context) ((_context)->Rip)
  55. #define STACK_POINTER(_context) ((_context)->Rsp)
  56. #define INSTRUCTION_WINDOW_SIZE 256
  57. #define PAGE_SIZE 4096
  58. #define ALL_REGISTERS (CONTEXT_FULL | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS)
  59. #elif defined (ALPHA)
  60. #define PROGRAM_COUNTER(_context) ((_context)->Fir)
  61. #define STACK_POINTER(_context) ((_context)->IntSp)
  62. #define INSTRUCTION_WINDOW_SIZE 512
  63. #define PAGE_SIZE 8192
  64. #define ALL_REGISTERS (CONTEXT_FULL)
  65. #elif defined (_IA64_)
  66. #define PROGRAM_COUNTER(_context) ((_context)->StIIP)
  67. #define STACK_POINTER(_context) ((_context)->IntSp)
  68. #define INSTRUCTION_WINDOW_SIZE 768
  69. #define PAGE_SIZE 8192
  70. #define ALL_REGISTERS (CONTEXT_FULL | CONTEXT_DEBUG)
  71. #define DUMP_BACKING_STORE
  72. #if 1
  73. // XXX drewb - The TEB bstore values don't seem to point to
  74. // the actual base of the backing store. Just
  75. // assume it's contiguous with the stack.
  76. #define BSTORE_BASE(_teb) ((_teb)->NtTib.StackBase)
  77. #else
  78. #define BSTORE_BASE(_teb) ((_teb)->DeallocationBStore)
  79. #endif
  80. #define BSTORE_LIMIT(_teb) ((_teb)->BStoreLimit)
  81. // The BSP points to the bottom of the current frame's
  82. // storage area. We need to add on the size of the
  83. // current frame to get the amount of memory that
  84. // really needs to be stored. When computing the
  85. // size of the current frame space for NAT bits
  86. // must be figured in properly based on the number
  87. // of entries in the frame. The NAT collection
  88. // is spilled on every 63'rd spilled register to
  89. // make each block an every 64 ULONG64s long.
  90. // On NT the backing store base is always 9-bit aligned
  91. // so we can tell when exactly the next NAT spill
  92. // will occur by looking for when the 9-bit spill
  93. // region will overflow.
  94. __inline ULONG64
  95. BSTORE_POINTER(CONTEXT* Context)
  96. {
  97. ULONG64 Limit = Context->RsBSP;
  98. ULONG Count = (ULONG)(Context->StIFS & 0x7f);
  99. // Add in a ULONG64 for every register in the
  100. // current frame. While doing so, check for
  101. // spill entries.
  102. while (Count-- > 0)
  103. {
  104. Limit += sizeof(ULONG64);
  105. if ((Limit & 0x1f8) == 0x1f8)
  106. {
  107. // Spill will be placed at this address so
  108. // account for it.
  109. Limit += sizeof(ULONG64);
  110. }
  111. }
  112. return Limit;
  113. }
  114. #elif defined (ARM)
  115. #define PROGRAM_COUNTER(_context) ((_context)->Pc)
  116. #define STACK_POINTER(_context) ((_context)->Sp)
  117. #define INSTRUCTION_WINDOW_SIZE 512
  118. #define PAGE_SIZE 4096
  119. #define ALL_REGISTERS (CONTEXT_CONTROL | CONTEXT_INTEGER)
  120. // ARM doesn't have function entries but it makes the code
  121. // cleaner to provide placeholder types to avoid some ifdefs in the code
  122. // itself.
  123. typedef struct _DYNAMIC_FUNCTION_TABLE {
  124. LIST_ENTRY Links;
  125. ULONG64 MinimumAddress;
  126. ULONG64 MaximumAddress;
  127. ULONG64 BaseAddress;
  128. ULONG EntryCount;
  129. PVOID FunctionTable;
  130. } DYNAMIC_FUNCTION_TABLE, *PDYNAMIC_FUNCTION_TABLE;
  131. typedef struct _RUNTIME_FUNCTION {
  132. ULONG64 Unused;
  133. } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
  134. typedef struct _UNWIND_INFO {
  135. ULONG64 Unused;
  136. } UNWIND_INFO, *PUNWIND_INFO;
  137. #else
  138. #error ("unknown processor type")
  139. #endif
  140. #define AMD_VENDOR_ID_0 ('htuA')
  141. #define AMD_VENDOR_ID_1 ('itne')
  142. #define AMD_VENDOR_ID_2 ('DMAc')
  143. #define INTEL_VENDOR_ID_0 ('uneG')
  144. #define INTEL_VENDOR_ID_1 ('Ieni')
  145. #define INTEL_VENDOR_ID_2 ('letn')