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.

482 lines
12 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. genxx.h
  5. Abstract:
  6. This file contains macros (some of them destined for the M4 preprocessor)
  7. to aid in the generation of ks & hal header files. This is used by
  8. ke\xxx\genxxx.c, as well as sdktools\genxx.
  9. Author:
  10. Forrest C. Foltz (forrestf) 23-Jan-1998
  11. Revision History:
  12. --*/
  13. //
  14. // Structure element definitions.
  15. //
  16. #define MAX_ELEMENT_NAME_LEN 127 // big enough for comments too
  17. typedef struct _STRUC_ELEMENT {
  18. //
  19. // Flags is one or more SEF_xxx, defined below.
  20. //
  21. UINT64 Flags;
  22. //
  23. // Note that Equate is used to store a pointer in the case of bitfield
  24. // processing.
  25. //
  26. UINT64 Equate;
  27. //
  28. // Name should be quite long, as it is used to hold comments as well.
  29. //
  30. CHAR Name[ MAX_ELEMENT_NAME_LEN + 1 ];
  31. } STRUC_ELEMENT, *PSTRUC_ELEMENT;
  32. #define SEF_ENABLE_MASK 0x0000FF00
  33. #define SEF_HAL 0x00000100
  34. #define SEF_KERNEL 0x00000200
  35. #define SEF_INC_FORMAT_MASK 0x00010000
  36. #define SEF_H_FORMAT 0x00000000
  37. #define SEF_INC_FORMAT 0x00010000
  38. //
  39. // Types. Note that SETMASK, CLRMASK has no effect on te BITFLD types. BITFLD
  40. // types have SEF_HAL | SEF_KERNEL set in the type.
  41. //
  42. #define SEF_TYPE_MASK 0x000000FF
  43. #define SEF_EQUATE 0x00000000
  44. #define SEF_EQUATE64 0x00000001
  45. #define SEF_COMMENT 0x00000002
  46. #define SEF_STRING 0x00000003 // Equate is vararg to printf
  47. #define SEF_BITFLD 0x00000004
  48. #define SEF_BITALIAS 0x00000005
  49. #define SEF_STRUCTURE 0x00000006
  50. #define SEF_SETMASK 0x00000010 // Equate is the mask
  51. #define SEF_CLRMASK 0x00000011 // Equate is the mask
  52. #define SEF_END 0x00000012
  53. #define SEF_START 0x00000013
  54. #define SEF_PATH 0x00000014
  55. //
  56. // Note that BITFLD entries have per-entry hal|kernel flags
  57. //
  58. //
  59. // Define architecture specific generation macros.
  60. //
  61. #define SEF_FLAGS 0
  62. #define HAL SEF_HAL
  63. #define KERNEL SEF_KERNEL
  64. #ifndef ULONG_MAX
  65. #define ULONG_MAX 0xFFFFFFFF
  66. #endif
  67. #ifndef LONG_MAX
  68. #define LONG_MAX ((LONG)0x7FFFFFFF)
  69. #endif
  70. #ifndef LONG_MIN
  71. #define LONG_MIN ((LONG)0x80000000)
  72. #endif
  73. #ifdef _WIN64_
  74. #define SEF_UINT SEF_EQUATE64
  75. #else
  76. #define SEF_UINT SEF_EQUATE
  77. #endif
  78. //
  79. // genDef(Pc, KPCR, MinorVersion)
  80. //
  81. // -> #define PcMinorVersion 0x0
  82. //
  83. #define genDef(Prefix, Type, Member) \
  84. { SEF_EQUATE, OFFSET(Type, Member), #Prefix #Member },
  85. //
  86. // genOff(Pc, KPCR, MinorVersion, 128)
  87. //
  88. // -> #define PcMinorVersion 0xffffff80
  89. //
  90. #define genOff(Prefix, Type, Member, Offset) \
  91. { SEF_EQUATE, OFFSET(Type, Member) - Offset, #Prefix #Member },
  92. //
  93. // genAlt( PbAlignmentFixupCount, KPRCB, KeAlignmentFixupCount )
  94. //
  95. // -> #define PbAlignmentFixupCount 0x2f4
  96. //
  97. #define genAlt(Name, Type, Member) \
  98. { SEF_EQUATE, OFFSET(Type, Member), #Name },
  99. //
  100. // genCom("This is a comment")
  101. //
  102. // //
  103. // -> // This is a comment
  104. // //
  105. //
  106. #define genCom(Comment) \
  107. { SEF_COMMENT, 0, Comment },
  108. //
  109. // genNam(PCR_MINOR_VERSION)
  110. //
  111. // -> #define PCR_MINOR_VERSION 0x1
  112. //
  113. #define genNam(Name) \
  114. { SEF_EQUATE, (ULONG)(Name), #Name },
  115. //
  116. // genNamUint(KSEG0_BASE)
  117. //
  118. // -> #define KSE0_BASE 0xffffffff80000000
  119. //
  120. #define genNamUint(Name) \
  121. { SEF_UINT, (UINT64)(Name), #Name },
  122. //
  123. // genVal(FirmwareFrameLength, FIRMWARE_FRAME_LENGTH)
  124. //
  125. // -> #define FirmwareFrameLength 0x250
  126. //
  127. // Note: if the value is 64-bit when _WIN64_ is enabled, use genValUint()
  128. //
  129. #define genVal(Name, Value) \
  130. { SEF_EQUATE, (ULONG)(Value), #Name },
  131. //
  132. // genValUint(KiPcr, KIPCR)
  133. //
  134. // -> #define KiPcr 0xe0000000ffffe000
  135. //
  136. #define genValUint(Name, Value) \
  137. { SEF_UINT, (UINT64)(Value), #Name },
  138. //
  139. // genSpc()
  140. //
  141. // ->
  142. //
  143. #define genSpc() \
  144. { SEF_STRING, 0, "\n" },
  145. //
  146. // genStr(" PCR equ ds:[0%lXH]\n", KIP0PCRADDRESS)
  147. //
  148. // -> PCR equ ds:[0FFDFF000H]
  149. //
  150. #define genStr(String, Value) \
  151. { SEF_STRING, (ULONG_PTR)(Value), String },
  152. //
  153. // genTxt("ifdef NT_UP\n")
  154. //
  155. // -> ifdef NT_UP
  156. //
  157. #define genTxt(String) \
  158. { SEF_STRING, 0, String },
  159. #define DisableInc( x ) \
  160. { SEF_CLRMASK, x, "" },
  161. #define EnableInc( x ) \
  162. { SEF_SETMASK, x, "" },
  163. #define MARKER_STRING "This is the genxx marker string."
  164. //
  165. // Source file can specify the _NTDRIVE\_NTROOT - relative output path.
  166. // 'f' is the set of enable-flags that should be routed to this file.
  167. // Use '0' if there is only a single output file.
  168. //
  169. // 'f' should also contain one of SEF_H_FORMAT or SEF_INC_FORMAT to
  170. // indicate whether the generated file is in 'header file' or 'include file'
  171. // format.
  172. //
  173. #define setPath( p, f ) \
  174. { SEF_PATH | f, 0, p },
  175. //
  176. // START_LIST defines the first element in ElementList. This element contains
  177. // a (possibly truncated) pointer to the ElementList array. This is used to
  178. // determine the fixup RA bias.
  179. //
  180. #define START_LIST \
  181. { SEF_START, (ULONG_PTR)ElementList, MARKER_STRING },
  182. #define END_LIST \
  183. { SEF_END, 0, "" }
  184. //
  185. // Preprocessor assertion. Do something here to make the compiler generate
  186. // an error if x != y.
  187. //
  188. #define ASSERT_SAME( x, y )
  189. //
  190. // Macro to round Val up to the next Bnd boundary. Bnd must be an integral
  191. // power of two.
  192. //
  193. #define ROUND_UP( Val, Bnd ) \
  194. (((Val) + ((Bnd) - 1)) & ~((Bnd) - 1))
  195. #ifndef OFFSET
  196. //
  197. // Define member offset computation macro.
  198. //
  199. #define OFFSET(type, field) ((ULONG_PTR)(&((type *)0)->field))
  200. #endif
  201. //
  202. // Following are some M4 macros to help with bitfields.
  203. //
  204. #ifndef SKIP_M4
  205. //
  206. // First, define the makezeros(n) macro that will generate a string with
  207. // n pairs of ',0'. This is a recursively defined macro.
  208. //
  209. define(`makezeros',`ifelse(eval($1),0,,`0,makezeros(eval($1-1))')')
  210. //
  211. // Define a concatenation macro.
  212. //
  213. define(`cat',`$1$2')
  214. //
  215. // The following example bitfield declaration uses HARDWARE_PTE as an
  216. // example, which is declared (for alpha) as follows:
  217. //
  218. // typedef struct _HARDWARE_PTE {
  219. // ULONG Valid: 1;
  220. // ULONG Owner: 1;
  221. // ULONG Dirty: 1;
  222. // ULONG reserved: 1;
  223. // ULONG Global: 1;
  224. // ULONG GranularityHint: 2;
  225. // ULONG Write: 1;
  226. // ULONG CopyOnWrite: 1;
  227. // ULONG PageFrameNumber: 23;
  228. // } HARDWARE_PTE, *PHARDWARE_PTE;
  229. //
  230. //
  231. // // First, startBitStruc() is invoked with the structure name.
  232. //
  233. // startBitStruc( HARDWARE_PTE, SEF_HAL | SEF_KERNEL )
  234. //
  235. // //
  236. // // Now, suppose we wanted to expose seven of the fields in an assembly
  237. // // include file:
  238. // //
  239. //
  240. // genBitField( Valid, PTE_VALID )
  241. // genBitField( Owner, PTE_OWNER )
  242. // genBitField( Dirty, PTE_DIRTY )
  243. // genBitField( reserved )
  244. // genBitField( Global, PTE_GLOBAL )
  245. // genBitField( GranularityHint )
  246. // genBitField( Write, PTE_WRITE )
  247. // genBitField( CopyOnWrite, PTE_COPYONWRITE )
  248. // genBitField( PageFrameNumber, PTE_PFN )
  249. //
  250. // Note that fields that are not used (in this case 'reserved' and
  251. // 'GranularityHint') must still appear in the list.
  252. //
  253. // The above will generate a bunch of static, initialized copies of HARDWARE_PTE
  254. // like so:
  255. //
  256. // HARDWARE_PTE HARDWARE_PTE_Valid = {
  257. // 0xFFFFFFFF };
  258. //
  259. // HARDWARE_PTE HARDWARE_PTE_Owner = {
  260. // 0, // Valid
  261. // 0xFFFFFFFF };
  262. //
  263. // HARDWARE_PTE HARDWARE_PTE_Dirty = {
  264. // 0, // Valid
  265. // 0, // Owner
  266. // 0xFFFFFFFF };
  267. //
  268. // HARDWARE_PTE HARDWARE_PTE_Global = {
  269. // 0, // Valid
  270. // 0, // Owner
  271. // 0, // Dirty
  272. // 0, // reserved
  273. // 0xFFFFFFFF };
  274. //
  275. // HARDWARE_PTE HARDWARE_PTE_Write = {
  276. // 0, // Valid
  277. // 0, // Owner
  278. // 0, // Dirty
  279. // 0, // reserved (skipped)
  280. // 0, // Global
  281. // 0xFFFFFFFF };
  282. //
  283. // HARDWARE_PTE HARDWARE_PTE_CopyOnWrite = {
  284. // 0, // Valid
  285. // 0, // Owner
  286. // 0, // Dirty
  287. // 0, // reserved (skipped)
  288. // 0, // Global
  289. // 0, // GranularityHint (skipped)
  290. // 0xFFFFFFFF };
  291. //
  292. // HARDWARE_PTE HARDWARE_PTE_PageFrameNumber = {
  293. // 0, // Valid
  294. // 0, // Owner
  295. // 0, // Dirty
  296. // 0, // reserved (skipped)
  297. // 0, // Global
  298. // 0, // GranularityHint (skipped)
  299. // 0, // CopyOnWrite
  300. // 0xFFFFFFFF };
  301. //
  302. // Then, as part of processing the END_LIST macro, these structures are
  303. // generated:
  304. //
  305. // { SEF_BITFLD, &HARDWARE_PTE_Valid, "PTE_VALID" },
  306. // { SEF_BITFLD, &HARDWARE_PTE_Owner, "PTE_OWNER" },
  307. // { SEF_BITFLD, &HARDWARE_PTE_Dirty, "PTE_DIRTY" },
  308. // { SEF_BITFLD, &HARDWARE_PTE_Global, "PTE_GLOBAL" },
  309. // { SEF_BITFLD, &HARDWARE_PTE_Write, "PTE_WRITE" },
  310. // { SEF_BITFLD, &HARDWARE_PTE_CopyOnWrite, "PTE_COPYONWRITE" },
  311. // { SEF_BITFLD, &HARDWARE_PTE_PageFrameNumber, "PTE_PFN" },
  312. // { SEF_END, 0, "" }
  313. //
  314. //
  315. // ... and that's what gets compiled by the target compiler into the .obj.
  316. // Now, the final stage: genxx.exe is run against this target .obj, and
  317. // would generate the following:
  318. //
  319. // #define PTE_VALID_MASK 0x1
  320. // #define PTE_VALID 0x0
  321. // #define PTE_OWNER_MASK 0x2
  322. // #define PTE_OWNER 0x1
  323. // #define PTE_DIRTY_MASK 0x4
  324. // #define PTE_DIRTY 0x2
  325. // #define PTE_GLOBAL_MASK 0x10
  326. // #define PTE_GLOBAL 0x4
  327. // #define PTE_WRITE_MASK 0x80
  328. // #define PTE_WRITE 0x7
  329. // #define PTE_COPYONWRITE_MASK 0x100
  330. // #define PTE_COPYONWRITE 0x8
  331. // #define PTE_PFN_MASK 0xfffffe00
  332. // #define PTE_PFN 0x9
  333. //
  334. //
  335. // BITFIELD_STRUCS accumulates array element initializations. END_LIST will
  336. // dump these into the definition array.
  337. //
  338. define(`BITFIELD_STRUCS',`')
  339. //
  340. // startBitStruc( <strucname>, <whichfile> )
  341. // sets BIT_STRUC_NAME = <strucname> and resets the ZERO_FIELDS count to 0.
  342. // It also sets the WHICH_FILE macro.
  343. //
  344. define(`startBitStruc', `define(`BIT_STRUC_NAME',`$1')
  345. define(`BITFIELD_STRUCS',
  346. BITFIELD_STRUCS
  347. )
  348. define(`ZERO_FIELDS',0)
  349. define(`SEF_TYPE',$2)
  350. ')
  351. //
  352. // genBitField( <fldname>, <generatedname> ) declares a structure of type
  353. // <strucname> and initializes the <fldname> bitfield within it.
  354. //
  355. // Note that I used "cma" instead of an actual comma, this gets changed to
  356. // a comma by DUMP_BITFIELDS, below. If I were more proficient with M4 I
  357. // would know how to get around this.
  358. //
  359. define(`genBitField', `define(`VAR_NAME', cat(cat(BIT_STRUC_NAME,`_'),$1))
  360. `#'define `def_'VAR_NAME
  361. BIT_STRUC_NAME VAR_NAME = {'
  362. `makezeros(ZERO_FIELDS)'
  363. `(ULONG_PTR)-1 };'
  364. `define(`PAD_VAR_NAME', cat(cat(BIT_STRUC_NAME,`p'),$1))'
  365. `ULONG64 PAD_VAR_NAME = 0x8000000000000000UI64;'
  366. `define(`ZERO_FIELDS',incr(ZERO_FIELDS))'
  367. `define(`FIELD_NAME', $1)'
  368. `define(`FIELD_ASMNAME', $2)'
  369. `define(`BITFIELD_STRUCS',
  370. BITFIELD_STRUCS
  371. `#i'fdef `def_'VAR_NAME
  372. `#i'fndef `dec_'VAR_NAME
  373. `#de'fine `dec_'VAR_NAME
  374. { SEF_BITFLD | SEF_TYPE cma (ULONG_PTR)&VAR_NAME cma "FIELD_ASMNAME" } cma
  375. `#e'ndif
  376. `#e'ndif
  377. )'
  378. )
  379. define(`genBitAlias', `define(`BITFIELD_STRUCS',
  380. BITFIELD_STRUCS
  381. `#i'fdef `def_'VAR_NAME
  382. `#i'fndef `deca_'VAR_NAME
  383. `#de'fine `deca_'VAR_NAME
  384. { SEF_BITALIAS | SEF_TYPE cma 0 cma "$1" } cma
  385. `#e'ndif
  386. `#e'ndif
  387. )'
  388. )
  389. //
  390. // DUMP_BITFIELDS dumps the array initializers accumulated by BITFIELD_STRUCS,
  391. // after replacing each 'cma' with an actual comma.
  392. //
  393. define(`DUMP_BITFIELDS',`define(`cma',`,') BITFIELD_STRUCS')
  394. #endif // SKIP_M4