Compare commits

...

2 Commits

Author SHA1 Message Date
4e456d9928 [efi] Do not attempt to drive PCI bridge devices
The "bridge" driver introduced in 3aa6b79 ("[pci] Add minimal PCI
bridge driver") is required only for BIOS builds using the ENA driver,
where experimentation shows that we cannot rely on the BIOS to fully
assign MMIO addresses.

Since the driver is a valid PCI driver, it will end up binding to all
PCI bridge devices even on a UEFI platform, where the firmware is
likely to have completed MMIO address assignment correctly.  This has
no impact on most systems since there is generally no UEFI driver for
PCI bridges: the enumeration of the whole PCI bus is handled by the
PciBusDxe driver bound to the root bridge.

Experimentation shows that at least one laptop will freeze at the
point that iPXE attempts to bind to the bridge device.  No deeper
investigation has been carried out to find the root cause.

Fix by causing efipci_supported() to return an error unless the
configuration space header type indicates a non-bridge device.

Reported-by: Marcel Petersen <mp@sbe.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-03 16:10:31 +00:00
d405a0bd84 [util] Add support for LoongArch64 binaries
Signed-off-by: Xiaotian Wu <wuxiaotian@loongson.cn>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-03 12:44:11 +00:00
6 changed files with 51 additions and 0 deletions

View File

@ -205,6 +205,7 @@ int pci_read_config ( struct pci_device *pci ) {
pci_read_config_dword ( pci, PCI_REVISION, &tmp );
pci->class = ( tmp >> 8 );
pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, &pci->irq );
pci_read_config_byte ( pci, PCI_HEADER_TYPE, &pci->hdrtype );
pci_read_bases ( pci );
/* Initialise generic device component */

View File

@ -227,6 +227,8 @@ struct pci_device {
uint32_t class;
/** Interrupt number */
uint8_t irq;
/** Header type */
uint8_t hdrtype;
/** Segment, bus, device, and function (bus:dev.fn) number */
uint32_t busdevfn;
/** Driver for this device */

View File

@ -785,12 +785,22 @@ int efipci_info ( EFI_HANDLE device, struct efi_pci_device *efipci ) {
*/
static int efipci_supported ( EFI_HANDLE device ) {
struct efi_pci_device efipci;
uint8_t hdrtype;
int rc;
/* Get PCI device information */
if ( ( rc = efipci_info ( device, &efipci ) ) != 0 )
return rc;
/* Do not attempt to drive bridges */
hdrtype = efipci.pci.hdrtype;
if ( ( hdrtype & PCI_HEADER_TYPE_MASK ) != PCI_HEADER_TYPE_NORMAL ) {
DBGC ( device, "EFIPCI " PCI_FMT " type %02x is not type %02x\n",
PCI_ARGS ( &efipci.pci ), hdrtype,
PCI_HEADER_TYPE_NORMAL );
return -ENOTTY;
}
/* Look for a driver */
if ( ( rc = pci_find_driver ( &efipci.pci ) ) != 0 ) {
DBGC ( device, "EFIPCI " PCI_FMT " (%04x:%04x class %06x) "

View File

@ -95,6 +95,7 @@ static void read_pe_info ( void *pe, uint16_t *machine,
break;
case EFI_IMAGE_MACHINE_X64:
case EFI_IMAGE_MACHINE_AARCH64:
case EFI_IMAGE_MACHINE_LOONGARCH64:
*subsystem = nt->nt64.OptionalHeader.Subsystem;
break;
default:

View File

@ -81,6 +81,9 @@
#ifndef EM_AARCH64
#define EM_AARCH64 183
#endif
#ifndef EM_LOONGARCH
#define EM_LOONGARCH 258
#endif
#ifndef R_AARCH64_NONE
#define R_AARCH64_NONE 0
#endif
@ -126,6 +129,27 @@
#ifndef R_ARM_V4BX
#define R_ARM_V4BX 40
#endif
#ifndef R_LARCH_NONE
#define R_LARCH_NONE 0
#endif
#ifndef R_LARCH_64
#define R_LARCH_64 2
#endif
#ifndef R_LARCH_B26
#define R_LARCH_B26 66
#endif
#ifndef R_LARCH_PCALA_HI20
#define R_LARCH_PCALA_HI20 71
#endif
#ifndef R_LARCH_PCALA_LO12
#define R_LARCH_PCALA_LO12 72
#endif
#ifndef R_LARCH_GOT_PC_HI20
#define R_LARCH_GOT_PC_HI20 75
#endif
#ifndef R_LARCH_GOT_PC_LO12
#define R_LARCH_GOT_PC_LO12 76
#endif
/**
* Alignment of raw data of sections in the image file
@ -486,6 +510,9 @@ static void set_machine ( struct elf_file *elf, struct pe_header *pe_header ) {
case EM_AARCH64:
machine = EFI_IMAGE_MACHINE_AARCH64;
break;
case EM_LOONGARCH:
machine = EFI_IMAGE_MACHINE_LOONGARCH64;
break;
default:
eprintf ( "Unknown ELF architecture %d\n", ehdr->e_machine );
exit ( 1 );
@ -671,6 +698,7 @@ static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr,
case ELF_MREL ( EM_X86_64, R_X86_64_NONE ) :
case ELF_MREL ( EM_AARCH64, R_AARCH64_NONE ) :
case ELF_MREL ( EM_AARCH64, R_AARCH64_NULL ) :
case ELF_MREL ( EM_LOONGARCH, R_LARCH_NONE ) :
/* Ignore dummy relocations used by REQUIRE_SYMBOL() */
break;
case ELF_MREL ( EM_386, R_386_32 ) :
@ -680,6 +708,7 @@ static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr,
break;
case ELF_MREL ( EM_X86_64, R_X86_64_64 ) :
case ELF_MREL ( EM_AARCH64, R_AARCH64_ABS64 ) :
case ELF_MREL ( EM_LOONGARCH, R_LARCH_64 ) :
/* Generate an 8-byte PE relocation */
generate_pe_reloc ( pe_reltab, offset, 8 );
break;
@ -700,6 +729,11 @@ static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr,
case ELF_MREL ( EM_AARCH64, R_AARCH64_LDST16_ABS_LO12_NC ) :
case ELF_MREL ( EM_AARCH64, R_AARCH64_LDST32_ABS_LO12_NC ) :
case ELF_MREL ( EM_AARCH64, R_AARCH64_LDST64_ABS_LO12_NC ) :
case ELF_MREL ( EM_LOONGARCH, R_LARCH_B26):
case ELF_MREL ( EM_LOONGARCH, R_LARCH_PCALA_HI20 ):
case ELF_MREL ( EM_LOONGARCH, R_LARCH_PCALA_LO12 ):
case ELF_MREL ( EM_LOONGARCH, R_LARCH_GOT_PC_HI20 ):
case ELF_MREL ( EM_LOONGARCH, R_LARCH_GOT_PC_LO12 ):
/* Skip PC-relative relocations; all relative
* offsets remain unaltered when the object is
* loaded.

View File

@ -72,6 +72,9 @@ efi_boot_name() {
"c201" )
echo "BOOTARM.EFI"
;;
"6462" )
echo "BOOTLOONGARCH64.EFI"
;;
"64aa" )
echo "BOOTAA64.EFI"
;;