[efi] Add efirom utility and .efirom image format
authorMichael Brown <mcb30@etherboot.org>
Thu, 8 Jan 2009 02:19:18 +0000 (02:19 +0000)
committerMichael Brown <mcb30@etherboot.org>
Thu, 8 Jan 2009 02:19:18 +0000 (02:19 +0000)
src/Makefile
src/Makefile.housekeeping
src/arch/x86/Makefile.efi
src/include/gpxe/efi/IndustryStandard/Pci22.h [new file with mode: 0644]
src/util/.gitignore
src/util/efirom.c [new file with mode: 0644]
src/util/elf2efi.c

index 015fcc4..eed91f0 100644 (file)
@@ -39,6 +39,7 @@ NRV2B         := ./util/nrv2b
 ZBIN           := ./util/zbin
 ELF2EFI32      := ./util/elf2efi32
 ELF2EFI64      := ./util/elf2efi64
+EFIROM         := ./util/efirom
 DOXYGEN                := doxygen
 
 ###############################################################################
index 2a1a1a2..757707b 100644 (file)
@@ -707,14 +707,21 @@ CLEANUP += $(ZBIN)
 #
 $(ELF2EFI32) : util/elf2efi.c $(MAKEDEPS)
        $(QM)$(ECHO) "  [HOSTCC] $@"
-       $(Q)$(HOST_CC) -DMDE_CPU_IA32 -O2 -o $@ $< -lbfd -liberty
+       $(Q)$(HOST_CC) -DMDE_CPU_IA32 -idirafter include -O2 \
+               -o $@ $< -lbfd -liberty
 CLEANUP += $(ELF2EFI32)
 
 $(ELF2EFI64) : util/elf2efi.c $(MAKEDEPS)
        $(QM)$(ECHO) "  [HOSTCC] $@"
-       $(Q)$(HOST_CC) -DMDE_CPU_X64 -O2 -o $@ $< -lbfd -liberty
+       $(Q)$(HOST_CC) -DMDE_CPU_X64 -idirafter include -O2 \
+               -o $@ $< -lbfd -liberty
 CLEANUP += $(ELF2EFI64)
 
+$(EFIROM) : util/efirom.c $(MAKEDEPS)
+       $(QM)$(ECHO) "  [HOSTCC] $@"
+       $(Q)$(HOST_CC) -idirafter include -O2 -o $@ $<
+CLEANUP += $(EFIROM)
+
 ###############################################################################
 #
 # Auto-incrementing build serial number.  Append "bs" to your list of
index 92cd020..bef8d59 100644 (file)
@@ -22,3 +22,7 @@ $(BIN)/%.efi : $(BIN)/%.efi.tmp $(ELF2EFI)
 $(BIN)/%.efidrv : $(BIN)/%.efidrv.tmp $(ELF2EFI)
        $(QM)$(ECHO) "  [FINISH] $@"
        $(Q)$(ELF2EFI) --subsystem=11 $< $@
+
+$(BIN)/%.efirom : $(BIN)/%.efidrv $(EFIROM)
+       $(QM)$(ECHO) "  [FINISH] $@"
+       $(Q)$(EFIROM) -v $(TGT_PCI_VENDOR) -d $(TGT_PCI_DEVICE) $< $@
diff --git a/src/include/gpxe/efi/IndustryStandard/Pci22.h b/src/include/gpxe/efi/IndustryStandard/Pci22.h
new file mode 100644 (file)
index 0000000..5b96a56
--- /dev/null
@@ -0,0 +1,601 @@
+/** @file
+  Support for PCI 2.2 standard.
+
+  This file includes the definitions in the following specifications,
+    PCI Local Bus Specification, 2.0
+    PCI-to-PCI Bridge Architecture Specification,
+    PC Card Standard, 8.0
+
+  Copyright (c) 2006 - 2008, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI22_H_
+#define _PCI22_H_
+
+#define PCI_MAX_SEGMENT 0
+#define PCI_MAX_BUS     255
+#define PCI_MAX_DEVICE  31
+#define PCI_MAX_FUNC    7
+
+
+#pragma pack(1)
+typedef struct {
+  UINT16  VendorId;
+  UINT16  DeviceId;
+  UINT16  Command;
+  UINT16  Status;
+  UINT8   RevisionID;
+  UINT8   ClassCode[3];
+  UINT8   CacheLineSize;
+  UINT8   LatencyTimer;
+  UINT8   HeaderType;
+  UINT8   BIST;
+} PCI_DEVICE_INDEPENDENT_REGION;
+
+typedef struct {
+  UINT32  Bar[6];
+  UINT32  CISPtr;
+  UINT16  SubsystemVendorID;
+  UINT16  SubsystemID;
+  UINT32  ExpansionRomBar;
+  UINT8   CapabilityPtr;
+  UINT8   Reserved1[3];
+  UINT32  Reserved2;
+  UINT8   InterruptLine;
+  UINT8   InterruptPin;
+  UINT8   MinGnt;
+  UINT8   MaxLat;
+} PCI_DEVICE_HEADER_TYPE_REGION;
+
+typedef struct {
+  PCI_DEVICE_INDEPENDENT_REGION Hdr;
+  PCI_DEVICE_HEADER_TYPE_REGION Device;
+} PCI_TYPE00;
+
+///
+/// defined in PCI-to-PCI Bridge Architecture Specification
+///
+typedef struct {
+  UINT32  Bar[2];
+  UINT8   PrimaryBus;
+  UINT8   SecondaryBus;
+  UINT8   SubordinateBus;
+  UINT8   SecondaryLatencyTimer;
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  SecondaryStatus;
+  UINT16  MemoryBase;
+  UINT16  MemoryLimit;
+  UINT16  PrefetchableMemoryBase;
+  UINT16  PrefetchableMemoryLimit;
+  UINT32  PrefetchableBaseUpper32;
+  UINT32  PrefetchableLimitUpper32;
+  UINT16  IoBaseUpper16;
+  UINT16  IoLimitUpper16;
+  UINT8   CapabilityPtr;
+  UINT8   Reserved[3];
+  UINT32  ExpansionRomBAR;
+  UINT8   InterruptLine;
+  UINT8   InterruptPin;
+  UINT16  BridgeControl;
+} PCI_BRIDGE_CONTROL_REGISTER;
+
+typedef struct {
+  PCI_DEVICE_INDEPENDENT_REGION Hdr;
+  PCI_BRIDGE_CONTROL_REGISTER   Bridge;
+} PCI_TYPE01;
+
+typedef union {
+  PCI_TYPE00  Device;
+  PCI_TYPE01  Bridge;
+} PCI_TYPE_GENERIC;
+
+///
+/// CardBus Conroller Configuration Space, defined in PC Card Standard. 8.0
+///
+typedef struct {
+  UINT32  CardBusSocketReg;     ///< Cardus Socket/ExCA Base
+  UINT8   Cap_Ptr;
+  UINT8   Reserved;
+  UINT16  SecondaryStatus;      ///< Secondary Status
+  UINT8   PciBusNumber;         ///< PCI Bus Number
+  UINT8   CardBusBusNumber;     ///< CardBus Bus Number
+  UINT8   SubordinateBusNumber; ///< Subordinate Bus Number
+  UINT8   CardBusLatencyTimer;  ///< CardBus Latency Timer
+  UINT32  MemoryBase0;          ///< Memory Base Register 0
+  UINT32  MemoryLimit0;         ///< Memory Limit Register 0
+  UINT32  MemoryBase1;
+  UINT32  MemoryLimit1;
+  UINT32  IoBase0;
+  UINT32  IoLimit0;             ///< I/O Base Register 0
+  UINT32  IoBase1;              ///< I/O Limit Register 0
+  UINT32  IoLimit1;
+  UINT8   InterruptLine;        ///< Interrupt Line
+  UINT8   InterruptPin;         ///< Interrupt Pin
+  UINT16  BridgeControl;        ///< Bridge Control
+} PCI_CARDBUS_CONTROL_REGISTER;
+
+///
+/// Definitions of PCI class bytes and manipulation macros.
+///
+#define PCI_CLASS_OLD                 0x00
+#define   PCI_CLASS_OLD_OTHER           0x00
+#define   PCI_CLASS_OLD_VGA             0x01
+
+#define PCI_CLASS_MASS_STORAGE        0x01
+#define   PCI_CLASS_MASS_STORAGE_SCSI   0x00
+#define   PCI_CLASS_MASS_STORAGE_IDE    0x01
+#define   PCI_CLASS_MASS_STORAGE_FLOPPY 0x02
+#define   PCI_CLASS_MASS_STORAGE_IPI    0x03
+#define   PCI_CLASS_MASS_STORAGE_RAID   0x04
+#define   PCI_CLASS_MASS_STORAGE_OTHER  0x80
+
+#define PCI_CLASS_NETWORK             0x02
+#define   PCI_CLASS_NETWORK_ETHERNET    0x00
+#define   PCI_CLASS_NETWORK_TOKENRING   0x01
+#define   PCI_CLASS_NETWORK_FDDI        0x02
+#define   PCI_CLASS_NETWORK_ATM         0x03
+#define   PCI_CLASS_NETWORK_ISDN        0x04
+#define   PCI_CLASS_NETWORK_OTHER       0x80
+
+#define PCI_CLASS_DISPLAY             0x03
+#define   PCI_CLASS_DISPLAY_VGA         0x00
+#define     PCI_IF_VGA_VGA                0x00
+#define     PCI_IF_VGA_8514               0x01
+#define   PCI_CLASS_DISPLAY_XGA         0x01
+#define   PCI_CLASS_DISPLAY_3D          0x02
+#define   PCI_CLASS_DISPLAY_OTHER       0x80
+#define   PCI_CLASS_DISPLAY_GFX         0x80
+
+#define PCI_CLASS_MEDIA               0x04
+#define   PCI_CLASS_MEDIA_VIDEO         0x00
+#define   PCI_CLASS_MEDIA_AUDIO         0x01
+#define   PCI_CLASS_MEDIA_TELEPHONE     0x02
+#define   PCI_CLASS_MEDIA_OTHER         0x80
+
+#define PCI_CLASS_MEMORY_CONTROLLER   0x05
+#define   PCI_CLASS_MEMORY_RAM          0x00
+#define   PCI_CLASS_MEMORY_FLASH        0x01
+#define   PCI_CLASS_MEMORY_OTHER        0x80
+
+#define PCI_CLASS_BRIDGE              0x06
+#define   PCI_CLASS_BRIDGE_HOST         0x00
+#define   PCI_CLASS_BRIDGE_ISA          0x01
+#define   PCI_CLASS_BRIDGE_EISA         0x02
+#define   PCI_CLASS_BRIDGE_MCA          0x03
+#define   PCI_CLASS_BRIDGE_P2P          0x04
+#define     PCI_IF_BRIDGE_P2P             0x00
+#define     PCI_IF_BRIDGE_P2P_SUBTRACTIVE 0x01
+#define   PCI_CLASS_BRIDGE_PCMCIA       0x05
+#define   PCI_CLASS_BRIDGE_NUBUS        0x06
+#define   PCI_CLASS_BRIDGE_CARDBUS      0x07
+#define   PCI_CLASS_BRIDGE_RACEWAY      0x08
+#define   PCI_CLASS_BRIDGE_OTHER        0x80
+#define   PCI_CLASS_BRIDGE_ISA_PDECODE  0x80
+
+#define PCI_CLASS_SCC                 0x07  ///< Simple communications controllers
+#define   PCI_SUBCLASS_SERIAL           0x00
+#define     PCI_IF_GENERIC_XT             0x00
+#define     PCI_IF_16450                  0x01
+#define     PCI_IF_16550                  0x02
+#define     PCI_IF_16650                  0x03
+#define     PCI_IF_16750                  0x04
+#define     PCI_IF_16850                  0x05
+#define     PCI_IF_16950                  0x06
+#define   PCI_SUBCLASS_PARALLEL         0x01
+#define     PCI_IF_PARALLEL_PORT          0x00
+#define     PCI_IF_BI_DIR_PARALLEL_PORT   0x01
+#define     PCI_IF_ECP_PARALLEL_PORT      0x02
+#define     PCI_IF_1284_CONTROLLER        0x03
+#define     PCI_IF_1284_DEVICE            0xFE
+#define   PCI_SUBCLASS_MULTIPORT_SERIAL 0x02
+#define   PCI_SUBCLASS_MODEM            0x03
+#define     PCI_IF_GENERIC_MODEM          0x00
+#define     PCI_IF_16450_MODEM            0x01
+#define     PCI_IF_16550_MODEM            0x02
+#define     PCI_IF_16650_MODEM            0x03
+#define     PCI_IF_16750_MODEM            0x04
+#define   PCI_SUBCLASS_SCC_OTHER          0x80
+
+#define PCI_CLASS_SYSTEM_PERIPHERAL   0x08
+#define   PCI_SUBCLASS_PIC              0x00
+#define     PCI_IF_8259_PIC               0x00
+#define     PCI_IF_ISA_PIC                0x01
+#define     PCI_IF_EISA_PIC               0x02
+#define     PCI_IF_APIC_CONTROLLER        0x10  ///< I/O APIC interrupt controller , 32 bye none-prefectable memory.
+#define     PCI_IF_APIC_CONTROLLER2       0x20
+#define   PCI_SUBCLASS_DMA              0x01
+#define     PCI_IF_8237_DMA               0x00
+#define     PCI_IF_ISA_DMA                0x01
+#define     PCI_IF_EISA_DMA               0x02
+#define   PCI_SUBCLASS_TIMER            0x02
+#define     PCI_IF_8254_TIMER             0x00
+#define     PCI_IF_ISA_TIMER              0x01
+#define     PCI_IF_EISA_TIMER             0x02
+#define   PCI_SUBCLASS_RTC              0x03
+#define     PCI_IF_GENERIC_RTC            0x00
+#define     PCI_IF_ISA_RTC                0x00
+#define   PCI_SUBCLASS_PNP_CONTROLLER   0x04    ///< HotPlug Controller
+#define   PCI_SUBCLASS_PERIPHERAL_OTHER 0x80
+
+#define PCI_CLASS_INPUT_DEVICE        0x09
+#define   PCI_SUBCLASS_KEYBOARD         0x00
+#define   PCI_SUBCLASS_PEN              0x01
+#define   PCI_SUBCLASS_MOUSE_CONTROLLER 0x02
+#define   PCI_SUBCLASS_SCAN_CONTROLLER  0x03
+#define   PCI_SUBCLASS_GAMEPORT         0x04
+#define     PCI_IF_GAMEPORT               0x00
+#define     PCI_IF_GAMEPORT1              0x01
+#define   PCI_SUBCLASS_INPUT_OTHER      0x80
+
+#define PCI_CLASS_DOCKING_STATION     0x0A
+
+#define PCI_CLASS_PROCESSOR           0x0B
+#define   PCI_SUBCLASS_PROC_386         0x00
+#define   PCI_SUBCLASS_PROC_486         0x01
+#define   PCI_SUBCLASS_PROC_PENTIUM     0x02
+#define   PCI_SUBCLASS_PROC_ALPHA       0x10
+#define   PCI_SUBCLASS_PROC_POWERPC     0x20
+#define   PCI_SUBCLASS_PROC_MIPS        0x30
+#define   PCI_SUBCLASS_PROC_CO_PORC     0x40 ///< Co-Processor
+
+#define PCI_CLASS_SERIAL              0x0C
+#define   PCI_CLASS_SERIAL_FIREWIRE     0x00
+#define     PCI_IF_1394                   0x00
+#define     PCI_IF_1394_OPEN_HCI          0x10
+#define   PCI_CLASS_SERIAL_ACCESS_BUS   0x01
+#define   PCI_CLASS_SERIAL_SSA          0x02
+#define   PCI_CLASS_SERIAL_USB          0x03
+#define     PCI_IF_UHCI                   0x00
+#define     PCI_IF_OHCI                   0x10
+#define     PCI_IF_USB_OTHER              0x80
+#define     PCI_IF_USB_DEVICE             0xFE
+#define   PCI_CLASS_SERIAL_FIBRECHANNEL 0x04
+#define   PCI_CLASS_SERIAL_SMB          0x05
+
+#define PCI_CLASS_WIRELESS            0x0D
+#define   PCI_SUBCLASS_IRDA             0x00
+#define   PCI_SUBCLASS_IR               0x01
+#define   PCI_SUBCLASS_RF               0x02
+#define   PCI_SUBCLASS_WIRELESS_OTHER   0x80
+
+#define PCI_CLASS_INTELLIGENT_IO      0x0E
+
+#define PCI_CLASS_SATELLITE           0x0F
+#define   PCI_SUBCLASS_TV               0x01
+#define   PCI_SUBCLASS_AUDIO            0x02
+#define   PCI_SUBCLASS_VOICE            0x03
+#define   PCI_SUBCLASS_DATA             0x04
+
+#define PCI_SECURITY_CONTROLLER       0x10   ///< Encryption and decryption controller
+#define   PCI_SUBCLASS_NET_COMPUT       0x00
+#define   PCI_SUBCLASS_ENTERTAINMENT    0x10
+#define   PCI_SUBCLASS_SECURITY_OTHER   0x80
+
+#define PCI_CLASS_DPIO                0x11
+#define   PCI_SUBCLASS_DPIO             0x00
+#define   PCI_SUBCLASS_DPIO_OTHER       0x80
+
+#define IS_CLASS1(_p, c)              ((_p)->Hdr.ClassCode[2] == (c))
+#define IS_CLASS2(_p, c, s)           (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s)))
+#define IS_CLASS3(_p, c, s, p)        (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p)))
+
+#define IS_PCI_DISPLAY(_p)            IS_CLASS1 (_p, PCI_CLASS_DISPLAY)
+#define IS_PCI_VGA(_p)                IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0)
+#define IS_PCI_8514(_p)               IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1)
+#define IS_PCI_GFX(_p)                IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0)
+#define IS_PCI_OLD(_p)                IS_CLASS1 (_p, PCI_CLASS_OLD)
+#define IS_PCI_OLD_VGA(_p)            IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA)
+#define IS_PCI_IDE(_p)                IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE)
+#define IS_PCI_SCSI(_p)               IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0)
+#define IS_PCI_RAID(_p)               IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0)
+#define IS_PCI_LPC(_p)                IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0)
+#define IS_PCI_P2P(_p)                IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0)
+#define IS_PCI_P2P_SUB(_p)            IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1)
+#define IS_PCI_16550_SERIAL(_p)       IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550)
+#define IS_PCI_USB(_p)                IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB)
+
+//
+// the definition of Header Type
+//
+#define HEADER_TYPE_DEVICE            0x00
+#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01
+#define HEADER_TYPE_CARDBUS_BRIDGE    0x02
+#define HEADER_TYPE_MULTI_FUNCTION    0x80
+//
+// Mask of Header type
+//
+#define HEADER_LAYOUT_CODE            0x7f
+
+#define IS_PCI_BRIDGE(_p)             (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE))
+#define IS_CARDBUS_BRIDGE(_p)         (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE))
+#define IS_PCI_MULTI_FUNC(_p)         ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)
+
+///
+/// Rom Base Address in Bridge, defined in PCI-to-PCI Bridge Architecure Specification,
+///
+#define PCI_BRIDGE_ROMBAR             0x38
+
+#define PCI_MAX_BAR                   0x0006
+#define PCI_MAX_CONFIG_OFFSET         0x0100
+
+#define PCI_VENDOR_ID_OFFSET                        0x00
+#define PCI_DEVICE_ID_OFFSET                        0x02
+#define PCI_COMMAND_OFFSET                          0x04
+#define PCI_PRIMARY_STATUS_OFFSET                   0x06
+#define PCI_REVISION_ID_OFFSET                      0x08
+#define PCI_CLASSCODE_OFFSET                        0x09
+#define PCI_CACHELINE_SIZE_OFFSET                   0x0C
+#define PCI_LATENCY_TIMER_OFFSET                    0x0D
+#define PCI_HEADER_TYPE_OFFSET                      0x0E
+#define PCI_BIST_OFFSET                             0x0F
+#define PCI_BASE_ADDRESSREG_OFFSET                  0x10
+#define PCI_CARDBUS_CIS_OFFSET                      0x28
+#define PCI_SVID_OFFSET                             0x2C ///< SubSystem Vendor id
+#define PCI_SUBSYSTEM_VENDOR_ID_OFFSET              0x2C
+#define PCI_SID_OFFSET                              0x2E ///< SubSystem ID
+#define PCI_SUBSYSTEM_ID_OFFSET                     0x2E
+#define PCI_EXPANSION_ROM_BASE                      0x30
+#define PCI_CAPBILITY_POINTER_OFFSET                0x34
+#define PCI_INT_LINE_OFFSET                         0x3C ///< Interrupt Line Register
+#define PCI_INT_PIN_OFFSET                          0x3D ///< Interrupt Pin Register
+#define PCI_MAXGNT_OFFSET                           0x3E ///< Max Grant Register
+#define PCI_MAXLAT_OFFSET                           0x3F ///< Max Latency Register
+
+///
+/// defined in PCI-to-PCI Bridge Architecture Specification
+///
+#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET      0x18
+#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET    0x19
+#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET  0x1a
+#define PCI_BRIDGE_STATUS_REGISTER_OFFSET           0x1E
+#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET          0x3E
+
+///
+/// Interrupt Line "Unknown" or "No connection" value defined for x86 based system
+///
+#define PCI_INT_LINE_UNKNOWN                        0xFF
+
+typedef union {
+  struct {
+    UINT32  Reg : 8;
+    UINT32  Func : 3;
+    UINT32  Dev : 5;
+    UINT32  Bus : 8;
+    UINT32  Reserved : 7;
+    UINT32  Enable : 1;
+  } Bits;
+  UINT32  Uint32;
+} PCI_CONFIG_ACCESS_CF8;
+
+#pragma pack()
+
+#define EFI_PCI_COMMAND_IO_SPACE                        BIT0   ///< 0x0001
+#define EFI_PCI_COMMAND_MEMORY_SPACE                    BIT1   ///< 0x0002
+#define EFI_PCI_COMMAND_BUS_MASTER                      BIT2   ///< 0x0004
+#define EFI_PCI_COMMAND_SPECIAL_CYCLE                   BIT3   ///< 0x0008
+#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE     BIT4   ///< 0x0010
+#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP               BIT5   ///< 0x0020
+#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND            BIT6   ///< 0x0040
+#define EFI_PCI_COMMAND_STEPPING_CONTROL                BIT7   ///< 0x0080
+#define EFI_PCI_COMMAND_SERR                            BIT8   ///< 0x0100
+#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK               BIT9   ///< 0x0200
+
+///
+/// defined in PCI-to-PCI Bridge Architecture Specification
+///
+#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE    BIT0   ///< 0x0001
+#define EFI_PCI_BRIDGE_CONTROL_SERR                     BIT1   ///< 0x0002
+#define EFI_PCI_BRIDGE_CONTROL_ISA                      BIT2   ///< 0x0004
+#define EFI_PCI_BRIDGE_CONTROL_VGA                      BIT3   ///< 0x0008
+#define EFI_PCI_BRIDGE_CONTROL_VGA_16                   BIT4   ///< 0x0010
+#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT             BIT5   ///< 0x0020
+#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS      BIT6   ///< 0x0040
+#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK        BIT7   ///< 0x0080
+#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER    BIT8   ///< 0x0100
+#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER  BIT9   ///< 0x0200
+#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS             BIT10  ///< 0x0400
+#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR       BIT11  ///< 0x0800
+
+///
+/// Following are the PCI-CARDBUS bridge control bit, defined in PC Card Standard
+///
+#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE           BIT7   ///< 0x0080
+#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE       BIT8   ///< 0x0100
+#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE       BIT9   ///< 0x0200
+#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE     BIT10  ///< 0x0400
+
+//
+// Following are the PCI status control bit
+//
+#define EFI_PCI_STATUS_CAPABILITY                       BIT4   ///< 0x0010
+#define EFI_PCI_STATUS_66MZ_CAPABLE                     BIT5   ///< 0x0020
+#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE               BIT7   ///< 0x0080
+#define EFI_PCI_MASTER_DATA_PARITY_ERROR                BIT8   ///< 0x0100
+
+///
+/// defined in PC Card Standard
+///
+#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14
+
+#pragma pack(1)
+//
+// PCI Capability List IDs and records
+//
+#define EFI_PCI_CAPABILITY_ID_PMI     0x01
+#define EFI_PCI_CAPABILITY_ID_AGP     0x02
+#define EFI_PCI_CAPABILITY_ID_VPD     0x03
+#define EFI_PCI_CAPABILITY_ID_SLOTID  0x04
+#define EFI_PCI_CAPABILITY_ID_MSI     0x05
+#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06
+typedef struct {
+  UINT8 CapabilityID;
+  UINT8 NextItemPtr;
+} EFI_PCI_CAPABILITY_HDR;
+
+///
+/// Capability EFI_PCI_CAPABILITY_ID_PMI, defined in PCI Power Management Interface Specifiction
+///
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  PMC;
+  UINT16                  PMCSR;
+  UINT8                   BridgeExtention;
+  UINT8                   Data;
+} EFI_PCI_CAPABILITY_PMI;
+
+///
+/// Capability EFI_PCI_CAPABILITY_ID_AGP, defined in Accelerated Graphics Port Interface Specification
+///
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT8                   Rev;
+  UINT8                   Reserved;
+  UINT32                  Status;
+  UINT32                  Command;
+} EFI_PCI_CAPABILITY_AGP;
+
+///
+/// Capability EFI_PCI_CAPABILITY_ID_VPD, in PCI2.2 Spec.
+///
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  AddrReg;
+  UINT32                  DataReg;
+} EFI_PCI_CAPABILITY_VPD;
+
+///
+/// Capability EFI_PCI_CAPABILITY_ID_SLOTID, defined in PCI-to-PCI Bridge Architeture Specification
+///
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT8                   ExpnsSlotReg;
+  UINT8                   ChassisNo;
+} EFI_PCI_CAPABILITY_SLOTID;
+
+///
+/// Capability EFI_PCI_CAPABILITY_ID_MSI, defined in PCI2.2
+///
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  MsgCtrlReg;
+  UINT32                  MsgAddrReg;
+  UINT16                  MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI32;
+
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  MsgCtrlReg;
+  UINT32                  MsgAddrRegLsdw;
+  UINT32                  MsgAddrRegMsdw;
+  UINT16                  MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI64;
+
+///
+/// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG, defined in CompactPCI Hot Swap Specification PICMG 2.1, R1.0
+///
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  ///
+  /// not finished - fields need to go here
+  ///
+} EFI_PCI_CAPABILITY_HOTPLUG;
+
+#define DEVICE_ID_NOCARE    0xFFFF
+
+#define PCI_ACPI_UNUSED     0
+#define PCI_BAR_NOCHANGE    0
+#define PCI_BAR_OLD_ALIGN   0xFFFFFFFFFFFFFFFFULL
+#define PCI_BAR_EVEN_ALIGN  0xFFFFFFFFFFFFFFFEULL
+#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL
+#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL
+
+#define PCI_BAR_IDX0        0x00
+#define PCI_BAR_IDX1        0x01
+#define PCI_BAR_IDX2        0x02
+#define PCI_BAR_IDX3        0x03
+#define PCI_BAR_IDX4        0x04
+#define PCI_BAR_IDX5        0x05
+#define PCI_BAR_ALL         0xFF
+
+///
+/// EFI PCI Option ROM definitions
+///
+#define EFI_ROOT_BRIDGE_LIST                            'eprb'
+#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE       0x0EF1  ///< defined in UEFI Spec.
+
+typedef struct {
+  UINT8 Register;
+  UINT8 Function;
+  UINT8 Device;
+  UINT8 Bus;
+  UINT8 Reserved[4];
+} DEFIO_PCI_ADDR;
+
+#define PCI_EXPANSION_ROM_HEADER_SIGNATURE              0xaa55
+#define PCI_DATA_STRUCTURE_SIGNATURE                    SIGNATURE_32 ('P', 'C', 'I', 'R')
+#define PCI_CODE_TYPE_PCAT_IMAGE                        0x00
+#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED         0x0001  ///<defined in UEFI spec.
+
+typedef struct {
+  UINT16  Signature;    ///< 0xaa55
+  UINT8   Reserved[0x16];
+  UINT16  PcirOffset;
+} PCI_EXPANSION_ROM_HEADER;
+
+typedef struct {
+  UINT16  Signature;    ///< 0xaa55
+  UINT8   Size512;
+  UINT8   InitEntryPoint[3];
+  UINT8   Reserved[0x12];
+  UINT16  PcirOffset;
+} EFI_LEGACY_EXPANSION_ROM_HEADER;
+
+typedef struct {
+  UINT32  Signature;    ///< "PCIR"
+  UINT16  VendorId;
+  UINT16  DeviceId;
+  UINT16  Reserved0;
+  UINT16  Length;
+  UINT8   Revision;
+  UINT8   ClassCode[3];
+  UINT16  ImageLength;
+  UINT16  CodeRevision;
+  UINT8   CodeType;
+  UINT8   Indicator;
+  UINT16  Reserved1;
+} PCI_DATA_STRUCTURE;
+
+///
+/// defined in EFI/UEFI Spec
+///
+typedef struct {
+  UINT16  Signature;    ///< 0xaa55
+  UINT16  InitializationSize;
+  UINT32  EfiSignature; ///< 0x0EF1
+  UINT16  EfiSubsystem;
+  UINT16  EfiMachineType;
+  UINT16  CompressionType;
+  UINT8   Reserved[8];
+  UINT16  EfiImageHeaderOffset;
+  UINT16  PcirOffset;
+} EFI_PCI_EXPANSION_ROM_HEADER;
+
+typedef union {
+  UINT8                           *Raw;
+  PCI_EXPANSION_ROM_HEADER        *Generic;
+  EFI_PCI_EXPANSION_ROM_HEADER    *Efi;
+  EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt;
+} EFI_PCI_ROM_HEADER;
+
+#pragma pack()
+
+#endif
index 07bfc5d..c256701 100644 (file)
@@ -4,3 +4,4 @@ hijack
 prototester
 elf2efi32
 elf2efi64
+efirom
diff --git a/src/util/efirom.c b/src/util/efirom.c
new file mode 100644 (file)
index 0000000..1784add
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <assert.h>
+#include <getopt.h>
+#include <gpxe/efi/efi.h>
+#include <gpxe/efi/IndustryStandard/PeImage.h>
+#include <gpxe/efi/IndustryStandard/Pci22.h>
+
+#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
+
+/** Command-line options */
+struct options {
+       uint16_t vendor;
+       uint16_t device;
+};
+
+/**
+ * Allocate memory
+ *
+ * @v len              Length of memory to allocate
+ * @ret ptr            Pointer to allocated memory
+ */
+static void * xmalloc ( size_t len ) {
+       void *ptr;
+
+       ptr = malloc ( len );
+       if ( ! ptr ) {
+               eprintf ( "Could not allocate %zd bytes\n", len );
+               exit ( 1 );
+       }
+
+       return ptr;
+}
+
+/**
+ * Get file size
+ *
+ * @v file             File
+ * @v len              File size
+ */
+static size_t file_size ( FILE *file ) {
+       ssize_t len;
+
+       if ( fseek ( file, 0, SEEK_END ) != 0 ) {
+               eprintf ( "Could not seek: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+       len = ftell ( file );
+       if ( len < 0 ) {
+               eprintf ( "Could not determine file size: %s\n",
+                         strerror ( errno ) );
+               exit ( 1 );
+       }
+       return len;
+}
+
+/**
+ * Copy file
+ *
+ * @v in               Input file
+ * @v out              Output file
+ * @v len              Length to copy
+ */
+static void file_copy ( FILE *in, FILE *out, size_t len ) {
+       char buf[4096];
+       size_t frag_len;
+
+       while ( len ) {
+               frag_len = len;
+               if ( frag_len > sizeof ( buf ) )
+                       frag_len = sizeof ( buf );
+               if ( fread ( buf, frag_len, 1, in ) != 1 ) {
+                       eprintf ( "Could not read: %s\n",
+                                 strerror ( errno ) );
+                       exit ( 1 );
+               }
+               if ( fwrite ( buf, frag_len, 1, out ) != 1 ) {
+                       eprintf ( "Could not write: %s\n",
+                                 strerror ( errno ) );
+                       exit ( 1 );
+               }
+               len -= frag_len;
+       }
+}
+
+/**
+ * Read information from PE headers
+ *
+ * @v pe               PE file
+ * @ret machine                Machine type
+ * @ret subsystem      EFI subsystem
+ */
+static void read_pe_info ( FILE *pe, uint16_t *machine,
+                          uint16_t *subsystem ) {
+       EFI_IMAGE_DOS_HEADER dos;
+       union {
+               EFI_IMAGE_NT_HEADERS32 nt32;
+               EFI_IMAGE_NT_HEADERS64 nt64;
+       } nt;
+
+       /* Read DOS header */
+       if ( fseek ( pe, 0, SEEK_SET ) != 0 ) {
+               eprintf ( "Could not seek: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+       if ( fread ( &dos, sizeof ( dos ), 1, pe ) != 1 ) {
+               eprintf ( "Could not read: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+
+       /* Read NT header */
+       if ( fseek ( pe, dos.e_lfanew, SEEK_SET ) != 0 ) {
+               eprintf ( "Could not seek: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+       if ( fread ( &nt, sizeof ( nt ), 1, pe ) != 1 ) {
+               eprintf ( "Could not read: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+
+       /* Locate NT header */
+       *machine = nt.nt32.FileHeader.Machine;
+       switch ( *machine ) {
+       case EFI_IMAGE_MACHINE_IA32:
+               *subsystem = nt.nt32.OptionalHeader.Subsystem;
+               break;
+       case EFI_IMAGE_MACHINE_X64:
+               *subsystem = nt.nt64.OptionalHeader.Subsystem;
+               break;
+       default:
+               eprintf ( "Unrecognised machine type %04x\n", *machine );
+               exit ( 1 );
+       }
+}
+
+/**
+ * Convert EFI image to ROM image
+ *
+ * @v pe               EFI file
+ * @v rom              ROM file
+ */
+static void make_efi_rom ( FILE *pe, FILE *rom, struct options *opts ) {
+       struct {
+               EFI_PCI_EXPANSION_ROM_HEADER rom;
+               PCI_DATA_STRUCTURE pci __attribute__ (( aligned ( 4 ) ));
+       } headers;
+       size_t pe_size;
+       size_t rom_size;
+       unsigned int rom_size_sectors;
+
+       /* Determine output file size */
+       pe_size = file_size ( pe );
+       rom_size = ( pe_size + sizeof ( headers ) );
+       rom_size_sectors = ( ( rom_size + 511 ) / 512 );
+
+       /* Construct ROM header */
+       memset ( &headers, 0, sizeof ( headers ) );
+       headers.rom.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE;
+       headers.rom.InitializationSize = rom_size_sectors;
+       headers.rom.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE;
+       read_pe_info ( pe, &headers.rom.EfiMachineType,
+                      &headers.rom.EfiSubsystem );
+       headers.rom.EfiImageHeaderOffset = sizeof ( headers );
+       headers.rom.PcirOffset =
+               offsetof ( typeof ( headers ), pci );
+       headers.pci.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
+       headers.pci.VendorId = opts->vendor;
+       headers.pci.DeviceId = opts->device;
+       headers.pci.Length = sizeof ( headers.pci );
+       headers.pci.ClassCode[0] = PCI_CLASS_NETWORK;
+       headers.pci.ImageLength = rom_size_sectors;
+       headers.pci.CodeType = 0x03; /* No constant in EFI headers? */
+       headers.pci.Indicator = 0x80; /* No constant in EFI headers? */
+
+       /* Write out ROM header */
+       if ( fwrite ( &headers, sizeof ( headers ), 1, rom ) != 1 ) {
+               eprintf ( "Could not write headers: %s\n",
+                         strerror ( errno ) );
+               exit ( 1 );
+       }
+
+       /* Write out payload */
+       if ( fseek ( pe, 0, SEEK_SET ) != 0 ) {
+               eprintf ( "Could not seek: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+       file_copy ( pe, rom, pe_size );
+
+       /* Round up to 512-byte boundary */
+       if ( ftruncate ( fileno ( rom ), ( rom_size_sectors * 512 ) ) != 0 ) {
+               eprintf ( "Could not set length: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+}
+
+/**
+ * Print help
+ *
+ * @v program_name     Program name
+ */
+static void print_help ( const char *program_name ) {
+       eprintf ( "Syntax: %s [--vendor=VVVV] [--device=DDDD] "
+                 "infile outfile\n", program_name );
+}
+
+/**
+ * Parse command-line options
+ *
+ * @v argc             Argument count
+ * @v argv             Argument list
+ * @v opts             Options structure to populate
+ */
+static int parse_options ( const int argc, char **argv,
+                          struct options *opts ) {
+       char *end;
+       int c;
+
+       while (1) {
+               int option_index = 0;
+               static struct option long_options[] = {
+                       { "vendor", required_argument, NULL, 'v' },
+                       { "device", required_argument, NULL, 'd' },
+                       { "help", 0, NULL, 'h' },
+                       { 0, 0, 0, 0 }
+               };
+
+               if ( ( c = getopt_long ( argc, argv, "v:d:h",
+                                        long_options,
+                                        &option_index ) ) == -1 ) {
+                       break;
+               }
+
+               switch ( c ) {
+               case 'v':
+                       opts->vendor = strtoul ( optarg, &end, 16 );
+                       if ( *end ) {
+                               eprintf ( "Invalid vendor \"%s\"\n", optarg );
+                               exit ( 2 );
+                       }
+                       break;
+               case 'd':
+                       opts->device = strtoul ( optarg, &end, 16 );
+                       if ( *end ) {
+                               eprintf ( "Invalid device \"%s\"\n", optarg );
+                               exit ( 2 );
+                       }
+                       break;
+               case 'h':
+                       print_help ( argv[0] );
+                       exit ( 0 );
+               case '?':
+               default:
+                       exit ( 2 );
+               }
+       }
+       return optind;
+}
+
+int main ( int argc, char **argv ) {
+       struct options opts = {
+       };
+       unsigned int infile_index;
+       const char *infile_name;
+       const char *outfile_name;
+       FILE *infile;
+       FILE *outfile;
+
+       /* Parse command-line arguments */
+       infile_index = parse_options ( argc, argv, &opts );
+       if ( argc != ( infile_index + 2 ) ) {
+               print_help ( argv[0] );
+               exit ( 2 );
+       }
+       infile_name = argv[infile_index];
+       outfile_name = argv[infile_index + 1];
+
+       /* Open input and output files */
+       infile = fopen ( infile_name, "r" );
+       if ( ! infile ) {
+               eprintf ( "Could not open %s for reading: %s\n",
+                         infile_name, strerror ( errno ) );
+               exit ( 1 );
+       }
+       outfile = fopen ( outfile_name, "w" );
+       if ( ! outfile ) {
+               eprintf ( "Could not open %s for writing: %s\n",
+                         outfile_name, strerror ( errno ) );
+               exit ( 1 );
+       }
+
+       /* Convert file */
+       make_efi_rom ( infile, outfile, &opts );
+
+       fclose ( outfile );
+       fclose ( infile );
+
+       return 0;
+}
index ec75be0..886777d 100644 (file)
 #include <assert.h>
 #include <getopt.h>
 #include <bfd.h>
-
-/* Include the EFI PE image header file */
-typedef uint8_t UINT8;
-typedef uint16_t UINT16;
-typedef uint32_t UINT32;
-typedef uint64_t UINT64;
-#define SIGNATURE_16( a, b ) ( (a) | ( (b) << 8 ) )
-#define SIGNATURE_32( a, b, c, d ) \
-       ( (a) | ( (b) << 8 ) | ( (c) << 16 ) | ( (d) << 24 ) )
-#define  BIT0     0x00000001
-#define  BIT1     0x00000002
-#define  BIT2     0x00000004
-#define  BIT3     0x00000008
-#define  BIT4     0x00000010
-#define  BIT5     0x00000020
-#define  BIT6     0x00000040
-#define  BIT7     0x00000080
-#define  BIT8     0x00000100
-#define  BIT9     0x00000200
-#define  BIT10    0x00000400
-#define  BIT11    0x00000800
-#define  BIT12    0x00001000
-#define  BIT13    0x00002000
-#define  BIT14    0x00004000
-#define  BIT15    0x00008000
-#define  BIT16    0x00010000
-#define  BIT17    0x00020000
-#define  BIT18    0x00040000
-#define  BIT19    0x00080000
-#define  BIT20    0x00100000
-#define  BIT21    0x00200000
-#define  BIT22    0x00400000
-#define  BIT23    0x00800000
-#define  BIT24    0x01000000
-#define  BIT25    0x02000000
-#define  BIT26    0x04000000
-#define  BIT27    0x08000000
-#define  BIT28    0x10000000
-#define  BIT29    0x20000000
-#define  BIT30    0x40000000
-#define  BIT31    0x80000000
-#include "../include/gpxe/efi/IndustryStandard/PeImage.h"
+#include <gpxe/efi/efi.h>
+#include <gpxe/efi/IndustryStandard/PeImage.h>
 
 #define eprintf(...) fprintf ( stderr, __VA_ARGS__ )