Commit Graph

7243 Commits

Author SHA1 Message Date
Michael Brown
d4258272c6 [crypto] Construct signatures using ASN.1 builders
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-01 16:02:54 +00:00
Michael Brown
8cd963ab96 [crypto] Pass signatures for verification as ASN.1 cursors
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-01 14:50:54 +00:00
Michael Brown
c9c0282594 [crypto] Restructure handling of ASN.1 bit strings
Signature values in ASN.1 tend to be encoded as bit strings rather
than octet strings.  In practice, no existent signature scheme uses a
non-integral number of bytes.

Switch to using a standard ASN.1 cursor to hold signature values, to
simplify consuming code.  Restructure the API to treat entering an
ASN.1 bit string in the same way as entering any other ASN.1 type.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-01 13:09:45 +00:00
Bert Ezendam
d73981aece [intel] Add PCI IDs for I225 and I226 chipsets
Identifiers are taken from the pci.ids database.

Signed-off-by: Bert Ezendam <bert.ezendam@alliander.com>
2025-11-26 14:14:02 +00:00
Michael Brown
19dffdc836 [efi] Allow for creating devices with no EFI parent device
On some systems (observed on an AWS m8g.medium instance in eu-west-2),
the UEFI firmware fails to enumerate some of the underlying hardware
devices.  On these systems, we cannot comply with the UEFI device
model by adding our SNP device as a child of the hardware device and
appending to the parent hardware device path, since no parent hardware
device has been created.

Work around these systems by allowing for the creation of SNP devices
with no parent device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-25 12:04:43 +00:00
Michael Brown
dfea3bbfad [pci] Use runtime selectable PCI I/O API for EFI cloud builds
On some systems (observed on an AWS m8g.medium instance in eu-west-2),
the UEFI firmware omits the PCI host bridge drivers for all but the
first PCI bus.  The observable result is that any devices on other PCI
buses (such as the ENA network device) are not enumerated by the UEFI
firmware and are therefore unusable by iPXE.

Support these systems by switching to using PCIAPI_CLOUD for EFI cloud
builds, trying the EFI PCI I/O API first and falling back to direct
access (via ECAM) for devices that the UEFI firmware has failed to
enumerate itself.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 23:25:31 +00:00
Michael Brown
9c1ac48bcf [pci] Allow probing permission to vary by range
Make pci_can_probe() part of the runtime selectable PCI I/O API, and
defer this check to the per-range API.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 23:16:32 +00:00
Michael Brown
ff1a17dc7e [pci] Use linker tables for runtime selectable PCI APIs
Use the linker table mechanism to enumerate the underlying PCI I/O
APIs, to allow PCIAPI_CLOUD to become architecture-independent code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 20:54:01 +00:00
Michael Brown
0cf2f8028c [pci] Allow PCI configuration space access mechanism to vary by range
On some systems (observed on an AWS EC2 c7a.medium instance in
eu-west-2), there is no single PCI configuration space access
mechanism that covers all PCI devices.  For example: the ECAM may
provide access only to bus 01 and above, with type 1 accesses required
to access bus 00.

Allow the choice of PCI configuration space access mechanism to be
made on a per-range basis, rather than being made just once in an
initialisation function.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 19:10:49 +00:00
Michael Brown
81496315f2 [arm] Avoid unaligned accesses for memcpy() and memset()
iPXE runs only in environments that support unaligned accesses to RAM.
However, memcpy() and memset() are also used to write to graphical
framebuffer memory, which may support only aligned accesses on some
CPU architectures such as ARM.

Restructure the 64-bit ARM memcpy() and memset() routines along the
lines of the RISC-V implementations, which split the region into
pre-aligned, aligned, and post-aligned sections.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-19 22:20:38 +00:00
Michael Brown
3383474653 [efi] Wrap a selection of runtime services calls
Allow DEBUG=efi_wrap to trace various runtime services calls as well
as the existing boot services calls.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-13 15:02:03 +00:00
Michael Brown
925af2b4d7 [efi] Allow SAN-booted images to be traced via DEBUG=efi_wrap
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-13 13:17:25 +00:00
Michael Brown
0a8e34657e [efi] Add image security database GUID definition
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-12 12:09:40 +00:00
Michael Brown
5c135240bc [efi] Add Microsoft vendor GUID definition
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-12 12:01:37 +00:00
Michael Brown
5154b6fcc5 [efi] Add storage security command protocol header and GUID definition
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 23:24:22 +00:00
Michael Brown
27ec3c76ab [efi] Update to current EDK2 headers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 23:24:22 +00:00
Michael Brown
3a2f75b789 [efi] Mark Arm/ProcessorBind.h as a non-imported header
Support for ARM32 has been removed from the EDK2 codebase.  However,
we may as well retain the ability to build iPXE for existing EFI
platforms.

Add an iPXE include guard to this file so that the EDK2 header import
script will no longer attempt to import it from the EDK2 tree.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 16:14:22 +00:00
Michael Brown
f0d978d8b4 [efi] Mark Ip4Config.h as a non-imported header
The Ip4Config.h header has been removed from the EDK2 codebase as
obsolete.  However, we may still encounter it in the wild and so it is
useful to retain the GUID and the corresponding protocol name for
debug messages.

Add an iPXE include guard to this file so that the EDK2 header import
script will no longer attempt to import it from the EDK2 tree.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 16:12:26 +00:00
Michael Brown
f9b9ef578a [efi] Mark UgaDraw.h as a non-imported header
The UgaDraw.h header has been removed from the EDK2 codebase as
obsolete.  However, we may still encounter it in the wild and so it is
useful to retain the GUID and the corresponding protocol name for
debug messages.

Add an iPXE include guard to this file so that the EDK2 header import
script will no longer attempt to import it from the EDK2 tree.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 16:09:27 +00:00
Michael Brown
c0ac23fc56 [efi] Switch back to VA_START() etc macros for EFIAPI functions
Commit 670810b ("[efi] Use standard va_args macros instead of
VA_START() etc") fixed a 32-bit RISC-V build error, but broke the
functionality of the InstallMultipleProtocolInterfaces() and
UninstallMultipleProtocolInterfaces() wrapper functions.  GCC does not
automatically check the ABI of the current function when using the
__builtin_va_start() and related macros, and it is therefore necessary
for code to use __builtin_ms_va_start() etc from within functions
marked as EFIAPI.

Since commit 9016f2e ("[efi] Skip including the EDK2 ProcessorBind.h
header for 32-bit RISC-V") has now fixed the original 32-bit RISC-V
build error, we can switch back to using the EDK2 VA_START() etc
macros to obtain the correct behaviour.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 15:41:42 +00:00
Michael Brown
360aa7064f [efi] Skip including the EDK2 ProcessorBind.h header for 32-bit RISC-V
We currently include the EDK2 RiscV64/ProcessorBind.h header when
building for 32-bit RISC-V, as a placeholder since there is no support
for 32-bit RISC-V in upstream EDK2.

This causes errors when attempting to use the EDK2 VA_START() et al
macros, since RiscV64/ProcessorBind.h ends up defining UINTN with a
size different from the size of a pointer.

Fix by falling back to the generic definitions for UINTN etc (as used
for EFI_HOSTONLY) whenever we don't have an architecture-specific
ProcessorBind.h header available.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 15:41:42 +00:00
Michael Brown
df7f59d47a [pci] Move ECAM pci_can_probe() definition to correct header file
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-11 13:13:54 +00:00
Michael Brown
b41bda4413 [spcr] Accept alternative type value for a 16550-compatible UART
Some systems (observed on an AWS EC2 m7i.metal-24xl instance in
eu-south-2) use the newer "16550-compatible with parameters defined in
Generic Address Structure" type value.  (There does not appear to be
any particular reason why the newer value needs to be used: the UART
is still a standard 16550 with single-byte registers.)

Accept this additional type value for a 16550-compatible UART.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-05 20:06:53 +00:00
Michael Brown
6d9374e5a3 [acpi] Allow acpi_ioremap() to map a port I/O address
Assume that on any platforms where port I/O is used (i.e. x86), a port
I/O address may be used directly for the combined MMIO and port I/O
accessors without requiring an explicit mapping operation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-05 19:33:53 +00:00
Michael Brown
bd3982b630 [ioapi] Allow iounmap() to be called for port I/O addresses
Allow code using the combined MMIO and port I/O accessors to safely
call iounmap() to unmap the MMIO or port I/O region.

In the virtual offset I/O mapping API as used for UEFI, 32-bit BIOS,
and 32-bit RISC-V SBI, iounmap() is a no-op anyway.  In 64-bit RISC-V
SBI, we have no concept of port I/O and so the issue is moot.

This leaves only 64-bit BIOS, where it suffices to simply do nothing
for any pages outside of the chosen MMIO virtual address range.

For symmetry, we implement the equivalent change in the very closely
related RISC-V page management code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-05 19:33:53 +00:00
Michael Brown
f2ea97102e [spcr] Use the serial port defined by the ACPI SPCR by default
On platforms where we expect ACPI tables to exist, use the serial port
defined by the ACPI Serial Port Console Redirection (SPCR) table by
default, falling back to the fixed serial port defined at build time.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-05 16:55:20 +00:00
Michael Brown
595ff24030 [spcr] Add support for the ACPI Serial Port Console Redirection table
The BIOS may provide an ACPI Serial Port Console Redirection (SPCR)
table to describe the serial port to be used for early boot messages.

Add support for parsing the SPCR and instantiating a 16550-based UART.
We do not currently attempt to support other types of UART, since iPXE
does not yet have drivers for other types.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-05 14:12:57 +00:00
Michael Brown
8fd5e27727 [acpi] Add acpi_ioremap() to map an ACPI-described address
An ACPI Generic Address Structure (GAS) may be used to describe the
location of a peripheral such as an early boot console.  Add the
relevant definitions and provide acpi_ioremap() as a helper function
to map a region described using this structure.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-05 14:10:14 +00:00
Michael Brown
08d4d7fe9d [uart] Make baud rate a property of the UART
Make the current baud rate (if specified) a property of the UART, to
allow the default_serial_console() function to specify the default
baud rate as well as the default UART device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-05 12:18:17 +00:00
Michael Brown
a786c8d231 [uart] Support 16550 UARTs accessed via either MMIO or port I/O
Use the combined accessors ioread8() and iowrite8() to read and write
16550 UART registers, to allow the decision between using MMIO and
port I/O to be made at runtime.

Minimise the increase in code size for x86 by ignoring the register
shift, since this is essentially used only for non-x86 SoCs.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-04 21:14:41 +00:00
Michael Brown
f7de1b53dc [ioapi] Provide combined MMIO and port I/O accessors
Some devices (such as a 16550 UART) may be accessed via either MMIO or
port I/O.  This is currently forced to be a compile-time decision.
For example: we currently access a 16550 UART via port I/O on x86 and
via MMIO on any other platform.

PCI UARTs with MMIO BARs do exist but are not currently supported in
an x86 build of iPXE.  Some AWS EC2 systems (observed on a c6i.metal
instance in eu-west-2) provide only a PCI MMIO UART, and it is
therefore currently impossible to get serial output from iPXE on these
instance types.

Add ioread8(), ioread16(), etc accessors that will select between MMIO
and port I/O at the point of use.  For non-x86 platforms where we
currently have no port I/O support, these simply become wrappers
around the corresponding readb(), readw(), etc MMIO accessors.  On
x86, we use the fairly well-known trick of treating any 16-bit address
(below 64kB) as a port I/O address.

This trick works even in the i386 BIOS build of iPXE (where virtual
addresses are offset from physical addresses by a runtime constant),
since the first 64kB of the virtual address space will correspond to
the iPXE binary itself (along with its uninitialised-data space), and
so must be RAM rather than a valid MMIO address range.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-04 21:14:41 +00:00
Michael Brown
fde35ff003 [pci] Disable decoding while setting a BAR value
Setting the base address for a 64-bit BAR requires two separate 32-bit
writes to configuration space, and so will necessarily result in the
BAR temporarily holding an invalid partially written address.

Some hypervisors (observed on an AWS EC2 c7a.medium instance in
eu-west-2) will assume that guests will write BAR values only while
decoding is disabled, and may not rebuild MMIO mappings for the guest
if the BAR registers are written while decoding is enabled.  The
effect of this is that MMIO accesses are not routed through to the
device even though inspection from within the guest shows that every
single PCI configuration register has the correct value.  Writes to
the device will be ignored, and reads will return the all-ones pattern
that typically indicates a nonexistent device.

With the ENA network driver now using low latency transmit queues,
this results in the transmit descriptors being lost (since the MMIO
writes to BAR2 never reach the device), which in turn causes the
device to lock up as soon as the transmit doorbell is rung for the
first time.

Fix by disabling decoding of memory and I/O cycles while setting a BAR
address (as we already do while sizing a BAR), so that the invalid
partial address can never be decoded and so that hypervisors will
rebuild MMIO mappings as expected.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-29 23:30:52 +00:00
Michael Brown
606e87ec7a [cloud] Display instance type in AWS EC2
Experiments suggest that the instance type is exposed via the SMBIOS
product name.  Include this information within the default output,
since it is often helpful in debugging.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-29 13:26:50 +00:00
Michael Brown
0336e2987c [ena] Leave queue base address empty when creating a low latency queue
The queue base address is meaningless for a low latency queue, since
the queue entries are written directly to the on-device memory.  Any
non-zero queue base address will be safely ignored by the hardware,
but leaves open the possibility that future revisions could treat it
as an error.

Leave this field as zero, to match the behaviour of the Linux driver.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-28 12:27:06 +00:00
Michael Brown
0ddd830693 [riscv] Correct page table stride calculation
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-27 14:22:16 +00:00
Michael Brown
426c721e32 [librm] Correct page table stride calculation
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-27 14:22:16 +00:00
Michael Brown
c8f088d4e1 [cloud] Display build architecture in AWS EC2
On some newer (7th and 8th generation) instance types, the 32-bit
build of iPXE cannot access PCI configuration space since the ECAM is
placed outside of the 32-bit address space.  The visible symptom is
that iPXE fails to detect any network devices.

The public AMIs are all now built as 64-bit binaries, but there is
nothing that prevents the building and importing of a 32-bit AMI.
There are still potentially valid use cases for 32-bit AMIs (e.g. if
planning to use the AMI only for older instance types), and so we
cannot sensibly prevent this error at build time.

Display the build architecture as part of the AWS EC2 embedded script,
to at least allow for easy identification of this particular failure
mode at run time.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-20 12:58:03 +01:00
Michael Brown
416a2143af [cloud] Remove AWS public image access block only if not already unblocked
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-20 12:58:03 +01:00
Michael Brown
ba1846a0d3 [cloud] Remove AWS public image access block automatically if needed
Making images public is blocked by default in new AWS regions.  Remove
this block automatically whenever creating a public image.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-17 14:22:21 +01:00
Michael Brown
b2e8468219 [ena] Limit receive queue size to work around hardware bugs
Commit a801244 ("[ena] Increase receive ring size to 128 entries")
increased the receive ring size to 128 entries (while leaving the fill
level at 16), since using a smaller receive ring caused unexplained
failures on some instance types.

The original hardware bug that resulted in that commit seems to have
been fixed: experiments suggest that the original failure (observed on
a c6i.large instance in eu-west-2) will no longer reproduce when using
a receive ring containing only 16 entries (as was the case prior to
that commit).

Newer generations of the ENA hardware (observed on an m8i.large
instance in eu-south-2) seem to have a new and exciting hardware bug:
these instance types appear to use a hash of the received packet
header to determine which portion of the (out-of-order) receive ring
to use.  If that portion of the ring happens to be empty (e.g. because
only 32 entries of the 128-entry ring are filled at any one time),
then the packet will be silently dropped.

Work around this new hardware bug by reducing the receive ring size
down to the current fill level of 32 entries.  This appears to work on
all current instance types (but has not been exhaustively tested).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-17 13:25:05 +01:00
Michael Brown
846c505ae9 [ena] Increase transmit queue size to match receive fill level
Avoid running out of transmit descriptors when sending TCP ACKs by
increasing the transmit queue size to match the increased received
fill level.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-17 13:25:05 +01:00
Michael Brown
0ae5e25de2 [ena] Add memory barrier after writing to on-device memory
Ensure that writes to on-device memory have taken place before writing
to the doorbell register.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-17 12:35:23 +01:00
Michael Brown
c296747d0e [ena] Increase receive fill level
Experiments suggest that at least some instance types (observed with
c6i.large in eu-west-2) experience high packet drop rates with only 16
receive buffers allocated.  Increase the fill level to 32 buffers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-16 16:36:29 +01:00
Michael Brown
c1badf71ca [ena] Add support for low latency transmit queues
Newer generations of the ENA hardware require the use of low latency
transmit queues, where the submission queues and the initial portion
of the transmitted packet are written to on-device memory via BAR2
instead of being read from host memory.

Detect support for low latency queues and set the placement policy
appropriately.  We attempt the use of low latency queues only if the
device reports that it supports inline headers, 128-byte entries, and
two descriptors prior to the inlined header, on the basis that we
don't care about using low latency queues on older versions of the
hardware since those versions will support normal host memory
submission queues anyway.

We reuse the redundant memory allocated for the submission queue as
the bounce buffer for constructing the descriptors and inlined packet
data, since this avoids needing a separate allocation just for the
bounce buffer.

We construct a metadata submission queue entry prior to the actual
submission queue entry, since experimentation suggests that newer
generations of the hardware require this to be present even though it
conveys no information beyond its own existence.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-16 16:36:29 +01:00
Michael Brown
0d15d7f0a5 [ena] Record supported device features
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-16 16:36:29 +01:00
Michael Brown
e5e371f485 [ena] Cancel uncompleted transmit buffers on close
Avoid spurious assertion failures by ensuring that references to
uncompleted transmit buffers are not retained after the device has
been closed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-16 16:36:29 +01:00
Michael Brown
dcc5d36ce5 [ena] Map the on-device memory, if present
Newer generations of the ENA hardware require the use of low latency
transmit queues, where the submission queues and the initial portion
of the transmitted packet are written to on-device memory via BAR2
instead of being read from host memory.

Prepare for this by mapping the on-device memory BAR.  As with the
register BAR, we may need to steal a base address from the upstream
PCI bridge since the BIOS on some instance types (observed with an
m8i.metal-48xl instance in eu-south-2) will fail to assign an address
to the device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-15 15:55:57 +01:00
Michael Brown
510f3e5e17 [ena] Add descriptive messages for any admin queue command failures
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-15 12:00:42 +01:00
Michael Brown
3538e9c39a [pci] Record prefetchable memory window for PCI bridges
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-14 18:38:08 +01:00
Michael Brown
04a61c413d [ena] Use pci_bar_set() to place device within bridge memory window
Use pci_bar_set() when we need to set a device base address (on
instance types such as c6i.metal where the BIOS fails to do so), so
that 64-bit BARs will be handled automatically.

This particular issue has so far been observed only on 6th generation
instances.  These use 32-bit BARs, and so the lack of support for
handling 64-bit BARs has not caused any observable issue.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-10-14 15:57:02 +01:00