efirom.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259
  1. /*
  2. * utils/efirom.c
  3. *
  4. * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of the
  9. * License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. * modifications for gnuefi by bzt (bztsrc@gitlab)
  21. *
  22. * This file is part of the POSIX-UEFI package.
  23. * @brief small tool to convert an .efi file to a .rom file
  24. *
  25. */
  26. #include <stdint.h>
  27. #include <stddef.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <sys/stat.h>
  32. #include <unistd.h>
  33. #include <errno.h>
  34. #include <assert.h>
  35. #include <getopt.h>
  36. #define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
  37. /**
  38. * Print help
  39. *
  40. * @v program_name Program name
  41. */
  42. static void print_help ( const char *program_name ) {
  43. eprintf ( "POSIX-UEFI utils - efirom by Michael Brown GPL\r\n\r\n" );
  44. eprintf ( "%s [--vendor=VVVV] [--device=DDDD] "
  45. "infile outfile\n", program_name );
  46. }
  47. #define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
  48. #define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
  49. #define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
  50. typedef uint64_t UINTN;
  51. typedef UINTN EFI_TPL;
  52. typedef struct _EFI_DEVICE_PATH_PROTOCOL {
  53. uint8_t Type;
  54. uint8_t SubType;
  55. uint8_t Length[2];
  56. } EFI_DEVICE_PATH_PROTOCOL;
  57. typedef struct _EFI_DEVICE_PATH_PROTOCOL _EFI_DEVICE_PATH;
  58. typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH;
  59. #ifndef _EFI_LINK_H
  60. #define _EFI_LINK_H
  61. /*++
  62. Copyright (c) 1998 Intel Corporation
  63. Module Name:
  64. link.h (renamed efilink.h to avoid conflicts)
  65. Abstract:
  66. EFI link list macro's
  67. Revision History
  68. --*/
  69. #ifndef EFI_NT_EMUL
  70. //
  71. // List entry - doubly linked list
  72. //
  73. typedef struct _LIST_ENTRY {
  74. struct _LIST_ENTRY *Flink;
  75. struct _LIST_ENTRY *Blink;
  76. } LIST_ENTRY;
  77. #endif
  78. //
  79. // VOID
  80. // InitializeListHead(
  81. // LIST_ENTRY *ListHead
  82. // );
  83. //
  84. #define InitializeListHead(ListHead) \
  85. (ListHead)->Flink = ListHead; \
  86. (ListHead)->Blink = ListHead;
  87. //
  88. // BOOLEAN
  89. // IsListEmpty(
  90. // PLIST_ENTRY ListHead
  91. // );
  92. //
  93. #define IsListEmpty(ListHead) \
  94. ((ListHead)->Flink == (ListHead))
  95. //
  96. // VOID
  97. // RemoveEntryList(
  98. // PLIST_ENTRY Entry
  99. // );
  100. //
  101. #define _RemoveEntryList(Entry) { \
  102. LIST_ENTRY *_Blink, *_Flink; \
  103. _Flink = (Entry)->Flink; \
  104. _Blink = (Entry)->Blink; \
  105. _Blink->Flink = _Flink; \
  106. _Flink->Blink = _Blink; \
  107. }
  108. #if EFI_DEBUG
  109. #define RemoveEntryList(Entry) \
  110. _RemoveEntryList(Entry); \
  111. (Entry)->Flink = (LIST_ENTRY *) BAD_POINTER; \
  112. (Entry)->Blink = (LIST_ENTRY *) BAD_POINTER;
  113. #else
  114. #define RemoveEntryList(Entry) \
  115. _RemoveEntryList(Entry);
  116. #endif
  117. //
  118. // VOID
  119. // InsertTailList(
  120. // PLIST_ENTRY ListHead,
  121. // PLIST_ENTRY Entry
  122. // );
  123. //
  124. #define InsertTailList(ListHead,Entry) {\
  125. LIST_ENTRY *_ListHead, *_Blink; \
  126. _ListHead = (ListHead); \
  127. _Blink = _ListHead->Blink; \
  128. (Entry)->Flink = _ListHead; \
  129. (Entry)->Blink = _Blink; \
  130. _Blink->Flink = (Entry); \
  131. _ListHead->Blink = (Entry); \
  132. }
  133. //
  134. // VOID
  135. // InsertHeadList(
  136. // PLIST_ENTRY ListHead,
  137. // PLIST_ENTRY Entry
  138. // );
  139. //
  140. #define InsertHeadList(ListHead,Entry) {\
  141. LIST_ENTRY *_ListHead, *_Flink; \
  142. _ListHead = (ListHead); \
  143. _Flink = _ListHead->Flink; \
  144. (Entry)->Flink = _Flink; \
  145. (Entry)->Blink = _ListHead; \
  146. _Flink->Blink = (Entry); \
  147. _ListHead->Flink = (Entry); \
  148. }
  149. // VOID
  150. // SwapListEntries(
  151. // PLIST_ENTRY Entry1,
  152. // PLIST_ENTRY Entry2
  153. // );
  154. //
  155. // Put Entry2 before Entry1
  156. //
  157. #define SwapListEntries(Entry1,Entry2) {\
  158. LIST_ENTRY *Entry1Flink, *Entry1Blink; \
  159. LIST_ENTRY *Entry2Flink, *Entry2Blink; \
  160. Entry2Flink = (Entry2)->Flink; \
  161. Entry2Blink = (Entry2)->Blink; \
  162. Entry1Flink = (Entry1)->Flink; \
  163. Entry1Blink = (Entry1)->Blink; \
  164. Entry2Blink->Flink = Entry2Flink; \
  165. Entry2Flink->Blink = Entry2Blink; \
  166. (Entry2)->Flink = Entry1; \
  167. (Entry2)->Blink = Entry1Blink; \
  168. Entry1Blink->Flink = (Entry2); \
  169. (Entry1)->Blink = (Entry2); \
  170. }
  171. //
  172. // EFI_FIELD_OFFSET - returns the byte offset to a field within a structure
  173. //
  174. #define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field)))
  175. //
  176. // CONTAINING_RECORD - returns a pointer to the structure
  177. // from one of it's elements.
  178. //
  179. #define _CR(Record, TYPE, Field) \
  180. ((TYPE *) ( (CHAR8 *)(Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
  181. #if EFI_DEBUG
  182. #define CR(Record, TYPE, Field, Sig) \
  183. _CR(Record, TYPE, Field)->Signature != Sig ? \
  184. (TYPE *) ASSERT_STRUCT(_CR(Record, TYPE, Field), Record) : \
  185. _CR(Record, TYPE, Field)
  186. #else
  187. #define CR(Record, TYPE, Field, Signature) \
  188. _CR(Record, TYPE, Field)
  189. #endif
  190. //
  191. // A lock structure
  192. //
  193. typedef struct _FLOCK {
  194. EFI_TPL Tpl;
  195. EFI_TPL OwnerTpl;
  196. UINTN Lock;
  197. } FLOCK;
  198. #endif
  199. /*
  200. PE32+ header file
  201. */
  202. #ifndef _PE_H
  203. #define _PE_H
  204. #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
  205. #define IMAGE_OS2_SIGNATURE 0x454E // NE
  206. #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
  207. #define IMAGE_NT_SIGNATURE 0x00004550 // PE00
  208. #define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
  209. typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
  210. uint16_t e_magic; // Magic number
  211. uint16_t e_cblp; // Bytes on last page of file
  212. uint16_t e_cp; // Pages in file
  213. uint16_t e_crlc; // Relocations
  214. uint16_t e_cparhdr; // Size of header in paragraphs
  215. uint16_t e_minalloc; // Minimum extra paragraphs needed
  216. uint16_t e_maxalloc; // Maximum extra paragraphs needed
  217. uint16_t e_ss; // Initial (relative) SS value
  218. uint16_t e_sp; // Initial SP value
  219. uint16_t e_csum; // Checksum
  220. uint16_t e_ip; // Initial IP value
  221. uint16_t e_cs; // Initial (relative) CS value
  222. uint16_t e_lfarlc; // File address of relocation table
  223. uint16_t e_ovno; // Overlay number
  224. uint16_t e_res[4]; // Reserved words
  225. uint16_t e_oemid; // OEM identifier (for e_oeminfo)
  226. uint16_t e_oeminfo; // OEM information; e_oemid specific
  227. uint16_t e_res2[10]; // Reserved words
  228. uint32_t e_lfanew; // File address of new exe header
  229. } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
  230. typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header
  231. uint16_t ne_magic; // Magic number
  232. uint8_t ne_ver; // Version number
  233. uint8_t ne_rev; // Revision number
  234. uint16_t ne_enttab; // Offset of Entry Table
  235. uint16_t ne_cbenttab; // Number of bytes in Entry Table
  236. uint32_t ne_crc; // Checksum of whole file
  237. uint16_t ne_flags; // Flag uint16_t
  238. uint16_t ne_autodata; // Automatic data segment number
  239. uint16_t ne_heap; // Initial heap allocation
  240. uint16_t ne_stack; // Initial stack allocation
  241. uint32_t ne_csip; // Initial CS:IP setting
  242. uint32_t ne_sssp; // Initial SS:SP setting
  243. uint16_t ne_cseg; // Count of file segments
  244. uint16_t ne_cmod; // Entries in Module Reference Table
  245. uint16_t ne_cbnrestab; // Size of non-resident name table
  246. uint16_t ne_segtab; // Offset of Segment Table
  247. uint16_t ne_rsrctab; // Offset of Resource Table
  248. uint16_t ne_restab; // Offset of resident name table
  249. uint16_t ne_modtab; // Offset of Module Reference Table
  250. uint16_t ne_imptab; // Offset of Imported Names Table
  251. uint32_t ne_nrestab; // Offset of Non-resident Names Table
  252. uint16_t ne_cmovent; // Count of movable entries
  253. uint16_t ne_align; // Segment alignment shift count
  254. uint16_t ne_cres; // Count of resource segments
  255. uint8_t ne_exetyp; // Target Operating system
  256. uint8_t ne_flagsothers; // Other .EXE flags
  257. uint16_t ne_pretthunks; // offset to return thunks
  258. uint16_t ne_psegrefbytes; // offset to segment ref. bytes
  259. uint16_t ne_swaparea; // Minimum code swap area size
  260. uint16_t ne_expver; // Expected Windows version number
  261. } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
  262. //
  263. // File header format.
  264. //
  265. typedef struct _IMAGE_FILE_HEADER {
  266. uint16_t Machine;
  267. uint16_t NumberOfSections;
  268. uint32_t TimeDateStamp;
  269. uint32_t PointerToSymbolTable;
  270. uint32_t NumberOfSymbols;
  271. uint16_t SizeOfOptionalHeader;
  272. uint16_t Characteristics;
  273. } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
  274. #define IMAGE_SIZEOF_FILE_HEADER 20
  275. #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
  276. #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
  277. #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
  278. #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
  279. #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
  280. #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
  281. #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
  282. #define IMAGE_FILE_SYSTEM 0x1000 // System File.
  283. #define IMAGE_FILE_DLL 0x2000 // File is a DLL.
  284. #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
  285. #define IMAGE_FILE_MACHINE_UNKNOWN 0
  286. #define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
  287. #define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian
  288. #define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
  289. #define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
  290. #define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x1c2 // Arm/Thumb
  291. #define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
  292. #define IMAGE_FILE_MACHINE_IA64 0x200 // IA-64
  293. #define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
  294. #define IMAGE_FILE_MACHINE_EBC 0xebc // EFI Byte Code
  295. #define IMAGE_FILE_MACHINE_X64 0x8664 // x86_64
  296. //
  297. // Directory format.
  298. //
  299. typedef struct _IMAGE_DATA_DIRECTORY {
  300. uint32_t VirtualAddress;
  301. uint32_t Size;
  302. } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
  303. #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
  304. //
  305. // Optional header format.
  306. //
  307. typedef struct _IMAGE_OPTIONAL_HEADER {
  308. //
  309. // Standard fields.
  310. //
  311. uint16_t Magic;
  312. uint8_t MajorLinkerVersion;
  313. uint8_t MinorLinkerVersion;
  314. uint32_t SizeOfCode;
  315. uint32_t SizeOfInitializedData;
  316. uint32_t SizeOfUninitializedData;
  317. uint32_t AddressOfEntryPoint;
  318. uint32_t BaseOfCode;
  319. uint32_t BaseOfData;
  320. //
  321. // NT additional fields.
  322. //
  323. uint32_t ImageBase;
  324. uint32_t SectionAlignment;
  325. uint32_t FileAlignment;
  326. uint16_t MajorOperatingSystemVersion;
  327. uint16_t MinorOperatingSystemVersion;
  328. uint16_t MajorImageVersion;
  329. uint16_t MinorImageVersion;
  330. uint16_t MajorSubsystemVersion;
  331. uint16_t MinorSubsystemVersion;
  332. uint32_t Reserved1;
  333. uint32_t SizeOfImage;
  334. uint32_t SizeOfHeaders;
  335. uint32_t CheckSum;
  336. uint16_t Subsystem;
  337. uint16_t DllCharacteristics;
  338. uint32_t SizeOfStackReserve;
  339. uint32_t SizeOfStackCommit;
  340. uint32_t SizeOfHeapReserve;
  341. uint32_t SizeOfHeapCommit;
  342. uint32_t LoaderFlags;
  343. uint32_t NumberOfRvaAndSizes;
  344. IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
  345. } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
  346. typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
  347. uint16_t Magic;
  348. uint8_t MajorLinkerVersion;
  349. uint8_t MinorLinkerVersion;
  350. uint32_t SizeOfCode;
  351. uint32_t SizeOfInitializedData;
  352. uint32_t SizeOfUninitializedData;
  353. uint32_t AddressOfEntryPoint;
  354. uint32_t BaseOfCode;
  355. uint32_t BaseOfData;
  356. uint32_t BaseOfBss;
  357. uint32_t GprMask;
  358. uint32_t CprMask[4];
  359. uint32_t GpValue;
  360. } IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
  361. #define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
  362. #define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
  363. #define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
  364. #define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
  365. #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
  366. typedef struct _IMAGE_NT_HEADERS {
  367. uint32_t Signature;
  368. IMAGE_FILE_HEADER FileHeader;
  369. IMAGE_OPTIONAL_HEADER OptionalHeader;
  370. } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
  371. typedef struct _IMAGE_ROM_HEADERS {
  372. IMAGE_FILE_HEADER FileHeader;
  373. IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
  374. } IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
  375. #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
  376. ((uint32_t)ntheader + \
  377. FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
  378. ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \
  379. ))
  380. // Subsystem Values
  381. #define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem.
  382. #define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem.
  383. #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
  384. #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
  385. #define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem.
  386. #define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem.
  387. // Directory Entries
  388. #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
  389. #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
  390. #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
  391. #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
  392. #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
  393. #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
  394. #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
  395. #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
  396. #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
  397. #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
  398. #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
  399. //
  400. // Section header format.
  401. //
  402. #define IMAGE_SIZEOF_SHORT_NAME 8
  403. typedef struct _IMAGE_SECTION_HEADER {
  404. uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
  405. union {
  406. uint32_t PhysicalAddress;
  407. uint32_t VirtualSize;
  408. } Misc;
  409. uint32_t VirtualAddress;
  410. uint32_t SizeOfRawData;
  411. uint32_t PointerToRawData;
  412. uint32_t PointerToRelocations;
  413. uint32_t PointerToLinenumbers;
  414. uint16_t NumberOfRelocations;
  415. uint16_t NumberOfLinenumbers;
  416. uint32_t Characteristics;
  417. } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
  418. #define IMAGE_SIZEOF_SECTION_HEADER 40
  419. #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
  420. #define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
  421. #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
  422. #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
  423. #define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
  424. #define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
  425. #define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
  426. #define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
  427. #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
  428. #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
  429. #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
  430. #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
  431. #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
  432. #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
  433. #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
  434. #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
  435. #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
  436. #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
  437. #define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
  438. #define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
  439. #define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
  440. #define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
  441. //
  442. // Symbol format.
  443. //
  444. #define IMAGE_SIZEOF_SYMBOL 18
  445. //
  446. // Section values.
  447. //
  448. // Symbols have a section number of the section in which they are
  449. // defined. Otherwise, section numbers have the following meanings:
  450. //
  451. #define IMAGE_SYM_UNDEFINED (uint16_t)0 // Symbol is undefined or is common.
  452. #define IMAGE_SYM_ABSOLUTE (uint16_t)-1 // Symbol is an absolute value.
  453. #define IMAGE_SYM_DEBUG (uint16_t)-2 // Symbol is a special debug item.
  454. //
  455. // Type (fundamental) values.
  456. //
  457. #define IMAGE_SYM_TYPE_NULL 0 // no type.
  458. #define IMAGE_SYM_TYPE_VOID 1 //
  459. #define IMAGE_SYM_TYPE_CHAR 2 // type character.
  460. #define IMAGE_SYM_TYPE_SHORT 3 // type short integer.
  461. #define IMAGE_SYM_TYPE_INT 4 //
  462. #define IMAGE_SYM_TYPE_LONG 5 //
  463. #define IMAGE_SYM_TYPE_FLOAT 6 //
  464. #define IMAGE_SYM_TYPE_DOUBLE 7 //
  465. #define IMAGE_SYM_TYPE_STRUCT 8 //
  466. #define IMAGE_SYM_TYPE_UNION 9 //
  467. #define IMAGE_SYM_TYPE_ENUM 10 // enumeration.
  468. #define IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
  469. #define IMAGE_SYM_TYPE_BYTE 12 //
  470. #define IMAGE_SYM_TYPE_WORD 13 //
  471. #define IMAGE_SYM_TYPE_UINT 14 //
  472. #define IMAGE_SYM_TYPE_DWORD 15 //
  473. //
  474. // Type (derived) values.
  475. //
  476. #define IMAGE_SYM_DTYPE_NULL 0 // no derived type.
  477. #define IMAGE_SYM_DTYPE_POINTER 1 // pointer.
  478. #define IMAGE_SYM_DTYPE_FUNCTION 2 // function.
  479. #define IMAGE_SYM_DTYPE_ARRAY 3 // array.
  480. //
  481. // Storage classes.
  482. //
  483. #define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
  484. #define IMAGE_SYM_CLASS_NULL 0
  485. #define IMAGE_SYM_CLASS_AUTOMATIC 1
  486. #define IMAGE_SYM_CLASS_EXTERNAL 2
  487. #define IMAGE_SYM_CLASS_STATIC 3
  488. #define IMAGE_SYM_CLASS_REGISTER 4
  489. #define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
  490. #define IMAGE_SYM_CLASS_LABEL 6
  491. #define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
  492. #define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
  493. #define IMAGE_SYM_CLASS_ARGUMENT 9
  494. #define IMAGE_SYM_CLASS_STRUCT_TAG 10
  495. #define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
  496. #define IMAGE_SYM_CLASS_UNION_TAG 12
  497. #define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
  498. #define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
  499. #define IMAGE_SYM_CLASS_ENUM_TAG 15
  500. #define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
  501. #define IMAGE_SYM_CLASS_REGISTER_PARAM 17
  502. #define IMAGE_SYM_CLASS_BIT_FIELD 18
  503. #define IMAGE_SYM_CLASS_BLOCK 100
  504. #define IMAGE_SYM_CLASS_FUNCTION 101
  505. #define IMAGE_SYM_CLASS_END_OF_STRUCT 102
  506. #define IMAGE_SYM_CLASS_FILE 103
  507. // new
  508. #define IMAGE_SYM_CLASS_SECTION 104
  509. #define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
  510. // type packing constants
  511. #define N_BTMASK 017
  512. #define N_TMASK 060
  513. #define N_TMASK1 0300
  514. #define N_TMASK2 0360
  515. #define N_BTSHFT 4
  516. #define N_TSHIFT 2
  517. // MACROS
  518. //
  519. // Communal selection types.
  520. //
  521. #define IMAGE_COMDAT_SELECT_NODUPLICATES 1
  522. #define IMAGE_COMDAT_SELECT_ANY 2
  523. #define IMAGE_COMDAT_SELECT_SAME_SIZE 3
  524. #define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
  525. #define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
  526. #define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
  527. #define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
  528. #define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
  529. //
  530. // Relocation format.
  531. //
  532. typedef struct _IMAGE_RELOCATION {
  533. uint32_t VirtualAddress;
  534. uint32_t SymbolTableIndex;
  535. uint16_t Type;
  536. } IMAGE_RELOCATION;
  537. #define IMAGE_SIZEOF_RELOCATION 10
  538. //
  539. // I386 relocation types.
  540. //
  541. #define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
  542. #define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
  543. #define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
  544. #define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
  545. #define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
  546. #define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
  547. #define IMAGE_REL_I386_SECTION 012
  548. #define IMAGE_REL_I386_SECREL 013
  549. #define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
  550. //
  551. // MIPS relocation types.
  552. //
  553. #define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
  554. #define IMAGE_REL_MIPS_REFHALF 01
  555. #define IMAGE_REL_MIPS_REFWORD 02
  556. #define IMAGE_REL_MIPS_JMPADDR 03
  557. #define IMAGE_REL_MIPS_REFHI 04
  558. #define IMAGE_REL_MIPS_REFLO 05
  559. #define IMAGE_REL_MIPS_GPREL 06
  560. #define IMAGE_REL_MIPS_LITERAL 07
  561. #define IMAGE_REL_MIPS_SECTION 012
  562. #define IMAGE_REL_MIPS_SECREL 013
  563. #define IMAGE_REL_MIPS_REFWORDNB 042
  564. #define IMAGE_REL_MIPS_PAIR 045
  565. //
  566. // Alpha Relocation types.
  567. //
  568. #define IMAGE_REL_ALPHA_ABSOLUTE 0x0
  569. #define IMAGE_REL_ALPHA_REFLONG 0x1
  570. #define IMAGE_REL_ALPHA_REFQUAD 0x2
  571. #define IMAGE_REL_ALPHA_GPREL32 0x3
  572. #define IMAGE_REL_ALPHA_LITERAL 0x4
  573. #define IMAGE_REL_ALPHA_LITUSE 0x5
  574. #define IMAGE_REL_ALPHA_GPDISP 0x6
  575. #define IMAGE_REL_ALPHA_BRADDR 0x7
  576. #define IMAGE_REL_ALPHA_HINT 0x8
  577. #define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9
  578. #define IMAGE_REL_ALPHA_REFHI 0xA
  579. #define IMAGE_REL_ALPHA_REFLO 0xB
  580. #define IMAGE_REL_ALPHA_PAIR 0xC
  581. #define IMAGE_REL_ALPHA_MATCH 0xD
  582. #define IMAGE_REL_ALPHA_SECTION 0xE
  583. #define IMAGE_REL_ALPHA_SECREL 0xF
  584. #define IMAGE_REL_ALPHA_REFLONGNB 0x10
  585. //
  586. // IBM PowerPC relocation types.
  587. //
  588. #define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP
  589. #define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address
  590. #define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address
  591. #define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute)
  592. #define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address
  593. #define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword)
  594. #define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative)
  595. #define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative)
  596. #define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base
  597. #define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword)
  598. #define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base
  599. #define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr)
  600. #define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number
  601. #define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code
  602. #define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction
  603. #define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type
  604. // Flag bits in IMAGE_RELOCATION.TYPE
  605. #define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it
  606. #define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken
  607. #define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken
  608. #define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc)
  609. //
  610. // Based relocation format.
  611. //
  612. typedef struct _IMAGE_BASE_RELOCATION {
  613. uint32_t VirtualAddress;
  614. uint32_t SizeOfBlock;
  615. // uint16_t TypeOffset[1];
  616. } IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
  617. #define IMAGE_SIZEOF_BASE_RELOCATION 8
  618. //
  619. // Based relocation types.
  620. //
  621. #define IMAGE_REL_BASED_ABSOLUTE 0
  622. #define IMAGE_REL_BASED_HIGH 1
  623. #define IMAGE_REL_BASED_LOW 2
  624. #define IMAGE_REL_BASED_HIGHLOW 3
  625. #define IMAGE_REL_BASED_HIGHADJ 4
  626. #define IMAGE_REL_BASED_MIPS_JMPADDR 5
  627. #define IMAGE_REL_BASED_IA64_IMM64 9
  628. #define IMAGE_REL_BASED_DIR64 10
  629. //
  630. // Line number format.
  631. //
  632. typedef struct _IMAGE_LINENUMBER {
  633. union {
  634. uint32_t SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
  635. uint32_t VirtualAddress; // Virtual address of line number.
  636. } Type;
  637. uint16_t Linenumber; // Line number.
  638. } IMAGE_LINENUMBER;
  639. #define IMAGE_SIZEOF_LINENUMBER 6
  640. //
  641. // Archive format.
  642. //
  643. #define IMAGE_ARCHIVE_START_SIZE 8
  644. #define IMAGE_ARCHIVE_START "!<arch>\n"
  645. #define IMAGE_ARCHIVE_END "`\n"
  646. #define IMAGE_ARCHIVE_PAD "\n"
  647. #define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
  648. #define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
  649. typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
  650. uint8_t Name[16]; // File member name - `/' terminated.
  651. uint8_t Date[12]; // File member date - decimal.
  652. uint8_t UserID[6]; // File member user id - decimal.
  653. uint8_t GroupID[6]; // File member group id - decimal.
  654. uint8_t Mode[8]; // File member mode - octal.
  655. uint8_t Size[10]; // File member size - decimal.
  656. uint8_t EndHeader[2]; // String to end header.
  657. } IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
  658. #define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
  659. //
  660. // DLL support.
  661. //
  662. //
  663. // Export Format
  664. //
  665. typedef struct _IMAGE_EXPORT_DIRECTORY {
  666. uint32_t Characteristics;
  667. uint32_t TimeDateStamp;
  668. uint16_t MajorVersion;
  669. uint16_t MinorVersion;
  670. uint32_t Name;
  671. uint32_t Base;
  672. uint32_t NumberOfFunctions;
  673. uint32_t NumberOfNames;
  674. uint32_t *AddressOfFunctions;
  675. uint32_t *AddressOfNames;
  676. uint32_t *AddressOfNameOrdinals;
  677. } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
  678. //
  679. // Import Format
  680. //
  681. typedef struct _IMAGE_IMPORT_BY_NAME {
  682. uint16_t Hint;
  683. uint8_t Name[1];
  684. } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
  685. typedef struct _IMAGE_THUNK_DATA {
  686. union {
  687. uint32_t Function;
  688. uint32_t Ordinal;
  689. PIMAGE_IMPORT_BY_NAME AddressOfData;
  690. } u1;
  691. } IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
  692. #define IMAGE_ORDINAL_FLAG 0x80000000
  693. #define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)
  694. #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
  695. typedef struct _IMAGE_IMPORT_DESCRIPTOR {
  696. uint32_t Characteristics;
  697. uint32_t TimeDateStamp;
  698. uint32_t ForwarderChain;
  699. uint32_t Name;
  700. PIMAGE_THUNK_DATA FirstThunk;
  701. } IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
  702. #endif
  703. #ifndef _PCI22_H
  704. #define _PCI22_H
  705. /*++
  706. Copyright (c) 1999 Intel Corporation
  707. Module Name:
  708. pci22.h
  709. Abstract:
  710. Support for PCI 2.2 standard.
  711. Revision History
  712. --*/
  713. #ifdef SOFT_SDV
  714. #define PCI_MAX_BUS 1
  715. #else
  716. #define PCI_MAX_BUS 255
  717. #endif
  718. #define PCI_MAX_DEVICE 31
  719. #define PCI_MAX_FUNC 7
  720. //
  721. // Command
  722. //
  723. #define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20
  724. #pragma pack(1)
  725. typedef struct {
  726. uint16_t VendorId;
  727. uint16_t DeviceId;
  728. uint16_t Command;
  729. uint16_t Status;
  730. uint8_t RevisionID;
  731. uint8_t ClassCode[3];
  732. uint8_t CacheLineSize;
  733. uint8_t LaytencyTimer;
  734. uint8_t HeaderType;
  735. uint8_t BIST;
  736. } PCI_DEVICE_INDEPENDENT_REGION;
  737. typedef struct {
  738. uint32_t Bar[6];
  739. uint32_t CISPtr;
  740. uint16_t SubsystemVendorID;
  741. uint16_t SubsystemID;
  742. uint32_t ExpansionRomBar;
  743. uint32_t Reserved[2];
  744. uint8_t InterruptLine;
  745. uint8_t InterruptPin;
  746. uint8_t MinGnt;
  747. uint8_t MaxLat;
  748. } PCI_DEVICE_HEADER_TYPE_REGION;
  749. typedef struct {
  750. PCI_DEVICE_INDEPENDENT_REGION Hdr;
  751. PCI_DEVICE_HEADER_TYPE_REGION Device;
  752. } PCI_TYPE00;
  753. typedef struct {
  754. uint32_t Bar[2];
  755. uint8_t PrimaryBus;
  756. uint8_t SecondaryBus;
  757. uint8_t SubordinateBus;
  758. uint8_t SecondaryLatencyTimer;
  759. uint8_t IoBase;
  760. uint8_t IoLimit;
  761. uint16_t SecondaryStatus;
  762. uint16_t MemoryBase;
  763. uint16_t MemoryLimit;
  764. uint16_t PrefetchableMemoryBase;
  765. uint16_t PrefetchableMemoryLimit;
  766. uint32_t PrefetchableBaseUpper32;
  767. uint32_t PrefetchableLimitUpper32;
  768. uint16_t IoBaseUpper16;
  769. uint16_t IoLimitUpper16;
  770. uint32_t Reserved;
  771. uint32_t ExpansionRomBAR;
  772. uint8_t InterruptLine;
  773. uint8_t InterruptPin;
  774. uint16_t BridgeControl;
  775. } PCI_BRIDGE_CONTROL_REGISTER;
  776. #define PCI_CLASS_DISPLAY_CTRL 0x03
  777. #define PCI_CLASS_VGA 0x00
  778. #define PCI_CLASS_BRIDGE 0x06
  779. #define PCI_CLASS_ISA 0x01
  780. #define PCI_CLASS_ISA_POSITIVE_DECODE 0x80
  781. #define PCI_CLASS_NETWORK 0x02
  782. #define PCI_CLASS_ETHERNET 0x00
  783. #define HEADER_TYPE_DEVICE 0x00
  784. #define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01
  785. #define HEADER_TYPE_MULTI_FUNCTION 0x80
  786. #define HEADER_LAYOUT_CODE 0x7f
  787. #define IS_PCI_BRIDGE(_p) ((((_p)->Hdr.HeaderType) & HEADER_LAYOUT_CODE) == HEADER_TYPE_PCI_TO_PCI_BRIDGE)
  788. #define IS_PCI_MULTI_FUNC(_p) (((_p)->Hdr.HeaderType) & HEADER_TYPE_MULTI_FUNCTION)
  789. typedef struct {
  790. PCI_DEVICE_INDEPENDENT_REGION Hdr;
  791. PCI_BRIDGE_CONTROL_REGISTER Bridge;
  792. } PCI_TYPE01;
  793. typedef struct {
  794. uint8_t Register;
  795. uint8_t Function;
  796. uint8_t Device;
  797. uint8_t Bus;
  798. uint8_t Reserved[4];
  799. } DEFIO_PCI_ADDR;
  800. typedef struct {
  801. uint32_t Reg : 8;
  802. uint32_t Func : 3;
  803. uint32_t Dev : 5;
  804. uint32_t Bus : 8;
  805. uint32_t Reserved: 7;
  806. uint32_t Enable : 1;
  807. } PCI_CONFIG_ACCESS_CF8;
  808. #pragma pack()
  809. #define EFI_ROOT_BRIDGE_LIST 'eprb'
  810. typedef struct {
  811. UINTN Signature;
  812. uint16_t BridgeNumber;
  813. uint16_t PrimaryBus;
  814. uint16_t SubordinateBus;
  815. EFI_DEVICE_PATH *DevicePath;
  816. LIST_ENTRY Link;
  817. } PCI_ROOT_BRIDGE_ENTRY;
  818. #define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55
  819. #define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1
  820. #define PCI_DATA_STRUCTURE_SIGNATURE EFI_SIGNATURE_32('P','C','I','R')
  821. #pragma pack(1)
  822. typedef struct {
  823. uint16_t Signature; // 0xaa55
  824. uint8_t Reserved[0x16];
  825. uint16_t PcirOffset;
  826. } PCI_EXPANSION_ROM_HEADER;
  827. typedef struct {
  828. uint16_t Signature; // 0xaa55
  829. uint16_t InitializationSize;
  830. uint16_t EfiSignature; // 0x0EF1
  831. uint16_t EfiSubsystem;
  832. uint16_t EfiMachineType;
  833. uint8_t Reserved[0x0A];
  834. uint16_t EfiImageHeaderOffset;
  835. uint16_t PcirOffset;
  836. } EFI_PCI_EXPANSION_ROM_HEADER;
  837. typedef struct {
  838. uint32_t Signature; // "PCIR"
  839. uint16_t VendorId;
  840. uint16_t DeviceId;
  841. uint16_t Reserved0;
  842. uint16_t Length;
  843. uint8_t Revision;
  844. uint8_t ClassCode[3];
  845. uint16_t ImageLength;
  846. uint16_t CodeRevision;
  847. uint8_t CodeType;
  848. uint8_t Indicator;
  849. uint16_t Reserved1;
  850. } PCI_DATA_STRUCTURE;
  851. #pragma pack()
  852. #endif
  853. /** Command-line options */
  854. struct options {
  855. uint16_t vendor;
  856. uint16_t device;
  857. };
  858. /**
  859. * Allocate memory
  860. *
  861. * @v len Length of memory to allocate
  862. * @ret ptr Pointer to allocated memory
  863. */
  864. static void * xmalloc ( size_t len ) {
  865. void *ptr;
  866. ptr = malloc ( len );
  867. if ( ! ptr ) {
  868. eprintf ( "Could not allocate %zd bytes\n", len );
  869. exit ( 1 );
  870. }
  871. return ptr;
  872. }
  873. /**
  874. * Get file size
  875. *
  876. * @v file File
  877. * @v len File size
  878. */
  879. /*
  880. static size_t file_size ( FILE *file ) {
  881. ssize_t len;
  882. return len;
  883. }
  884. */
  885. /**
  886. * Read information from PE headers
  887. *
  888. * @v pe PE file
  889. * @ret machine Machine type
  890. * @ret subsystem EFI subsystem
  891. */
  892. static void read_pe_info ( void *pe, uint16_t *machine,
  893. uint16_t *subsystem ) {
  894. IMAGE_DOS_HEADER *dos;
  895. union {
  896. IMAGE_NT_HEADERS nt64;
  897. } *nt;
  898. /* Locate NT header */
  899. dos = pe;
  900. nt = ( pe + dos->e_lfanew );
  901. /* issue 4: TianoCore demands subsystem 10, so we must use EFI_APPLICATION
  902. * in the PE header. Therefore we force EFI_ROM subsystem in this code here. */
  903. if(nt->nt64.OptionalHeader.Subsystem == 10)
  904. nt->nt64.OptionalHeader.Subsystem = 13;
  905. /* Parse out PE information */
  906. *machine = nt->nt64.FileHeader.Machine;
  907. *subsystem = nt->nt64.OptionalHeader.Subsystem;
  908. }
  909. /**
  910. * Convert EFI image to ROM image
  911. *
  912. * @v pe EFI file
  913. * @v rom ROM file
  914. */
  915. static void make_efi_rom ( FILE *pe, FILE *rom, struct options *opts ) {
  916. struct {
  917. EFI_PCI_EXPANSION_ROM_HEADER rom;
  918. PCI_DATA_STRUCTURE pci __attribute__ (( aligned ( 4 ) ));
  919. uint8_t checksum;
  920. } *headers;
  921. struct stat pe_stat;
  922. size_t pe_size;
  923. size_t rom_size;
  924. void *buf;
  925. void *payload;
  926. unsigned int i;
  927. uint8_t checksum;
  928. /* Determine PE file size */
  929. if ( fstat ( fileno ( pe ), &pe_stat ) != 0 ) {
  930. eprintf ( "Could not stat PE file: %s\n",
  931. strerror ( errno ) );
  932. exit ( 1 );
  933. }
  934. pe_size = pe_stat.st_size;
  935. /* Determine ROM file size */
  936. rom_size = ( ( pe_size + sizeof ( *headers ) + 511 ) & ~511 );
  937. /* Allocate ROM buffer and read in PE file */
  938. buf = xmalloc ( rom_size );
  939. memset ( buf, 0, rom_size );
  940. headers = buf;
  941. payload = ( buf + sizeof ( *headers ) );
  942. if ( fread ( payload, pe_size, 1, pe ) != 1 ) {
  943. eprintf ( "Could not read PE file: %s\n",
  944. strerror ( errno ) );
  945. exit ( 1 );
  946. }
  947. /* Construct ROM header */
  948. headers->rom.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE;
  949. headers->rom.InitializationSize = ( rom_size / 512 );
  950. headers->rom.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE;
  951. read_pe_info ( payload, &headers->rom.EfiMachineType,
  952. &headers->rom.EfiSubsystem );
  953. headers->rom.EfiImageHeaderOffset = sizeof ( *headers );
  954. headers->rom.PcirOffset =
  955. offsetof ( typeof ( *headers ), pci );
  956. headers->pci.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
  957. headers->pci.VendorId = opts->vendor ? opts->vendor : 0x8086;
  958. headers->pci.DeviceId = opts->device ? opts->device : 0x100E;
  959. headers->pci.Length = sizeof ( headers->pci );
  960. headers->pci.ClassCode[0] = PCI_CLASS_NETWORK;
  961. headers->pci.ImageLength = ( rom_size / 512 );
  962. headers->pci.CodeType = 0x03; /* No constant in EFI headers? */
  963. headers->pci.Indicator = 0x80; /* No constant in EFI headers? */
  964. /* Fix image checksum */
  965. for ( i = 0, checksum = 0 ; i < rom_size ; i++ )
  966. checksum += *( ( uint8_t * ) buf + i );
  967. headers->checksum -= checksum;
  968. /* Write out ROM */
  969. if ( fwrite ( buf, rom_size, 1, rom ) != 1 ) {
  970. eprintf ( "Could not write ROM file: %s\n",
  971. strerror ( errno ) );
  972. exit ( 1 );
  973. }
  974. }
  975. /**
  976. * Parse command-line options
  977. *
  978. * @v argc Argument count
  979. * @v argv Argument list
  980. * @v opts Options structure to populate
  981. */
  982. static int parse_options ( const int argc, char **argv,
  983. struct options *opts ) {
  984. char *end;
  985. int c;
  986. while (1) {
  987. int option_index = 0;
  988. static struct option long_options[] = {
  989. { "vendor", required_argument, NULL, 'v' },
  990. { "device", required_argument, NULL, 'd' },
  991. { "help", 0, NULL, 'h' },
  992. { 0, 0, 0, 0 }
  993. };
  994. if ( ( c = getopt_long ( argc, argv, "v:d:h",
  995. long_options,
  996. &option_index ) ) == -1 ) {
  997. break;
  998. }
  999. switch ( c ) {
  1000. case 'v':
  1001. opts->vendor = strtoul ( optarg, &end, 16 );
  1002. if ( *end ) {
  1003. eprintf ( "Invalid vendor \"%s\"\n", optarg );
  1004. exit ( 2 );
  1005. }
  1006. break;
  1007. case 'd':
  1008. opts->device = strtoul ( optarg, &end, 16 );
  1009. if ( *end ) {
  1010. eprintf ( "Invalid device \"%s\"\n", optarg );
  1011. exit ( 2 );
  1012. }
  1013. break;
  1014. case 'h':
  1015. print_help ( argv[0] );
  1016. exit ( 0 );
  1017. case '?':
  1018. default:
  1019. exit ( 2 );
  1020. }
  1021. }
  1022. return optind;
  1023. }
  1024. int main ( int argc, char **argv ) {
  1025. struct options opts = {
  1026. };
  1027. unsigned int infile_index;
  1028. const char *infile_name;
  1029. const char *outfile_name;
  1030. FILE *infile;
  1031. FILE *outfile;
  1032. /* Parse command-line arguments */
  1033. infile_index = parse_options ( argc, argv, &opts );
  1034. if ( argc != ( infile_index + 2 ) ) {
  1035. print_help ( argv[0] );
  1036. exit ( 2 );
  1037. }
  1038. infile_name = argv[infile_index];
  1039. outfile_name = argv[infile_index + 1];
  1040. /* Open input and output files */
  1041. infile = fopen ( infile_name, "r" );
  1042. if ( ! infile ) {
  1043. eprintf ( "Could not open %s for reading: %s\n",
  1044. infile_name, strerror ( errno ) );
  1045. exit ( 1 );
  1046. }
  1047. outfile = fopen ( outfile_name, "w" );
  1048. if ( ! outfile ) {
  1049. eprintf ( "Could not open %s for writing: %s\n",
  1050. outfile_name, strerror ( errno ) );
  1051. exit ( 1 );
  1052. }
  1053. /* Convert file */
  1054. make_efi_rom ( infile, outfile, &opts );
  1055. fclose ( outfile );
  1056. fclose ( infile );
  1057. return 0;
  1058. }