00001 /*++ 00002 00003 Copyright (c) 1998 Microsoft Corporation 00004 00005 Module Name: 00006 00007 genxx.h 00008 00009 Abstract: 00010 00011 This file contains macros (some of them destined for the M4 preprocessor) 00012 to aid in the generation of ks & hal header files. This is used by 00013 ke\xxx\genxxx.c, as well as sdktools\genxx. 00014 00015 Author: 00016 00017 Forrest C. Foltz (forrestf) 23-Jan-1998 00018 00019 Revision History: 00020 00021 --*/ 00022 00023 00024 00025 // 00026 // Structure element definitions. 00027 // 00028 00029 #define MAX_ELEMENT_NAME_LEN 127 // big enough for comments too 00030 typedef struct _STRUC_ELEMENT { 00031 00032 // 00033 // Flags is one or more SEF_xxx, defined below. 00034 // 00035 00036 UINT64 Flags; 00037 00038 // 00039 // Note that Equate is used to store a pointer in the case of bitfield 00040 // processing. 00041 // 00042 00043 UINT64 Equate; 00044 00045 // 00046 // Name should be quite long, as it is used to hold comments as well. 00047 // 00048 00049 CHAR Name[ MAX_ELEMENT_NAME_LEN + 1 ]; 00050 } STRUC_ELEMENT, *PSTRUC_ELEMENT; 00051 00052 #define SEF_ENABLE_MASK 0x0000FF00 00053 #define SEF_HAL 0x00000100 00054 #define SEF_KERNEL 0x00000200 00055 00056 #define SEF_INC_FORMAT_MASK 0x00010000 00057 #define SEF_H_FORMAT 0x00000000 00058 #define SEF_INC_FORMAT 0x00010000 00059 00060 // 00061 // Types. Note that SETMASK, CLRMASK has no effect on te BITFLD types. BITFLD 00062 // types have SEF_HAL | SEF_KERNEL set in the type. 00063 // 00064 00065 #define SEF_TYPE_MASK 0x000000FF 00066 #define SEF_EQUATE 0x00000000 00067 #define SEF_EQUATE64 0x00000001 00068 #define SEF_COMMENT 0x00000002 00069 #define SEF_STRING 0x00000003 // Equate is vararg to printf 00070 #define SEF_BITFLD 0x00000004 00071 #define SEF_BITALIAS 0x00000005 00072 #define SEF_STRUCTURE 0x00000006 00073 #define SEF_SETMASK 0x00000010 // Equate is the mask 00074 #define SEF_CLRMASK 0x00000011 // Equate is the mask 00075 #define SEF_END 0x00000012 00076 #define SEF_START 0x00000013 00077 #define SEF_PATH 0x00000014 00078 00079 // 00080 // Note that BITFLD entries have per-entry hal|kernel flags 00081 // 00082 00083 00084 // 00085 // Define architecture specific generation macros. 00086 // 00087 00088 #define SEF_FLAGS 0 00089 #define HAL SEF_HAL 00090 #define KERNEL SEF_KERNEL 00091 00092 #ifndef ULONG_MAX 00093 #define ULONG_MAX 0xFFFFFFFF 00094 #endif 00095 00096 #ifdef _WIN64_ 00097 #define SEF_UINT SEF_EQUATE64 00098 #else 00099 #define SEF_UINT SEF_EQUATE 00100 #endif 00101 00102 // 00103 // genDef(Pc, KPCR, MinorVersion) 00104 // 00105 // -> #define PcMinorVersion 0x0 00106 // 00107 00108 #define genDef(Prefix, Type, Member) \ 00109 { SEF_EQUATE, OFFSET(Type, Member), #Prefix #Member }, 00110 00111 // 00112 // genAlt( PbAlignmentFixupCount, KPRCB, KeAlignmentFixupCount ) 00113 // 00114 // -> #define PbAlignmentFixupCount 0x2f4 00115 // 00116 00117 #define genAlt(Name, Type, Member) \ 00118 { SEF_EQUATE, OFFSET(Type, Member), #Name }, 00119 00120 // 00121 // genCom("This is a comment") 00122 // 00123 // // 00124 // -> // This is a comment 00125 // // 00126 // 00127 00128 #define genCom(Comment) \ 00129 { SEF_COMMENT, 0, Comment }, 00130 00131 // 00132 // genNam(PCR_MINOR_VERSION) 00133 // 00134 // -> #define PCR_MINOR_VERSION 0x1 00135 // 00136 00137 #define genNam(Name) \ 00138 { SEF_EQUATE, (ULONG)(Name), #Name }, 00139 00140 // 00141 // genNamUint(KSEG0_BASE) 00142 // 00143 // -> #define KSE0_BASE 0xffffffff80000000 00144 // 00145 00146 #define genNamUint(Name) \ 00147 { SEF_UINT, (UINT64)(Name), #Name }, 00148 00149 // 00150 // genVal(FirmwareFrameLength, FIRMWARE_FRAME_LENGTH) 00151 // 00152 // -> #define FirmwareFrameLength 0x250 00153 // 00154 // Note: if the value is 64-bit when _WIN64_ is enabled, use genValUint() 00155 // 00156 00157 #define genVal(Name, Value) \ 00158 { SEF_EQUATE, (ULONG)(Value), #Name }, 00159 00160 // 00161 // genValUint(KiPcr, KIPCR) 00162 // 00163 // -> #define KiPcr 0xe0000000ffffe000 00164 // 00165 00166 #define genValUint(Name, Value) \ 00167 { SEF_UINT, (UINT64)(Value), #Name }, 00168 00169 // 00170 // genSpc() 00171 // 00172 // -> 00173 // 00174 00175 #define genSpc() \ 00176 { SEF_STRING, 0, "\n" }, 00177 00178 // 00179 // genStr(" PCR equ ds:[0%lXH]\n", KIP0PCRADDRESS) 00180 // 00181 // -> PCR equ ds:[0FFDFF000H] 00182 // 00183 00184 #define genStr(String, Value) \ 00185 { SEF_STRING, (ULONG_PTR)(Value), String }, 00186 00187 // 00188 // genTxt("ifdef NT_UP\n") 00189 // 00190 // -> ifdef NT_UP 00191 // 00192 00193 #define genTxt(String) \ 00194 { SEF_STRING, 0, String }, 00195 00196 #define DisableInc( x ) \ 00197 { SEF_CLRMASK, x, "" }, 00198 00199 #define EnableInc( x ) \ 00200 { SEF_SETMASK, x, "" }, 00201 00202 #define MARKER_STRING "This is the genxx marker string." 00203 00204 // 00205 // Source file can specify the _NTDRIVE\_NTROOT - relative output path. 00206 // 'f' is the set of enable-flags that should be routed to this file. 00207 // Use '0' if there is only a single output file. 00208 // 00209 // 'f' should also contain one of SEF_H_FORMAT or SEF_INC_FORMAT to 00210 // indicate whether the generated file is in 'header file' or 'include file' 00211 // format. 00212 // 00213 00214 #define setPath( p, f ) \ 00215 { SEF_PATH | f, 0, p }, 00216 00217 // 00218 // START_LIST defines the first element in ElementList. This element contains 00219 // a (possibly truncated) pointer to the ElementList array. This is used to 00220 // determine the fixup RA bias. 00221 // 00222 00223 #define START_LIST \ 00224 { SEF_START, (ULONG_PTR)ElementList, MARKER_STRING }, 00225 00226 #define END_LIST \ 00227 { SEF_END, 0, "" } 00228 00229 // 00230 // Preprocessor assertion. Do something here to make the compiler generate 00231 // an error if x != y. 00232 // 00233 00234 #define ASSERT_SAME( x, y ) 00235 00236 // 00237 // Macro to round Val up to the next Bnd boundary. Bnd must be an integral 00238 // power of two. 00239 // 00240 00241 #define ROUND_UP( Val, Bnd ) \ 00242 (((Val) + ((Bnd) - 1)) & ~((Bnd) - 1)) 00243 00244 #ifndef OFFSET 00245 00246 // 00247 // Define member offset computation macro. 00248 // 00249 00250 #define OFFSET(type, field) ((ULONG_PTR)(&((type *)0)->field)) 00251 00252 #endif 00253 00254 // 00255 // Following are some M4 macros to help with bitfields. 00256 // 00257 00258 #ifndef SKIP_M4 00259 00260 // 00261 // First, define the makezeros(n) macro that will generate a string with 00262 // n pairs of ',0'. This is a recursively defined macro. 00263 // 00264 00265 define(`makezeros',`ifelse(eval($1),0,,`0,makezeros(eval($1-1))')') 00266 00267 // 00268 // Define a concatenation macro. 00269 // 00270 00271 define(`cat',`$1$2') 00272 00273 // 00274 // The following example bitfield declaration uses HARDWARE_PTE as an 00275 // example, which is declared (for alpha) as follows: 00276 // 00277 // typedef struct _HARDWARE_PTE { 00278 // ULONG Valid: 1; 00279 // ULONG Owner: 1; 00280 // ULONG Dirty: 1; 00281 // ULONG reserved: 1; 00282 // ULONG Global: 1; 00283 // ULONG GranularityHint: 2; 00284 // ULONG Write: 1; 00285 // ULONG CopyOnWrite: 1; 00286 // ULONG PageFrameNumber: 23; 00287 // } HARDWARE_PTE, *PHARDWARE_PTE; 00288 // 00289 // 00290 // // First, startBitStruc() is invoked with the structure name. 00291 // 00292 // startBitStruc( HARDWARE_PTE, SEF_HAL | SEF_KERNEL ) 00293 // 00294 // // 00295 // // Now, suppose we wanted to expose seven of the fields in an assembly 00296 // // include file: 00297 // // 00298 // 00299 // genBitField( Valid, PTE_VALID ) 00300 // genBitField( Owner, PTE_OWNER ) 00301 // genBitField( Dirty, PTE_DIRTY ) 00302 // genBitField( reserved ) 00303 // genBitField( Global, PTE_GLOBAL ) 00304 // genBitField( GranularityHint ) 00305 // genBitField( Write, PTE_WRITE ) 00306 // genBitField( CopyOnWrite, PTE_COPYONWRITE ) 00307 // genBitField( PageFrameNumber, PTE_PFN ) 00308 // 00309 // Note that fields that are not used (in this case 'reserved' and 00310 // 'GranularityHint') must still appear in the list. 00311 // 00312 // The above will generate a bunch of static, initialized copies of HARDWARE_PTE 00313 // like so: 00314 // 00315 // HARDWARE_PTE HARDWARE_PTE_Valid = { 00316 // 0xFFFFFFFF }; 00317 // 00318 // HARDWARE_PTE HARDWARE_PTE_Owner = { 00319 // 0, // Valid 00320 // 0xFFFFFFFF }; 00321 // 00322 // HARDWARE_PTE HARDWARE_PTE_Dirty = { 00323 // 0, // Valid 00324 // 0, // Owner 00325 // 0xFFFFFFFF }; 00326 // 00327 // HARDWARE_PTE HARDWARE_PTE_Global = { 00328 // 0, // Valid 00329 // 0, // Owner 00330 // 0, // Dirty 00331 // 0, // reserved 00332 // 0xFFFFFFFF }; 00333 // 00334 // HARDWARE_PTE HARDWARE_PTE_Write = { 00335 // 0, // Valid 00336 // 0, // Owner 00337 // 0, // Dirty 00338 // 0, // reserved (skipped) 00339 // 0, // Global 00340 // 0xFFFFFFFF }; 00341 // 00342 // HARDWARE_PTE HARDWARE_PTE_CopyOnWrite = { 00343 // 0, // Valid 00344 // 0, // Owner 00345 // 0, // Dirty 00346 // 0, // reserved (skipped) 00347 // 0, // Global 00348 // 0, // GranularityHint (skipped) 00349 // 0xFFFFFFFF }; 00350 // 00351 // HARDWARE_PTE HARDWARE_PTE_PageFrameNumber = { 00352 // 0, // Valid 00353 // 0, // Owner 00354 // 0, // Dirty 00355 // 0, // reserved (skipped) 00356 // 0, // Global 00357 // 0, // GranularityHint (skipped) 00358 // 0, // CopyOnWrite 00359 // 0xFFFFFFFF }; 00360 // 00361 // Then, as part of processing the END_LIST macro, these structures are 00362 // generated: 00363 // 00364 // { SEF_BITFLD, &HARDWARE_PTE_Valid, "PTE_VALID" }, 00365 // { SEF_BITFLD, &HARDWARE_PTE_Owner, "PTE_OWNER" }, 00366 // { SEF_BITFLD, &HARDWARE_PTE_Dirty, "PTE_DIRTY" }, 00367 // { SEF_BITFLD, &HARDWARE_PTE_Global, "PTE_GLOBAL" }, 00368 // { SEF_BITFLD, &HARDWARE_PTE_Write, "PTE_WRITE" }, 00369 // { SEF_BITFLD, &HARDWARE_PTE_CopyOnWrite, "PTE_COPYONWRITE" }, 00370 // { SEF_BITFLD, &HARDWARE_PTE_PageFrameNumber, "PTE_PFN" }, 00371 // { SEF_END, 0, "" } 00372 // 00373 // 00374 // ... and that's what gets compiled by the target compiler into the .obj. 00375 // Now, the final stage: genxx.exe is run against this target .obj, and 00376 // would generate the following: 00377 // 00378 // #define PTE_VALID_MASK 0x1 00379 // #define PTE_VALID 0x0 00380 // #define PTE_OWNER_MASK 0x2 00381 // #define PTE_OWNER 0x1 00382 // #define PTE_DIRTY_MASK 0x4 00383 // #define PTE_DIRTY 0x2 00384 // #define PTE_GLOBAL_MASK 0x10 00385 // #define PTE_GLOBAL 0x4 00386 // #define PTE_WRITE_MASK 0x80 00387 // #define PTE_WRITE 0x7 00388 // #define PTE_COPYONWRITE_MASK 0x100 00389 // #define PTE_COPYONWRITE 0x8 00390 // #define PTE_PFN_MASK 0xfffffe00 00391 // #define PTE_PFN 0x9 00392 // 00393 00394 // 00395 // BITFIELD_STRUCS accumulates array element initializations. END_LIST will 00396 // dump these into the definition array. 00397 // 00398 00399 define(`BITFIELD_STRUCS',`') 00400 00401 // 00402 // startBitStruc( <strucname>, <whichfile> ) 00403 // sets BIT_STRUC_NAME = <strucname> and resets the ZERO_FIELDS count to 0. 00404 // It also sets the WHICH_FILE macro. 00405 // 00406 00407 define(`startBitStruc', `define(`BIT_STRUC_NAME',`$1') 00408 define(`BITFIELD_STRUCS', 00409 BITFIELD_STRUCS 00410 ) 00411 define(`ZERO_FIELDS',0) 00412 define(`SEF_TYPE',$2) 00413 ') 00414 00415 // 00416 // genBitField( <fldname>, <generatedname> ) declares a structure of type 00417 // <strucname> and initializes the <fldname> bitfield within it. 00418 // 00419 // Note that I used "cma" instead of an actual comma, this gets changed to 00420 // a comma by END_LIST, below. If I were more proficient with M4 I would know 00421 // how to get around this. 00422 // 00423 00424 define(`genBitField', `define(`VAR_NAME', cat(cat(BIT_STRUC_NAME,`_'),$1)) 00425 `#'define `def_'VAR_NAME 00426 BIT_STRUC_NAME VAR_NAME = {' 00427 `makezeros(ZERO_FIELDS)' 00428 `(ULONG_PTR)-1 };' 00429 `define(`PAD_VAR_NAME', cat(cat(BIT_STRUC_NAME,`p'),$1))' 00430 `ULONG_PTR PAD_VAR_NAME = 0;' 00431 `define(`ZERO_FIELDS',incr(ZERO_FIELDS))' 00432 `define(`FIELD_NAME', $1)' 00433 `define(`FIELD_ASMNAME', $2)' 00434 `define(`BITFIELD_STRUCS', 00435 BITFIELD_STRUCS 00436 `#i'fdef `def_'VAR_NAME 00437 `#i'fndef `dec_'VAR_NAME 00438 `#de'fine `dec_'VAR_NAME 00439 { SEF_BITFLD | SEF_TYPE cma (ULONG_PTR)&VAR_NAME cma "FIELD_ASMNAME" } cma 00440 `#e'ndif 00441 `#e'ndif 00442 )' 00443 ) 00444 00445 define(`genBitAlias', `define(`BITFIELD_STRUCS', 00446 BITFIELD_STRUCS 00447 `#i'fdef `def_'VAR_NAME 00448 `#i'fndef `deca_'VAR_NAME 00449 `#de'fine `deca_'VAR_NAME 00450 { SEF_BITALIAS | SEF_TYPE cma 0 cma "$1" } cma 00451 `#e'ndif 00452 `#e'ndif 00453 )' 00454 ) 00455 00456 // 00457 // END_LIST dumps the array initializers accumulated by BITFIELD_STRUCS, after 00458 // replacing each 'cma' with an actual comma. 00459 // 00460 00461 define(`DUMP_BITFIELDS',`define(`cma',`,') BITFIELD_STRUCS') 00462 00463 #endif // SKIP_M4 00464
1.3.7