mirror of
https://gitlab.com/qemu-project/ipxe.git
synced 2025-11-03 07:59:06 +08:00
Compare commits
31 Commits
hermon_res
...
fxsr
| Author | SHA1 | Date | |
|---|---|---|---|
| 900f1f98d3 | |||
| e63b8c3302 | |||
| 22bb29eabc | |||
| 8446a439b3 | |||
| 4039b54ba3 | |||
| cd3de55ea5 | |||
| d562339fca | |||
| e39cd79a00 | |||
| 057674bb1f | |||
| 19d0fab40f | |||
| fa012dd020 | |||
| d16535aa4f | |||
| 1b99ba2a93 | |||
| 83516ba7f0 | |||
| 0049243367 | |||
| c160fb2593 | |||
| b539e9a7e9 | |||
| df16df2c85 | |||
| d79f504c0c | |||
| 831f17f66f | |||
| 1259580dde | |||
| eeca29a1e0 | |||
| e8393c3728 | |||
| e80299c56b | |||
| bfb72ec234 | |||
| 885c6d6e98 | |||
| 5bdb75c9d0 | |||
| 1af0fe04f8 | |||
| 0c94659a8a | |||
| 6f1cb791ee | |||
| 8747241b3e |
69
.github/workflows/build.yml
vendored
Normal file
69
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
name: Build
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
|
||||
x86:
|
||||
name: x86
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux libc6-dev-i386 valgrind
|
||||
- name: Build (BIOS)
|
||||
run: |
|
||||
make -j 4 -C src
|
||||
- name: Build (Everything)
|
||||
run: |
|
||||
make -j 4 -C src everything
|
||||
- name: Test
|
||||
run: |
|
||||
valgrind ./src/bin-i386-linux/tests.linux
|
||||
valgrind ./src/bin-x86_64-linux/tests.linux
|
||||
|
||||
arm32:
|
||||
name: ARM32
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux gcc-arm-none-eabi
|
||||
- name: Build
|
||||
run: |
|
||||
make -j 4 -C src CROSS=arm-none-eabi- \
|
||||
bin-arm32-efi/intel.efi \
|
||||
bin-arm32-efi/intel.usb \
|
||||
bin-arm32-efi/intel.iso
|
||||
|
||||
arm64:
|
||||
name: ARM64
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux gcc-aarch64-linux-gnu
|
||||
- name: Build
|
||||
run: |
|
||||
make -j 4 -C src CROSS=aarch64-linux-gnu- \
|
||||
bin-arm64-efi/ipxe.efi \
|
||||
bin-arm64-efi/ipxe.usb \
|
||||
bin-arm64-efi/ipxe.iso
|
||||
37
.github/workflows/coverity.yml
vendored
Normal file
37
.github/workflows/coverity.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: Coverity Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- coverity_scan
|
||||
|
||||
jobs:
|
||||
submit:
|
||||
name: Submit
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
- name: Download Coverity Scan
|
||||
run: |
|
||||
curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
|
||||
--form project=${{ github.repository }} \
|
||||
--output coverity.tar.gz \
|
||||
https://scan.coverity.com/download/cxx/linux64
|
||||
mkdir -p /opt/coverity
|
||||
sudo tar xvzf coverity.tar.gz --strip 1 --directory /opt/coverity
|
||||
- name: Build via Coverity Scan
|
||||
run: |
|
||||
make -C src bin/deps
|
||||
/opt/coverity/bin/cov-build --dir cov-int make -C src bin/blib.a
|
||||
- name: Create submission
|
||||
run : |
|
||||
tar cvzf cov-int.tar.gz cov-int
|
||||
- name: Submit to Coverity Scan
|
||||
run: |
|
||||
curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
|
||||
--form email=${{ secrets.COVERITY_SCAN_EMAIL }} \
|
||||
--form file=@cov-int.tar.gz \
|
||||
--form version=${{ github.sha }} \
|
||||
--form description=${{ github.ref }} \
|
||||
https://scan.coverity.com/builds?project=${{ github.repository }}
|
||||
58
.travis.yml
58
.travis.yml
@ -1,58 +0,0 @@
|
||||
dist: xenial
|
||||
|
||||
sudo: false
|
||||
|
||||
git:
|
||||
depth: false
|
||||
|
||||
language: c
|
||||
|
||||
cache: ccache
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- binutils-dev
|
||||
- liblzma-dev
|
||||
- syslinux
|
||||
- isolinux
|
||||
- genisoimage
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "ipxe/ipxe"
|
||||
version: $TRAVIS_COMMIT
|
||||
build_command_prepend: "make -C src bin/deps"
|
||||
build_command: "make -C src bin/blib.a"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
env:
|
||||
global:
|
||||
- MAKEFLAGS="-j 4"
|
||||
|
||||
script:
|
||||
- make -C src bin/blib.a
|
||||
- make -C src bin/ipxe.pxe
|
||||
- make -C src bin/ipxe.usb
|
||||
- make -C src bin/ipxe.iso
|
||||
- make -C src bin/8086100e.mrom
|
||||
- make -C src bin-x86_64-pcbios/blib.a
|
||||
- make -C src bin-x86_64-pcbios/ipxe.pxe
|
||||
- make -C src bin-x86_64-pcbios/ipxe.usb
|
||||
- make -C src bin-x86_64-pcbios/ipxe.iso
|
||||
- make -C src bin-x86_64-pcbios/8086100e.mrom
|
||||
- make -C src bin-x86_64-efi/blib.a
|
||||
- make -C src bin-x86_64-efi/ipxe.efi
|
||||
- make -C src bin-x86_64-efi/intel.efidrv
|
||||
- make -C src bin-x86_64-efi/intel.efirom
|
||||
- make -C src bin-i386-efi/blib.a
|
||||
- make -C src bin-i386-efi/ipxe.efi
|
||||
- make -C src bin-i386-efi/intel.efidrv
|
||||
- make -C src bin-i386-efi/intel.efirom
|
||||
- make -C src bin-x86_64-linux/blib.a
|
||||
- make -C src bin-x86_64-linux/tap.linux
|
||||
- make -C src bin-x86_64-linux/af_packet.linux
|
||||
- make -C src bin-x86_64-linux/tests.linux
|
||||
- ./src/bin-x86_64-linux/tests.linux
|
||||
100
contrib/cloud/aws-import
Executable file
100
contrib/cloud/aws-import
Executable file
@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from base64 import b64encode
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from hashlib import sha256
|
||||
from itertools import count
|
||||
|
||||
import boto3
|
||||
|
||||
BLOCKSIZE = 512 * 1024
|
||||
|
||||
|
||||
def create_snapshot(region, description, image):
|
||||
"""Create an EBS snapshot"""
|
||||
client = boto3.client('ebs', region_name=region)
|
||||
snapshot = client.start_snapshot(VolumeSize=1,
|
||||
Description=description)
|
||||
snapshot_id = snapshot['SnapshotId']
|
||||
with open(image, 'rb') as fh:
|
||||
for block in count():
|
||||
data = fh.read(BLOCKSIZE)
|
||||
if not data:
|
||||
break
|
||||
data = data.ljust(BLOCKSIZE, b'\0')
|
||||
checksum = b64encode(sha256(data).digest()).decode()
|
||||
client.put_snapshot_block(SnapshotId=snapshot_id,
|
||||
BlockIndex=block,
|
||||
BlockData=data,
|
||||
DataLength=BLOCKSIZE,
|
||||
Checksum=checksum,
|
||||
ChecksumAlgorithm='SHA256')
|
||||
client.complete_snapshot(SnapshotId=snapshot_id,
|
||||
ChangedBlocksCount=block)
|
||||
return snapshot_id
|
||||
|
||||
|
||||
def import_image(region, name, architecture, image, public):
|
||||
"""Import an AMI image"""
|
||||
client = boto3.client('ec2', region_name=region)
|
||||
resource = boto3.resource('ec2', region_name=region)
|
||||
description = '%s (%s)' % (name, architecture)
|
||||
snapshot_id = create_snapshot(region=region, description=description,
|
||||
image=image)
|
||||
client.get_waiter('snapshot_completed').wait(SnapshotIds=[snapshot_id])
|
||||
image = client.register_image(Architecture=architecture,
|
||||
BlockDeviceMappings=[{
|
||||
'DeviceName': '/dev/sda1',
|
||||
'Ebs': {
|
||||
'SnapshotId': snapshot_id,
|
||||
'VolumeType': 'standard',
|
||||
},
|
||||
}],
|
||||
EnaSupport=True,
|
||||
Name=description,
|
||||
RootDeviceName='/dev/sda1',
|
||||
SriovNetSupport='simple',
|
||||
VirtualizationType='hvm')
|
||||
image_id = image['ImageId']
|
||||
client.get_waiter('image_available').wait(ImageIds=[image_id])
|
||||
if public:
|
||||
resource.Image(image_id).modify_attribute(Attribute='launchPermission',
|
||||
OperationType='add',
|
||||
UserGroups=['all'])
|
||||
return image_id
|
||||
|
||||
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="Import AWS EC2 image (AMI)")
|
||||
parser.add_argument('--architecture', '-a', default='x86_64',
|
||||
help="CPU architecture")
|
||||
parser.add_argument('--name', '-n', required=True,
|
||||
help="Image name")
|
||||
parser.add_argument('--public', '-p', action='store_true',
|
||||
help="Make image public")
|
||||
parser.add_argument('--region', '-r', action='append',
|
||||
help="AWS region(s)")
|
||||
parser.add_argument('image', help="iPXE disk image")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Use all regions if none specified
|
||||
if not args.region:
|
||||
args.region = sorted(x['RegionName'] for x in
|
||||
boto3.client('ec2').describe_regions()['Regions'])
|
||||
|
||||
# Use one thread per region to maximise parallelism
|
||||
with ThreadPoolExecutor(max_workers=len(args.region)) as executor:
|
||||
futures = {executor.submit(import_image,
|
||||
region=region,
|
||||
name=args.name,
|
||||
architecture=args.architecture,
|
||||
image=args.image,
|
||||
public=args.public): region
|
||||
for region in args.region}
|
||||
results = {futures[future]: future.result()
|
||||
for future in as_completed(futures)}
|
||||
|
||||
# Show created images
|
||||
for region in args.region:
|
||||
print("%s: %s" % (region, results[region]))
|
||||
File diff suppressed because it is too large
Load Diff
@ -48,7 +48,6 @@ ELF2EFI32 := ./util/elf2efi32
|
||||
ELF2EFI64 := ./util/elf2efi64
|
||||
EFIROM := ./util/efirom
|
||||
EFIFATBIN := ./util/efifatbin
|
||||
ICCFIX := ./util/iccfix
|
||||
EINFO := ./util/einfo
|
||||
GENKEYMAP := ./util/genkeymap.pl
|
||||
DOXYGEN := doxygen
|
||||
|
||||
@ -76,9 +76,7 @@ CCDEFS := $(shell $(CC) -E -x c -c /dev/null -dM | cut -d" " -f2)
|
||||
ccdefs:
|
||||
@$(ECHO) $(CCDEFS)
|
||||
|
||||
ifeq ($(filter __ICC,$(CCDEFS)),__ICC)
|
||||
CCTYPE := icc
|
||||
else
|
||||
ifeq ($(filter __GNUC__,$(CCDEFS)),__GNUC__)
|
||||
CCTYPE := gcc
|
||||
endif
|
||||
cctype:
|
||||
@ -374,6 +372,43 @@ INCDIRS += arch/$(ARCH)/include
|
||||
INCDIRS += arch/$(ARCH)/include/$(PLATFORM)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Especially ugly workarounds
|
||||
|
||||
# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
|
||||
# default. Note that gcc will exit *successfully* if it fails to
|
||||
# recognise an option that starts with "no", so we have to test for
|
||||
# output on stderr instead of checking the exit status.
|
||||
#
|
||||
# Current versions of gcc require -no-pie; older versions require
|
||||
# -nopie. We therefore test for both.
|
||||
#
|
||||
# This workaround must be determined only after the
|
||||
# architecture-specific Makefile has been included, since some
|
||||
# platforms (e.g. bin-x86_64-efi) will explicitly require the use of
|
||||
# -fpie.
|
||||
#
|
||||
ifeq ($(filter -fpie,$(CFLAGS)),)
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
|
||||
PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
|
||||
WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Some widespread patched versions of gcc include -fcf-protection=full
|
||||
# by default.
|
||||
#
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
CFP_TEST = $(CC) -fcf-protection=none -x c -c /dev/null -o /dev/null \
|
||||
>/dev/null 2>&1
|
||||
CFP_FLAGS := $(shell $(CFP_TEST) && $(ECHO) '-fcf-protection=none')
|
||||
WORKAROUND_CFLAGS += $(CFP_FLAGS)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Source file handling
|
||||
@ -429,32 +464,6 @@ CFLAGS += -fcommon
|
||||
CFLAGS += -Wall -W -Wformat-nonliteral
|
||||
HOST_CFLAGS += -Wall -W -Wformat-nonliteral
|
||||
endif
|
||||
ifeq ($(CCTYPE),icc)
|
||||
CFLAGS += -fno-builtin
|
||||
CFLAGS += -no-ip
|
||||
CFLAGS += -no-gcc
|
||||
CFLAGS += -diag-disable 111 # Unreachable code
|
||||
CFLAGS += -diag-disable 128 # Unreachable loop
|
||||
CFLAGS += -diag-disable 170 # Array boundary checks
|
||||
CFLAGS += -diag-disable 177 # Unused functions
|
||||
CFLAGS += -diag-disable 181 # printf() format checks
|
||||
CFLAGS += -diag-disable 188 # enum strictness
|
||||
CFLAGS += -diag-disable 193 # Undefined preprocessor identifiers
|
||||
CFLAGS += -diag-disable 280 # switch ( constant )
|
||||
CFLAGS += -diag-disable 310 # K&R parameter lists
|
||||
CFLAGS += -diag-disable 424 # Extra semicolon
|
||||
CFLAGS += -diag-disable 589 # Declarations mid-code
|
||||
CFLAGS += -diag-disable 593 # Unused variables
|
||||
CFLAGS += -diag-disable 810 # Casting ints to smaller ints
|
||||
CFLAGS += -diag-disable 981 # Sequence point violations
|
||||
CFLAGS += -diag-disable 1292 # Ignored attributes
|
||||
CFLAGS += -diag-disable 1338 # void pointer arithmetic
|
||||
CFLAGS += -diag-disable 1361 # Variable-length arrays
|
||||
CFLAGS += -diag-disable 1418 # Missing prototypes
|
||||
CFLAGS += -diag-disable 1419 # Missing prototypes
|
||||
CFLAGS += -diag-disable 1599 # Hidden variables
|
||||
CFLAGS += -Wall -Wmissing-declarations
|
||||
endif
|
||||
CFLAGS += $(WORKAROUND_CFLAGS) $(EXTRA_CFLAGS)
|
||||
ASFLAGS += $(WORKAROUND_ASFLAGS) $(EXTRA_ASFLAGS)
|
||||
LDFLAGS += $(WORKAROUND_LDFLAGS) $(EXTRA_LDFLAGS)
|
||||
@ -468,35 +477,6 @@ ASFLAGS += --fatal-warnings
|
||||
HOST_CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
# Function trace recorder state in the last build. This is needed
|
||||
# in order to correctly rebuild whenever the function recorder is
|
||||
# enabled/disabled.
|
||||
#
|
||||
FNREC_STATE := $(BIN)/.fnrec.state
|
||||
ifeq ($(wildcard $(FNREC_STATE)),)
|
||||
FNREC_OLD := <invalid>
|
||||
else
|
||||
FNREC_OLD := $(shell cat $(FNREC_STATE))
|
||||
endif
|
||||
ifeq ($(FNREC_OLD),$(FNREC))
|
||||
$(FNREC_STATE) :
|
||||
else
|
||||
$(FNREC_STATE) : clean
|
||||
$(shell $(ECHO) "$(FNREC)" > $(FNREC_STATE))
|
||||
endif
|
||||
|
||||
VERYCLEANUP += $(FNREC_STATE)
|
||||
MAKEDEPS += $(FNREC_STATE)
|
||||
|
||||
ifeq ($(FNREC),1)
|
||||
# Enabling -finstrument-functions affects gcc's analysis and leads to spurious
|
||||
# warnings about use of uninitialised variables.
|
||||
#
|
||||
CFLAGS += -Wno-uninitialized
|
||||
CFLAGS += -finstrument-functions
|
||||
CFLAGS += -finstrument-functions-exclude-file-list=core/fnrec.c
|
||||
endif
|
||||
|
||||
# Enable per-item sections and section garbage collection. Note that
|
||||
# some older versions of gcc support -fdata-sections but treat it as
|
||||
# implying -fno-common, which would break our build. Some other older
|
||||
@ -547,16 +527,6 @@ OBJ_CFLAGS = $(CFLAGS_$(OBJECT)) -DOBJECT=$(subst -,_,$(OBJECT))
|
||||
$(BIN)/%.flags :
|
||||
@$(ECHO) $(OBJ_CFLAGS)
|
||||
|
||||
# ICC requires postprocessing objects to fix up table alignments
|
||||
#
|
||||
ifeq ($(CCTYPE),icc)
|
||||
POST_O = && $(ICCFIX) $@
|
||||
POST_O_DEPS := $(ICCFIX)
|
||||
else
|
||||
POST_O :=
|
||||
POST_O_DEPS :=
|
||||
endif
|
||||
|
||||
# Debug level calculations
|
||||
#
|
||||
DBGLVL_MAX = -DDBGLVL_MAX=$(firstword $(subst ., ,$(1)))
|
||||
@ -566,9 +536,9 @@ DBGLVL = $(call DBGLVL_MAX,$(1)) $(call DBGLVL_DFLT,$(1))
|
||||
# Rules for specific object types.
|
||||
#
|
||||
COMPILE_c = $(CC) $(CFLAGS) $(CFLAGS_c) $(OBJ_CFLAGS)
|
||||
RULE_c = $(Q)$(COMPILE_c) -c $< -o $@ $(POST_O)
|
||||
RULE_c = $(Q)$(COMPILE_c) -c $< -o $@
|
||||
RULE_c_to_ids.o = $(Q)$(ECHO_E) '$(OBJ_IDS_ASM_NL)' | $(ASSEMBLE_S) -o $@
|
||||
RULE_c_to_dbg%.o= $(Q)$(COMPILE_c) $(call DBGLVL,$*) -c $< -o $@ $(POST_O)
|
||||
RULE_c_to_dbg%.o= $(Q)$(COMPILE_c) $(call DBGLVL,$*) -c $< -o $@
|
||||
RULE_c_to_c = $(Q)$(COMPILE_c) -E -c $< > $@
|
||||
RULE_c_to_s = $(Q)$(COMPILE_c) -S -g0 -c $< -o $@
|
||||
|
||||
@ -808,6 +778,38 @@ include/ipxe/profile.h : $(PROFILE_LIST)
|
||||
|
||||
.PRECIOUS : include/ipxe/profile.h
|
||||
|
||||
# (Single-element) list of function recorder configuration
|
||||
#
|
||||
FNREC_LIST := $(BIN)/.fnrec.list
|
||||
ifeq ($(wildcard $(FNREC_LIST)),)
|
||||
FNREC_OLD := <invalid>
|
||||
else
|
||||
FNREC_OLD := $(shell cat $(FNREC_LIST))
|
||||
endif
|
||||
ifneq ($(FNREC_OLD),$(FNREC))
|
||||
$(shell $(ECHO) "$(FNREC)" > $(FNREC_LIST))
|
||||
endif
|
||||
|
||||
$(FNREC_LIST) : $(MAKEDEPS)
|
||||
|
||||
VERYCLEANUP += $(FNREC_LIST)
|
||||
|
||||
# Function recorder configuration
|
||||
#
|
||||
ifeq ($(FNREC),1)
|
||||
# Enabling -finstrument-functions affects gcc's analysis and leads to spurious
|
||||
# warnings about use of uninitialised variables.
|
||||
#
|
||||
CFLAGS += -Wno-uninitialized
|
||||
CFLAGS += -finstrument-functions
|
||||
CFLAGS += -finstrument-functions-exclude-file-list=core/fnrec.c
|
||||
endif
|
||||
|
||||
include/compiler.h : $(FNREC_LIST)
|
||||
$(Q)$(TOUCH) $@
|
||||
|
||||
.PRECIOUS : include/compiler.h
|
||||
|
||||
# These files use .incbin inline assembly to include a binary file.
|
||||
# Unfortunately ccache does not detect this dependency and caches
|
||||
# builds even when the binary file has changed.
|
||||
@ -879,7 +881,7 @@ endef
|
||||
# $(3) is the source base name (e.g. "rtl8139")
|
||||
#
|
||||
define rules_template_parts
|
||||
$$(BIN)/$(3).o : $(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(3)_DEPS)
|
||||
$$(BIN)/$(3).o : $(1) $$(MAKEDEPS) $$($(3)_DEPS)
|
||||
$$(QM)$(ECHO) " [BUILD] $$@"
|
||||
$$(RULE_$(2))
|
||||
BOBJS += $$(BIN)/$(3).o
|
||||
@ -894,7 +896,7 @@ endef
|
||||
# $(4) is the destination type (e.g. "dbg%.o")
|
||||
#
|
||||
define rules_template_target
|
||||
$$(BIN)/$(3).$(4) : $(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(3)_DEPS)
|
||||
$$(BIN)/$(3).$(4) : $(1) $$(MAKEDEPS) $$($(3)_DEPS)
|
||||
$$(QM)$(ECHO) " [BUILD] $$@"
|
||||
$$(RULE_$(2)_to_$(4))
|
||||
$(TGT)_OBJS += $$(BIN)/$(3).$(4)
|
||||
@ -1433,15 +1435,6 @@ $(EFIFATBIN) : util/efifatbin.c $(MAKEDEPS)
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(EFIFATBIN)
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# The ICC fixup utility
|
||||
#
|
||||
$(ICCFIX) : util/iccfix.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(ICCFIX)
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# The error usage information utility
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Avoid untranslatable relocations
|
||||
#
|
||||
CFLAGS += -fno-pic
|
||||
|
||||
# Specify EFI image builder
|
||||
#
|
||||
ELF2EFI = $(ELF2EFI64)
|
||||
|
||||
@ -69,22 +69,6 @@ CFLAGS += -fshort-wchar
|
||||
#
|
||||
CFLAGS += -Ui386
|
||||
|
||||
# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
|
||||
# default. Note that gcc will exit *successfully* if it fails to
|
||||
# recognise an option that starts with "no", so we have to test for
|
||||
# output on stderr instead of checking the exit status.
|
||||
#
|
||||
# Current versions of gcc require -no-pie; older versions require
|
||||
# -nopie. We therefore test for both.
|
||||
#
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
|
||||
PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
|
||||
WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
|
||||
endif
|
||||
|
||||
# i386-specific directories containing source files
|
||||
#
|
||||
SRCDIRS += arch/i386/core
|
||||
|
||||
@ -4,18 +4,15 @@
|
||||
#
|
||||
SRCDIRS += arch/x86/drivers/net
|
||||
|
||||
# The i386 linker script
|
||||
# The linker scripts
|
||||
#
|
||||
LDSCRIPT = arch/x86/scripts/pcbios.lds
|
||||
LDSCRIPT_PREFIX = arch/x86/scripts/prefixonly.lds
|
||||
|
||||
# Stop ld from complaining about our customised linker script
|
||||
#
|
||||
LDFLAGS += -N --no-check-sections
|
||||
|
||||
# Prefix always starts at address zero
|
||||
#
|
||||
LDFLAGS += --section-start=.prefix=0
|
||||
|
||||
# Media types.
|
||||
#
|
||||
MEDIA += rom
|
||||
@ -73,12 +70,12 @@ NON_AUTO_MEDIA += fd0
|
||||
# Special target for building Master Boot Record binary
|
||||
$(BIN)/mbr.tmp : $(BIN)/mbr.o
|
||||
$(QM)$(ECHO) " [LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
|
||||
$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
|
||||
|
||||
# rule to make a USB disk image
|
||||
$(BIN)/usbdisk.tmp : $(BIN)/usbdisk.o
|
||||
$(QM)$(ECHO) " [LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
|
||||
$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
|
||||
|
||||
NON_AUTO_MEDIA += usb
|
||||
%usb: $(BIN)/usbdisk.bin %hd
|
||||
|
||||
@ -13,7 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".stack", "aw", @nobits
|
||||
.align 8
|
||||
.balign 8
|
||||
.globl _stack
|
||||
_stack:
|
||||
.space STACK_SIZE
|
||||
|
||||
@ -7,7 +7,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".stack16", "aw", @nobits
|
||||
.align 8
|
||||
.balign 8
|
||||
.globl _stack16
|
||||
_stack16:
|
||||
.space 4096
|
||||
|
||||
@ -175,18 +175,18 @@ static int initrd_swap_any ( userptr_t free, size_t free_len ) {
|
||||
/* Search for adjacent image */
|
||||
for_each_image ( high ) {
|
||||
|
||||
/* If we have found the adjacent image, swap and exit */
|
||||
if ( high->data == adjacent ) {
|
||||
initrd_swap ( low, high, free, free_len );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Stop search if all remaining potential
|
||||
* adjacent images are already in the correct
|
||||
* order.
|
||||
*/
|
||||
if ( high == low )
|
||||
break;
|
||||
|
||||
/* If we have found the adjacent image, swap and exit */
|
||||
if ( high->data == adjacent ) {
|
||||
initrd_swap ( low, high, free, free_len );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,6 +42,9 @@ struct x86_features {
|
||||
/** Hypervisor is present */
|
||||
#define CPUID_FEATURES_INTEL_ECX_HYPERVISOR 0x80000000UL
|
||||
|
||||
/** FXSAVE and FXRSTOR are supported */
|
||||
#define CPUID_FEATURES_INTEL_EDX_FXSR 0x01000000UL
|
||||
|
||||
/** Get largest extended function */
|
||||
#define CPUID_AMD_MAX_FN 0x80000000UL
|
||||
|
||||
|
||||
76
src/arch/x86/interface/pcbios/bios_cachedhcp.c
Normal file
76
src/arch/x86/interface/pcbios/bios_cachedhcp.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/cachedhcp.h>
|
||||
#include <realmode.h>
|
||||
#include <pxe_api.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Cached DHCP packet
|
||||
*
|
||||
*/
|
||||
|
||||
/** Cached DHCPACK physical address
|
||||
*
|
||||
* This can be set by the prefix.
|
||||
*/
|
||||
uint32_t __bss16 ( cached_dhcpack_phys );
|
||||
#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &cached_dhcpack_phys
|
||||
|
||||
/**
|
||||
* Cached DHCPACK initialisation function
|
||||
*
|
||||
*/
|
||||
static void cachedhcp_init ( void ) {
|
||||
int rc;
|
||||
|
||||
/* Do nothing if no cached DHCPACK is present */
|
||||
if ( ! cached_dhcpack_phys ) {
|
||||
DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Record cached DHCPACK */
|
||||
if ( ( rc = cachedhcp_record ( phys_to_user ( cached_dhcpack_phys ),
|
||||
sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n",
|
||||
strerror ( rc ) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark as consumed */
|
||||
cached_dhcpack_phys = 0;
|
||||
}
|
||||
|
||||
/** Cached DHCPACK initialisation function */
|
||||
struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
|
||||
.initialise = cachedhcp_init,
|
||||
};
|
||||
@ -67,7 +67,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".data16", "aw", @progbits
|
||||
.align 16
|
||||
.balign 16
|
||||
.globl hidemem_base
|
||||
.globl hidemem_umalloc
|
||||
.globl hidemem_textdata
|
||||
|
||||
@ -34,7 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
*/
|
||||
.section ".text16.data", "aw", @progbits
|
||||
.globl ppxe
|
||||
.align 16
|
||||
.balign 16
|
||||
ppxe:
|
||||
.ascii "!PXE" /* Signature */
|
||||
.byte pxe_length /* StructLength */
|
||||
@ -72,7 +72,7 @@ undiheader:
|
||||
*/
|
||||
.section ".text16.data", "aw", @progbits
|
||||
.globl pxenv
|
||||
.align 16
|
||||
.balign 16
|
||||
pxenv:
|
||||
.ascii "PXENV+" /* Signature */
|
||||
.word 0x0201 /* Version */
|
||||
|
||||
@ -110,7 +110,7 @@ overlay:
|
||||
/* Overlay number */
|
||||
.word 0
|
||||
|
||||
.align 16, 0
|
||||
.balign 16, 0
|
||||
|
||||
.globl _exe_start
|
||||
_exe_start:
|
||||
|
||||
@ -492,7 +492,7 @@ mromheader:
|
||||
.word 0
|
||||
.size mromheader, . - mromheader
|
||||
|
||||
.align 4
|
||||
.balign 4
|
||||
mpciheader:
|
||||
.ascii "PCIR" /* Signature */
|
||||
.word pci_vendor_id /* Vendor identification */
|
||||
|
||||
53
src/arch/x86/prefix/rawprefix.S
Normal file
53
src/arch/x86/prefix/rawprefix.S
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Raw binary prefix
|
||||
*
|
||||
* Assumes that entire image is already loaded as a contiguous block
|
||||
* on a paragraph boundary and entered in real mode.
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.text
|
||||
.arch i386
|
||||
.org 0
|
||||
.code16
|
||||
|
||||
#include <librm.h>
|
||||
|
||||
.section ".prefix", "ax", @progbits
|
||||
.globl _raw_start
|
||||
_raw_start:
|
||||
|
||||
/* Adjust %cs so that %cs:0000 is the start of the image */
|
||||
movw %cs, %ax
|
||||
call 1f
|
||||
1: popw %bx
|
||||
subw $1b, %bx
|
||||
shrw $4, %bx
|
||||
addw %bx, %ax
|
||||
pushw %ax
|
||||
pushw $2f
|
||||
lret
|
||||
2:
|
||||
/* Install iPXE */
|
||||
call install
|
||||
|
||||
/* Set up real-mode stack */
|
||||
movw %bx, %ss
|
||||
movw $_estack16, %sp
|
||||
|
||||
/* Jump to .text16 segment */
|
||||
pushw %ax
|
||||
pushw $1f
|
||||
lret
|
||||
.section ".text16", "awx", @progbits
|
||||
1:
|
||||
/* Run iPXE */
|
||||
virtcall main
|
||||
|
||||
/* Uninstall iPXE */
|
||||
call uninstall
|
||||
|
||||
/* Boot next device */
|
||||
int $0x18
|
||||
@ -88,7 +88,7 @@ checksum:
|
||||
.previous
|
||||
|
||||
.ifeqs BUSTYPE, "PCIR"
|
||||
.align 4
|
||||
.balign 4
|
||||
pciheader:
|
||||
.ascii "PCIR" /* Signature */
|
||||
.word pci_vendor_id /* Vendor identification */
|
||||
@ -136,7 +136,7 @@ pci_devlist_end:
|
||||
* BIOSes will scan on 16-byte boundaries rather than using
|
||||
* the offset stored at 0x1a
|
||||
*/
|
||||
.align 16
|
||||
.balign 16
|
||||
pnpheader:
|
||||
.ascii "$PnP" /* Signature */
|
||||
.byte 0x01 /* Structure revision */
|
||||
@ -184,7 +184,7 @@ prodstr_pci_id:
|
||||
|
||||
.globl undiheader
|
||||
.weak undiloader
|
||||
.align 4
|
||||
.balign 4
|
||||
undiheader:
|
||||
.ascii "UNDI" /* Signature */
|
||||
.byte undiheader_len /* Length of structure */
|
||||
@ -199,7 +199,7 @@ undiheader:
|
||||
.equ undiheader_len, . - undiheader
|
||||
.size undiheader, . - undiheader
|
||||
|
||||
.align 4
|
||||
.balign 4
|
||||
ipxeheader:
|
||||
.ascii "iPXE" /* Signature */
|
||||
.byte ipxeheader_len /* Length of structure */
|
||||
|
||||
@ -231,7 +231,7 @@ rep_len_dec: .space sizeof__lzma_len_dec
|
||||
literal: .rept ( ( 1 << LZMA_LC ) * 0x300 )
|
||||
.word 0
|
||||
.endr
|
||||
.align 4
|
||||
.balign 4
|
||||
.equ sizeof__lzma_dec, . - lzma_dec
|
||||
.previous
|
||||
|
||||
|
||||
29
src/arch/x86/scripts/prefixonly.lds
Normal file
29
src/arch/x86/scripts/prefixonly.lds
Normal file
@ -0,0 +1,29 @@
|
||||
/* -*- ld-script -*- */
|
||||
|
||||
/*
|
||||
* Linker script for prefix-only binaries (e.g. USB disk MBR)
|
||||
*
|
||||
*/
|
||||
|
||||
SECTIONS {
|
||||
|
||||
.prefix 0x0 : AT ( 0x0 ) {
|
||||
*(.prefix)
|
||||
}
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.comment.*)
|
||||
*(.note)
|
||||
*(.note.*)
|
||||
*(.eh_frame)
|
||||
*(.eh_frame.*)
|
||||
*(.rel)
|
||||
*(.rel.*)
|
||||
*(.einfo)
|
||||
*(.einfo.*)
|
||||
*(.discard)
|
||||
*(.discard.*)
|
||||
}
|
||||
|
||||
}
|
||||
@ -285,7 +285,7 @@ enable_a20:
|
||||
ret
|
||||
|
||||
.section ".text16.early.data", "aw", @progbits
|
||||
.align 2
|
||||
.balign 2
|
||||
enable_a20_method:
|
||||
.word 0
|
||||
.size enable_a20_method, . - enable_a20_method
|
||||
|
||||
@ -99,7 +99,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".data16.gdt", "aw", @progbits
|
||||
.align 16
|
||||
.balign 16
|
||||
gdt:
|
||||
gdtr: /* The first GDT entry is unused, the GDTR can fit here. */
|
||||
gdt_limit: .word gdt_length - 1
|
||||
@ -210,9 +210,7 @@ VC_TMP_CR3: .space 4
|
||||
VC_TMP_CR4: .space 4
|
||||
VC_TMP_EMER: .space 8
|
||||
.endif
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
VC_TMP_FXSAVE: .space 512
|
||||
#endif
|
||||
VC_TMP_END:
|
||||
.previous
|
||||
|
||||
@ -224,7 +222,7 @@ RC_TMP_END:
|
||||
|
||||
/* Shared temporary static buffer */
|
||||
.section ".bss16.rm_tmpbuf", "aw", @nobits
|
||||
.align 16
|
||||
.balign 16
|
||||
rm_tmpbuf:
|
||||
.space VC_TMP_END
|
||||
.size rm_tmpbuf, . - rm_tmpbuf
|
||||
@ -350,6 +348,13 @@ init_librm_rmode:
|
||||
/* Initialise IDT */
|
||||
virtcall init_idt
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Check for FXSAVE/FXRSTOR */
|
||||
clc
|
||||
virtcall check_fxsr
|
||||
setnc fxsr_supported
|
||||
#endif
|
||||
|
||||
/* Restore registers */
|
||||
popl %edi
|
||||
popl %ebx
|
||||
@ -366,6 +371,10 @@ set_seg_base:
|
||||
roll $16, %eax
|
||||
ret
|
||||
|
||||
.section ".data16.fxsr_supported", "awx", @progbits
|
||||
fxsr_supported: /* FXSAVE/FXRSTOR instructions supported */
|
||||
.byte 0
|
||||
|
||||
/****************************************************************************
|
||||
* real_to_prot (real-mode near call, 32-bit virtual return address)
|
||||
*
|
||||
@ -1007,10 +1016,11 @@ virt_call:
|
||||
cli
|
||||
movw %cs:rm_ds, %ds
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Preserve FPU, MMX and SSE state in temporary static buffer */
|
||||
testb $0xff, fxsr_supported
|
||||
jz 1f
|
||||
fxsave ( rm_tmpbuf + VC_TMP_FXSAVE )
|
||||
#endif
|
||||
1:
|
||||
/* Preserve GDT and IDT in temporary static buffer */
|
||||
sidt ( rm_tmpbuf + VC_TMP_IDT )
|
||||
sgdt ( rm_tmpbuf + VC_TMP_GDT )
|
||||
@ -1077,10 +1087,11 @@ vc_rmode:
|
||||
wrmsr
|
||||
.endif
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Restore FPU, MMX and SSE state from temporary static buffer */
|
||||
testb $0xff, fxsr_supported
|
||||
jz 1f
|
||||
fxrstor ( rm_tmpbuf + VC_TMP_FXSAVE )
|
||||
#endif
|
||||
1:
|
||||
/* Restore registers and flags and return */
|
||||
popl %eax /* skip %cs and %ss */
|
||||
popw %ds
|
||||
@ -1470,7 +1481,7 @@ interrupt_wrapper:
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".pages", "aw", @nobits
|
||||
.align SIZEOF_PT
|
||||
.balign SIZEOF_PT
|
||||
|
||||
/* Page map level 4 entries (PML4Es)
|
||||
*
|
||||
|
||||
@ -14,6 +14,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <realmode.h>
|
||||
#include <pic8259.h>
|
||||
#include <ipxe/shell.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
|
||||
/*
|
||||
* This file provides functions for managing librm.
|
||||
@ -118,7 +119,7 @@ void set_interrupt_vector ( unsigned int intr, void *vector ) {
|
||||
* Initialise interrupt descriptor table
|
||||
*
|
||||
*/
|
||||
void init_idt ( void ) {
|
||||
__asmcall void init_idt ( void ) {
|
||||
struct interrupt_vector *vec;
|
||||
unsigned int intr;
|
||||
|
||||
@ -386,6 +387,21 @@ static void iounmap_pages ( volatile const void *io_addr ) {
|
||||
io_addr, first, i );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for FXSAVE/FXRSTOR instruction support
|
||||
*
|
||||
*/
|
||||
__asmcall void check_fxsr ( struct i386_all_regs *regs ) {
|
||||
struct x86_features features;
|
||||
|
||||
/* Check for FXSR bit */
|
||||
x86_features ( &features );
|
||||
if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_FXSR ) )
|
||||
regs->flags |= CF;
|
||||
DBGC ( &features, "FXSAVE/FXRSTOR is%s supported\n",
|
||||
( ( regs->flags & CF ) ? " not" : "" ) );
|
||||
}
|
||||
|
||||
PROVIDE_UACCESS_INLINE ( librm, phys_to_user );
|
||||
PROVIDE_UACCESS_INLINE ( librm, user_to_phys );
|
||||
PROVIDE_UACCESS_INLINE ( librm, virt_to_user );
|
||||
|
||||
@ -18,8 +18,13 @@
|
||||
* Note that the serial port output from an AWS EC2 virtual machine is
|
||||
* generally available (as the "System Log") only after the instance
|
||||
* has been stopped.
|
||||
*
|
||||
* Enable only for non-EFI builds, on the assumption that the standard
|
||||
* EFI firmware is likely to already be logging to the serial port.
|
||||
*/
|
||||
#ifndef PLATFORM_efi
|
||||
#define CONSOLE_SERIAL
|
||||
#endif
|
||||
|
||||
/* Log to partition on local disk
|
||||
*
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
/* Enable IPv6 and HTTPS */
|
||||
#define NET_PROTO_IPV6
|
||||
#define DOWNLOAD_PROTO_HTTPS
|
||||
|
||||
/* Allow retrieval of metadata (such as an iPXE boot script) from
|
||||
* Google Compute Engine metadata server.
|
||||
*/
|
||||
|
||||
7
src/config/cloud/ioapi.h
Normal file
7
src/config/cloud/ioapi.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* Work around missing PCI BIOS calls in the cut-down SeaBIOS found in
|
||||
* some AWS EC2 instances.
|
||||
*/
|
||||
#ifdef PLATFORM_pcbios
|
||||
#undef PCIAPI_PCBIOS
|
||||
#define PCIAPI_DIRECT
|
||||
#endif
|
||||
@ -14,6 +14,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
//#undef PCIAPI_PCBIOS /* Access via PCI BIOS */
|
||||
//#define PCIAPI_DIRECT /* Direct access via Type 1 accesses */
|
||||
|
||||
#include <config/named.h>
|
||||
#include NAMED_CONFIG(ioapi.h)
|
||||
#include <config/local/ioapi.h>
|
||||
#include LOCAL_NAMED_CONFIG(ioapi.h)
|
||||
|
||||
#endif /* CONFIG_IOAPI_H */
|
||||
|
||||
0
src/config/qemu/ioapi.h
Normal file
0
src/config/qemu/ioapi.h
Normal file
0
src/config/rpi/ioapi.h
Normal file
0
src/config/rpi/ioapi.h
Normal file
0
src/config/vbox/ioapi.h
Normal file
0
src/config/vbox/ioapi.h
Normal file
@ -25,11 +25,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/dhcppkt.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
#include <realmode.h>
|
||||
#include <pxe_api.h>
|
||||
#include <ipxe/cachedhcp.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
@ -37,50 +37,33 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
|
||||
/** Cached DHCPACK physical address
|
||||
*
|
||||
* This can be set by the prefix.
|
||||
*/
|
||||
uint32_t __bss16 ( cached_dhcpack_phys );
|
||||
#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &cached_dhcpack_phys
|
||||
|
||||
/** Cached DHCPACK */
|
||||
static struct dhcp_packet *cached_dhcpack;
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &cached_dhcpack
|
||||
|
||||
/**
|
||||
* Cached DHCPACK startup function
|
||||
* Record cached DHCPACK
|
||||
*
|
||||
* @v data DHCPACK packet buffer
|
||||
* @v max_len Maximum possible length
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static void cachedhcp_init ( void ) {
|
||||
int cachedhcp_record ( userptr_t data, size_t max_len ) {
|
||||
struct dhcp_packet *dhcppkt;
|
||||
struct dhcp_packet *tmp;
|
||||
struct dhcphdr *dhcphdr;
|
||||
size_t max_len;
|
||||
size_t len;
|
||||
|
||||
/* Do nothing if no cached DHCPACK is present */
|
||||
if ( ! cached_dhcpack_phys ) {
|
||||
DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* No reliable way to determine length before parsing packet;
|
||||
* start by assuming maximum length permitted by PXE.
|
||||
*/
|
||||
max_len = sizeof ( BOOTPLAYER_t );
|
||||
|
||||
/* Allocate and populate DHCP packet */
|
||||
dhcppkt = zalloc ( sizeof ( *dhcppkt ) + max_len );
|
||||
if ( ! dhcppkt ) {
|
||||
DBGC ( colour, "CACHEDHCP could not allocate copy\n" );
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
|
||||
copy_from_user ( dhcphdr, phys_to_user ( cached_dhcpack_phys ), 0,
|
||||
max_len );
|
||||
copy_from_user ( dhcphdr, data, 0, max_len );
|
||||
dhcppkt_init ( dhcppkt, dhcphdr, max_len );
|
||||
|
||||
/* Shrink packet to required length. If reallocation fails,
|
||||
@ -98,10 +81,11 @@ static void cachedhcp_init ( void ) {
|
||||
dhcppkt_init ( dhcppkt, dhcphdr, len );
|
||||
|
||||
/* Store as cached DHCPACK, and mark original copy as consumed */
|
||||
DBGC ( colour, "CACHEDHCP found cached DHCPACK at %08x+%zx\n",
|
||||
cached_dhcpack_phys, len );
|
||||
DBGC ( colour, "CACHEDHCP found cached DHCPACK at %#08lx+%#zx/%#zx\n",
|
||||
user_to_phys ( data, 0 ), len, max_len );
|
||||
cached_dhcpack = dhcppkt;
|
||||
cached_dhcpack_phys = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,11 +104,6 @@ static void cachedhcp_startup ( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Cached DHCPACK initialisation function */
|
||||
struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
|
||||
.initialise = cachedhcp_init,
|
||||
};
|
||||
|
||||
/** Cached DHCPACK startup function */
|
||||
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
|
||||
.name = "cachedhcp",
|
||||
@ -823,6 +823,11 @@ hermon_dump_cqctx ( struct hermon *hermon, struct ib_completion_queue *cq ) {
|
||||
struct hermonprm_completion_queue_context cqctx;
|
||||
int rc;
|
||||
|
||||
/* Do nothing unless debugging is enabled */
|
||||
if ( ! DBG_LOG )
|
||||
return 0;
|
||||
|
||||
/* Dump completion queue context */
|
||||
memset ( &cqctx, 0, sizeof ( cqctx ) );
|
||||
if ( ( rc = hermon_cmd_query_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) {
|
||||
DBGC ( hermon, "Hermon %p CQN %#lx QUERY_CQ failed: %s\n",
|
||||
@ -1099,16 +1104,30 @@ static uint8_t hermon_qp_st[] = {
|
||||
*/
|
||||
static __attribute__ (( unused )) int
|
||||
hermon_dump_qpctx ( struct hermon *hermon, struct ib_queue_pair *qp ) {
|
||||
struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
|
||||
struct hermonprm_qp_ee_state_transitions qpctx;
|
||||
unsigned int state;
|
||||
int rc;
|
||||
|
||||
/* Do nothing unless debugging is enabled */
|
||||
if ( ! DBG_LOG )
|
||||
return 0;
|
||||
|
||||
/* Dump queue pair context */
|
||||
memset ( &qpctx, 0, sizeof ( qpctx ) );
|
||||
if ( ( rc = hermon_cmd_query_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ) {
|
||||
DBGC ( hermon, "Hermon %p QPN %#lx QUERY_QP failed: %s\n",
|
||||
hermon, qp->qpn, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
DBGC ( hermon, "Hermon %p QPN %#lx context:\n", hermon, qp->qpn );
|
||||
state = MLX_GET ( &qpctx, qpc_eec_data.state );
|
||||
if ( state != hermon_qp->state ) {
|
||||
DBGC ( hermon, "Hermon %p QPN %#lx state %d unexpected "
|
||||
"(should be %d)\n",
|
||||
hermon, qp->qpn, state, hermon_qp->state );
|
||||
}
|
||||
DBGC ( hermon, "Hermon %p QPN %#lx state %d context:\n",
|
||||
hermon, qp->qpn, state );
|
||||
DBGC_HDA ( hermon, 0, &qpctx.u.dwords[2], ( sizeof ( qpctx ) - 8 ) );
|
||||
|
||||
return 0;
|
||||
@ -1789,6 +1808,11 @@ static int hermon_complete ( struct ib_device *ibdev,
|
||||
if ( is_send ) {
|
||||
/* Hand off to completion handler */
|
||||
ib_complete_send ( ibdev, qp, iobuf, rc );
|
||||
} else if ( rc != 0 ) {
|
||||
/* Dump queue state (for debugging) */
|
||||
hermon_dump_qpctx ( hermon, qp );
|
||||
/* Hand off to completion handler */
|
||||
ib_complete_recv ( ibdev, qp, NULL, NULL, iobuf, rc );
|
||||
} else {
|
||||
/* Set received length */
|
||||
len = MLX_GET ( &cqe->normal, byte_cnt );
|
||||
@ -1831,7 +1855,7 @@ static int hermon_complete ( struct ib_device *ibdev,
|
||||
assert ( len <= iob_tailroom ( iobuf ) );
|
||||
iob_put ( iobuf, len );
|
||||
/* Hand off to completion handler */
|
||||
ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, rc );
|
||||
ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, 0 );
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -1898,6 +1922,11 @@ hermon_dump_eqctx ( struct hermon *hermon,
|
||||
struct hermonprm_eqc eqctx;
|
||||
int rc;
|
||||
|
||||
/* Do nothing unless debugging is enabled */
|
||||
if ( ! DBG_LOG )
|
||||
return 0;
|
||||
|
||||
/* Dump event queue context */
|
||||
memset ( &eqctx, 0, sizeof ( eqctx ) );
|
||||
if ( ( rc = hermon_cmd_query_eq ( hermon, hermon_eq->eqn,
|
||||
&eqctx ) ) != 0 ) {
|
||||
@ -1930,6 +1959,11 @@ hermon_dump_eqes ( struct hermon *hermon,
|
||||
unsigned int idx;
|
||||
int rc;
|
||||
|
||||
/* Do nothing unless debugging is enabled */
|
||||
if ( ! DBG_LOG )
|
||||
return 0;
|
||||
|
||||
/* Dump event queue entries */
|
||||
memset ( &eqctx, 0, sizeof ( eqctx ) );
|
||||
if ( ( rc = hermon_cmd_query_eq ( hermon, hermon_eq->eqn,
|
||||
&eqctx ) ) != 0 ) {
|
||||
@ -4198,6 +4232,10 @@ static struct pci_device_id hermon_nics[] = {
|
||||
PCI_ROM ( 0x15b3, 0x675a, "mt26458", "MT26458 HCA driver", 0 ),
|
||||
PCI_ROM ( 0x15b3, 0x6764, "mt26468", "MT26468 HCA driver", 0 ),
|
||||
PCI_ROM ( 0x15b3, 0x676e, "mt26478", "MT26478 HCA driver", 0 ),
|
||||
|
||||
/* Mellanox ConnectX-3 VPI (ethernet + infiniband) */
|
||||
PCI_ROM ( 0x15b3, 0x1003, "mt4099", "ConnectX-3 HCA driver", 0 ),
|
||||
PCI_ROM ( 0x15b3, 0x1007, "mt4103", "ConnectX-3 Pro HCA driver", 0 ),
|
||||
};
|
||||
|
||||
struct pci_driver hermon_driver __pci_driver = {
|
||||
|
||||
@ -416,6 +416,7 @@ ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
|
||||
if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
|
||||
return 0;
|
||||
|
||||
AR5K_EEPROM_READ(o++, val);
|
||||
switch (mode){
|
||||
case AR5K_EEPROM_MODE_11A:
|
||||
ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
|
||||
|
||||
@ -65,35 +65,59 @@ static const char * ena_direction ( unsigned int direction ) {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reset hardware
|
||||
* Wait for reset operation to be acknowledged
|
||||
*
|
||||
* @v ena ENA device
|
||||
* @v expected Expected reset state
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int ena_reset ( struct ena_nic *ena ) {
|
||||
static int ena_reset_wait ( struct ena_nic *ena, uint32_t expected ) {
|
||||
uint32_t stat;
|
||||
unsigned int i;
|
||||
|
||||
/* Trigger reset */
|
||||
writel ( ENA_CTRL_RESET, ( ena->regs + ENA_CTRL ) );
|
||||
|
||||
/* Wait for reset to complete */
|
||||
for ( i = 0 ; i < ENA_RESET_MAX_WAIT_MS ; i++ ) {
|
||||
|
||||
/* Check if device is ready */
|
||||
stat = readl ( ena->regs + ENA_STAT );
|
||||
if ( stat & ENA_STAT_READY )
|
||||
if ( ( stat & ENA_STAT_RESET ) == expected )
|
||||
return 0;
|
||||
|
||||
/* Delay */
|
||||
mdelay ( 1 );
|
||||
}
|
||||
|
||||
DBGC ( ena, "ENA %p timed out waiting for reset (status %#08x)\n",
|
||||
ena, stat );
|
||||
DBGC ( ena, "ENA %p timed out waiting for reset status %#08x "
|
||||
"(got %#08x)\n", ena, expected, stat );
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset hardware
|
||||
*
|
||||
* @v ena ENA device
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int ena_reset ( struct ena_nic *ena ) {
|
||||
int rc;
|
||||
|
||||
/* Trigger reset */
|
||||
writel ( ENA_CTRL_RESET, ( ena->regs + ENA_CTRL ) );
|
||||
|
||||
/* Wait for reset to take effect */
|
||||
if ( ( rc = ena_reset_wait ( ena, ENA_STAT_RESET ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Clear reset */
|
||||
writel ( 0, ( ena->regs + ENA_CTRL ) );
|
||||
|
||||
/* Wait for reset to clear */
|
||||
if ( ( rc = ena_reset_wait ( ena, 0 ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Admin queue
|
||||
|
||||
@ -66,7 +66,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Device status register */
|
||||
#define ENA_STAT 0x58
|
||||
#define ENA_STAT_READY 0x00000001UL /**< Ready */
|
||||
#define ENA_STAT_RESET 0x00000008UL /**< Reset in progress */
|
||||
|
||||
/** Admin queue entry header */
|
||||
struct ena_aq_header {
|
||||
|
||||
@ -259,7 +259,7 @@ static inline void eplatform_discard ( int dummy __unused, ... ) {}
|
||||
*/
|
||||
#define __einfo_error( einfo ) ( { \
|
||||
__asm__ ( ".section \".einfo\", \"\", " PROGBITS_OPS "\n\t" \
|
||||
".align 8\n\t" \
|
||||
".balign 8\n\t" \
|
||||
"\n1:\n\t" \
|
||||
".long ( 4f - 1b )\n\t" \
|
||||
".long %c0\n\t" \
|
||||
@ -268,7 +268,7 @@ static inline void eplatform_discard ( int dummy __unused, ... ) {}
|
||||
".long %c1\n\t" \
|
||||
"\n2:\t.asciz \"" __einfo_desc ( einfo ) "\"\n\t" \
|
||||
"\n3:\t.asciz \"" __FILE__ "\"\n\t" \
|
||||
".align 8\n\t" \
|
||||
".balign 8\n\t" \
|
||||
"\n4:\n\t" \
|
||||
".previous\n\t" : : \
|
||||
"i" ( __einfo_errno ( einfo ) ), \
|
||||
|
||||
17
src/include/ipxe/cachedhcp.h
Normal file
17
src/include/ipxe/cachedhcp.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _IPXE_CACHEDHCP_H
|
||||
#define _IPXE_CACHEDHCP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Cached DHCP packet
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ipxe/uaccess.h>
|
||||
|
||||
extern int cachedhcp_record ( userptr_t data, size_t max_len );
|
||||
|
||||
#endif /* _IPXE_CACHEDHCP_H */
|
||||
@ -29,11 +29,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
/* EFI headers redefine ARRAY_SIZE */
|
||||
#undef ARRAY_SIZE
|
||||
|
||||
/* EFI headers expect ICC to define __GNUC__ */
|
||||
#if defined ( __ICC ) && ! defined ( __GNUC__ )
|
||||
#define __GNUC__ 1
|
||||
#endif
|
||||
|
||||
/* EFI headers think your compiler uses the MS ABI by default on X64 */
|
||||
#if __x86_64__
|
||||
#define EFIAPI __attribute__((ms_abi))
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
extern void efi_set_autoboot ( void );
|
||||
#include <ipxe/efi/efi.h>
|
||||
|
||||
extern int efi_set_autoboot_ll_addr ( EFI_HANDLE device );
|
||||
|
||||
#endif /* _IPXE_EFI_AUTOBOOT_H */
|
||||
|
||||
16
src/include/ipxe/efi/efi_autoexec.h
Normal file
16
src/include/ipxe/efi/efi_autoexec.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _IPXE_EFI_AUTOEXEC_H
|
||||
#define _IPXE_EFI_AUTOEXEC_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI autoexec script
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/efi/efi.h>
|
||||
|
||||
extern int efi_autoexec_load ( EFI_HANDLE device );
|
||||
|
||||
#endif /* _IPXE_EFI_AUTOEXEC_H */
|
||||
16
src/include/ipxe/efi/efi_cachedhcp.h
Normal file
16
src/include/ipxe/efi/efi_cachedhcp.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _IPXE_EFI_CACHEDHCP_H
|
||||
#define _IPXE_EFI_CACHEDHCP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI cached DHCP packet
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/efi/efi.h>
|
||||
|
||||
extern int efi_cachedhcp_record ( EFI_HANDLE device );
|
||||
|
||||
#endif /* _IPXE_EFI_CACHEDHCP_H */
|
||||
@ -76,6 +76,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_dummy_sanboot ( ERRFILE_CORE | 0x00240000 )
|
||||
#define ERRFILE_fdt ( ERRFILE_CORE | 0x00250000 )
|
||||
#define ERRFILE_dma ( ERRFILE_CORE | 0x00260000 )
|
||||
#define ERRFILE_cachedhcp ( ERRFILE_CORE | 0x00270000 )
|
||||
|
||||
#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 )
|
||||
#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )
|
||||
@ -384,6 +385,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_ntlm ( ERRFILE_OTHER | 0x00510000 )
|
||||
#define ERRFILE_efi_veto ( ERRFILE_OTHER | 0x00520000 )
|
||||
#define ERRFILE_efi_autoboot ( ERRFILE_OTHER | 0x00530000 )
|
||||
#define ERRFILE_efi_autoexec ( ERRFILE_OTHER | 0x00540000 )
|
||||
#define ERRFILE_efi_cachedhcp ( ERRFILE_OTHER | 0x00550000 )
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@ -444,75 +444,4 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
pointer >= table_start ( table ) ; \
|
||||
pointer-- )
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Intel's C compiler chokes on several of the constructs used in this
|
||||
* file. The workarounds are ugly, so we use them only for an icc
|
||||
* build.
|
||||
*
|
||||
*/
|
||||
#define ICC_ALIGN_HACK_FACTOR 128
|
||||
#ifdef __ICC
|
||||
|
||||
/*
|
||||
* icc miscompiles zero-length arrays by inserting padding to a length
|
||||
* of two array elements. We therefore have to generate the
|
||||
* __table_entries() symbols by hand in asm.
|
||||
*
|
||||
*/
|
||||
#undef __table_entries
|
||||
#define __table_entries( table, idx ) ( { \
|
||||
extern __table_type ( table ) \
|
||||
__table_temp_sym ( idx, __LINE__ ) [] \
|
||||
__table_entry ( table, idx ) \
|
||||
asm ( __table_entries_sym ( table, idx ) ); \
|
||||
__asm__ ( ".ifndef %c0\n\t" \
|
||||
".section " __table_section ( table, idx ) "\n\t" \
|
||||
".align %c1\n\t" \
|
||||
"\n%c0:\n\t" \
|
||||
".previous\n\t" \
|
||||
".endif\n\t" \
|
||||
: : "i" ( __table_temp_sym ( idx, __LINE__ ) ), \
|
||||
"i" ( __table_alignment ( table ) ) ); \
|
||||
__table_temp_sym ( idx, __LINE__ ); } )
|
||||
#define __table_entries_sym( table, idx ) \
|
||||
"__tbl_" __table_name ( table ) "_" #idx
|
||||
#define __table_temp_sym( a, b ) \
|
||||
___table_temp_sym( __table_, a, _, b )
|
||||
#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
|
||||
|
||||
/*
|
||||
* icc ignores __attribute__ (( aligned (x) )) when it is used to
|
||||
* decrease the compiler's default choice of alignment (which may be
|
||||
* higher than the alignment actually required by the structure). We
|
||||
* work around this by forcing the alignment to a large multiple of
|
||||
* the required value (so that we are never attempting to decrease the
|
||||
* default alignment) and then postprocessing the object file to
|
||||
* reduce the alignment back down to the "real" value.
|
||||
*
|
||||
*/
|
||||
#undef __table_alignment
|
||||
#define __table_alignment( table ) \
|
||||
( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
|
||||
|
||||
/*
|
||||
* Because of the alignment hack, we must ensure that the compiler
|
||||
* never tries to place multiple objects within the same section,
|
||||
* otherwise the assembler will insert padding to the (incorrect)
|
||||
* alignment boundary. Do this by appending the line number to table
|
||||
* section names.
|
||||
*
|
||||
* Note that we don't need to worry about padding between array
|
||||
* elements, since the alignment is declared on the variable (i.e. the
|
||||
* whole array) rather than on the type (i.e. on all individual array
|
||||
* elements).
|
||||
*/
|
||||
#undef __table_section
|
||||
#define __table_section( table, idx ) \
|
||||
".tbl." __table_name ( table ) "." __table_str ( idx ) \
|
||||
"." __table_xstr ( __LINE__ )
|
||||
#define __table_xstr( x ) __table_str ( x )
|
||||
|
||||
#endif /* __ICC */
|
||||
|
||||
#endif /* _IPXE_TABLES_H */
|
||||
|
||||
@ -25,40 +25,24 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/efi_autoboot.h>
|
||||
#include <ipxe/efi/Protocol/SimpleNetwork.h>
|
||||
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
|
||||
#include <ipxe/efi/Guid/FileInfo.h>
|
||||
#include <usr/autoboot.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI automatic booting
|
||||
* EFI autoboot device
|
||||
*
|
||||
*/
|
||||
|
||||
/** Autoexec script filename */
|
||||
#define AUTOEXEC_FILENAME L"autoexec.ipxe"
|
||||
|
||||
/** Autoexec script image name */
|
||||
#define AUTOEXEC_NAME "autoexec.ipxe"
|
||||
|
||||
/** Autoexec script (if any) */
|
||||
static void *efi_autoexec;
|
||||
|
||||
/** Autoexec script length */
|
||||
static size_t efi_autoexec_len;
|
||||
|
||||
/**
|
||||
* Identify autoboot device
|
||||
*
|
||||
* @v device Device handle
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int efi_set_autoboot_ll_addr ( EFI_HANDLE device ) {
|
||||
int efi_set_autoboot_ll_addr ( EFI_HANDLE device ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
union {
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *snp;
|
||||
@ -93,172 +77,3 @@ static int efi_set_autoboot_ll_addr ( EFI_HANDLE device ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load autoexec script
|
||||
*
|
||||
* @v device Device handle
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int efi_load_autoexec ( EFI_HANDLE device ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
static wchar_t name[] = AUTOEXEC_FILENAME;
|
||||
union {
|
||||
void *interface;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs;
|
||||
} u;
|
||||
struct {
|
||||
EFI_FILE_INFO info;
|
||||
CHAR16 name[ sizeof ( name ) / sizeof ( name[0] ) ];
|
||||
} info;
|
||||
EFI_FILE_PROTOCOL *root;
|
||||
EFI_FILE_PROTOCOL *file;
|
||||
UINTN size;
|
||||
VOID *data;
|
||||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( efi_autoexec == UNULL );
|
||||
assert ( efi_autoexec_len == 0 );
|
||||
|
||||
/* Open simple file system protocol */
|
||||
if ( ( efirc = bs->OpenProtocol ( device,
|
||||
&efi_simple_file_system_protocol_guid,
|
||||
&u.interface, efi_image_handle,
|
||||
device,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s has no filesystem instance: %s\n",
|
||||
efi_handle_name ( device ), strerror ( rc ) );
|
||||
goto err_filesystem;
|
||||
}
|
||||
|
||||
/* Open root directory */
|
||||
if ( ( efirc = u.fs->OpenVolume ( u.fs, &root ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not open volume: %s\n",
|
||||
efi_handle_name ( device ), strerror ( rc ) );
|
||||
goto err_volume;
|
||||
}
|
||||
|
||||
/* Open autoexec script */
|
||||
if ( ( efirc = root->Open ( root, &file, name,
|
||||
EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s has no %ls: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_open;
|
||||
}
|
||||
|
||||
/* Get file information */
|
||||
size = sizeof ( info );
|
||||
if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
|
||||
&info ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not get %ls info: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_getinfo;
|
||||
}
|
||||
size = info.info.FileSize;
|
||||
|
||||
/* Ignore zero-length files */
|
||||
if ( ! size ) {
|
||||
rc = -EINVAL;
|
||||
DBGC ( device, "EFI %s has zero-length %ls\n",
|
||||
efi_handle_name ( device ), name );
|
||||
goto err_empty;
|
||||
}
|
||||
|
||||
/* Allocate temporary copy */
|
||||
if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, size,
|
||||
&data ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not allocate %ls: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
/* Read file */
|
||||
if ( ( efirc = file->Read ( file, &size, data ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not read %ls: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_read;
|
||||
}
|
||||
|
||||
/* Record autoexec script */
|
||||
efi_autoexec = data;
|
||||
efi_autoexec_len = size;
|
||||
data = NULL;
|
||||
DBGC ( device, "EFI %s found %ls\n",
|
||||
efi_handle_name ( device ), name );
|
||||
|
||||
/* Success */
|
||||
rc = 0;
|
||||
|
||||
err_read:
|
||||
if ( data )
|
||||
bs->FreePool ( data );
|
||||
err_alloc:
|
||||
err_empty:
|
||||
err_getinfo:
|
||||
file->Close ( file );
|
||||
err_open:
|
||||
root->Close ( root );
|
||||
err_volume:
|
||||
bs->CloseProtocol ( device, &efi_simple_file_system_protocol_guid,
|
||||
efi_image_handle, device );
|
||||
err_filesystem:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure automatic booting
|
||||
*
|
||||
*/
|
||||
void efi_set_autoboot ( void ) {
|
||||
EFI_HANDLE device = efi_loaded_image->DeviceHandle;
|
||||
|
||||
/* Identify autoboot device, if any */
|
||||
efi_set_autoboot_ll_addr ( device );
|
||||
|
||||
/* Load autoexec script, if any */
|
||||
efi_load_autoexec ( device );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register automatic boot image
|
||||
*
|
||||
*/
|
||||
static void efi_autoboot_startup ( void ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
EFI_HANDLE device = efi_loaded_image->DeviceHandle;
|
||||
const char *name = AUTOEXEC_NAME;
|
||||
struct image *image;
|
||||
|
||||
/* Do nothing if we have no autoexec script */
|
||||
if ( ! efi_autoexec )
|
||||
return;
|
||||
|
||||
/* Create autoexec image */
|
||||
image = image_memory ( name, virt_to_user ( efi_autoexec ),
|
||||
efi_autoexec_len );
|
||||
if ( ! image ) {
|
||||
DBGC ( device, "EFI %s could not create %s\n",
|
||||
efi_handle_name ( device ), name );
|
||||
return;
|
||||
}
|
||||
DBGC ( device, "EFI %s registered %s\n",
|
||||
efi_handle_name ( device ), name );
|
||||
|
||||
/* Free temporary copy */
|
||||
bs->FreePool ( efi_autoexec );
|
||||
efi_autoexec = NULL;
|
||||
}
|
||||
|
||||
/** Automatic boot startup function */
|
||||
struct startup_fn efi_autoboot_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
|
||||
.name = "efi_autoboot",
|
||||
.startup = efi_autoboot_startup,
|
||||
};
|
||||
|
||||
206
src/interface/efi/efi_autoexec.c
Normal file
206
src/interface/efi/efi_autoexec.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/efi_autoexec.h>
|
||||
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
|
||||
#include <ipxe/efi/Guid/FileInfo.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI autoexec script
|
||||
*
|
||||
*/
|
||||
|
||||
/** Autoexec script filename */
|
||||
#define AUTOEXEC_FILENAME L"autoexec.ipxe"
|
||||
|
||||
/** Autoexec script image name */
|
||||
#define AUTOEXEC_NAME "autoexec.ipxe"
|
||||
|
||||
/** Autoexec script (if any) */
|
||||
static void *efi_autoexec;
|
||||
|
||||
/** Autoexec script length */
|
||||
static size_t efi_autoexec_len;
|
||||
|
||||
/**
|
||||
* Load autoexec script
|
||||
*
|
||||
* @v device Device handle
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int efi_autoexec_load ( EFI_HANDLE device ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
static wchar_t name[] = AUTOEXEC_FILENAME;
|
||||
union {
|
||||
void *interface;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs;
|
||||
} u;
|
||||
struct {
|
||||
EFI_FILE_INFO info;
|
||||
CHAR16 name[ sizeof ( name ) / sizeof ( name[0] ) ];
|
||||
} info;
|
||||
EFI_FILE_PROTOCOL *root;
|
||||
EFI_FILE_PROTOCOL *file;
|
||||
UINTN size;
|
||||
VOID *data;
|
||||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( efi_autoexec == NULL );
|
||||
assert ( efi_autoexec_len == 0 );
|
||||
|
||||
/* Open simple file system protocol */
|
||||
if ( ( efirc = bs->OpenProtocol ( device,
|
||||
&efi_simple_file_system_protocol_guid,
|
||||
&u.interface, efi_image_handle,
|
||||
device,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s has no filesystem instance: %s\n",
|
||||
efi_handle_name ( device ), strerror ( rc ) );
|
||||
goto err_filesystem;
|
||||
}
|
||||
|
||||
/* Open root directory */
|
||||
if ( ( efirc = u.fs->OpenVolume ( u.fs, &root ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not open volume: %s\n",
|
||||
efi_handle_name ( device ), strerror ( rc ) );
|
||||
goto err_volume;
|
||||
}
|
||||
|
||||
/* Open autoexec script */
|
||||
if ( ( efirc = root->Open ( root, &file, name,
|
||||
EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s has no %ls: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_open;
|
||||
}
|
||||
|
||||
/* Get file information */
|
||||
size = sizeof ( info );
|
||||
if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
|
||||
&info ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not get %ls info: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_getinfo;
|
||||
}
|
||||
size = info.info.FileSize;
|
||||
|
||||
/* Ignore zero-length files */
|
||||
if ( ! size ) {
|
||||
rc = -EINVAL;
|
||||
DBGC ( device, "EFI %s has zero-length %ls\n",
|
||||
efi_handle_name ( device ), name );
|
||||
goto err_empty;
|
||||
}
|
||||
|
||||
/* Allocate temporary copy */
|
||||
if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, size,
|
||||
&data ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not allocate %ls: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
/* Read file */
|
||||
if ( ( efirc = file->Read ( file, &size, data ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s could not read %ls: %s\n",
|
||||
efi_handle_name ( device ), name, strerror ( rc ) );
|
||||
goto err_read;
|
||||
}
|
||||
|
||||
/* Record autoexec script */
|
||||
efi_autoexec = data;
|
||||
efi_autoexec_len = size;
|
||||
data = NULL;
|
||||
DBGC ( device, "EFI %s found %ls\n",
|
||||
efi_handle_name ( device ), name );
|
||||
|
||||
/* Success */
|
||||
rc = 0;
|
||||
|
||||
err_read:
|
||||
if ( data )
|
||||
bs->FreePool ( data );
|
||||
err_alloc:
|
||||
err_empty:
|
||||
err_getinfo:
|
||||
file->Close ( file );
|
||||
err_open:
|
||||
root->Close ( root );
|
||||
err_volume:
|
||||
bs->CloseProtocol ( device, &efi_simple_file_system_protocol_guid,
|
||||
efi_image_handle, device );
|
||||
err_filesystem:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register autoexec script
|
||||
*
|
||||
*/
|
||||
static void efi_autoexec_startup ( void ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
EFI_HANDLE device = efi_loaded_image->DeviceHandle;
|
||||
const char *name = AUTOEXEC_NAME;
|
||||
struct image *image;
|
||||
|
||||
/* Do nothing if we have no autoexec script */
|
||||
if ( ! efi_autoexec )
|
||||
return;
|
||||
|
||||
/* Create autoexec image */
|
||||
image = image_memory ( name, virt_to_user ( efi_autoexec ),
|
||||
efi_autoexec_len );
|
||||
if ( ! image ) {
|
||||
DBGC ( device, "EFI %s could not create %s\n",
|
||||
efi_handle_name ( device ), name );
|
||||
return;
|
||||
}
|
||||
DBGC ( device, "EFI %s registered %s\n",
|
||||
efi_handle_name ( device ), name );
|
||||
|
||||
/* Free temporary copy */
|
||||
bs->FreePool ( efi_autoexec );
|
||||
efi_autoexec = NULL;
|
||||
}
|
||||
|
||||
/** Autoexec script startup function */
|
||||
struct startup_fn efi_autoexec_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
|
||||
.name = "efi_autoexec",
|
||||
.startup = efi_autoexec_startup,
|
||||
};
|
||||
94
src/interface/efi/efi_cachedhcp.c
Normal file
94
src/interface/efi/efi_cachedhcp.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/cachedhcp.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/efi_cachedhcp.h>
|
||||
#include <ipxe/efi/Protocol/PxeBaseCode.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI cached DHCP packet
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Record cached DHCP packet
|
||||
*
|
||||
* @v device Device handle
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int efi_cachedhcp_record ( EFI_HANDLE device ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
union {
|
||||
EFI_PXE_BASE_CODE_PROTOCOL *pxe;
|
||||
void *interface;
|
||||
} pxe;
|
||||
EFI_PXE_BASE_CODE_MODE *mode;
|
||||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
||||
/* Look for a PXE base code instance on the image's device handle */
|
||||
if ( ( efirc = bs->OpenProtocol ( device,
|
||||
&efi_pxe_base_code_protocol_guid,
|
||||
&pxe.interface, efi_image_handle,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( device, "EFI %s has no PXE base code instance: %s\n",
|
||||
efi_handle_name ( device ), strerror ( rc ) );
|
||||
goto err_open;
|
||||
}
|
||||
|
||||
/* Do not attempt to cache IPv6 packets */
|
||||
mode = pxe.pxe->Mode;
|
||||
if ( mode->UsingIpv6 ) {
|
||||
rc = -ENOTSUP;
|
||||
DBGC ( device, "EFI %s has IPv6 PXE base code\n",
|
||||
efi_handle_name ( device ) );
|
||||
goto err_ipv6;
|
||||
}
|
||||
|
||||
/* Record DHCPACK, if present */
|
||||
if ( mode->DhcpAckReceived &&
|
||||
( ( rc = cachedhcp_record ( virt_to_user ( &mode->DhcpAck ),
|
||||
sizeof ( mode->DhcpAck ) ) ) != 0 ) ) {
|
||||
DBGC ( device, "EFI %s could not record DHCPACK: %s\n",
|
||||
efi_handle_name ( device ), strerror ( rc ) );
|
||||
goto err_record;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
rc = 0;
|
||||
|
||||
err_record:
|
||||
err_ipv6:
|
||||
bs->CloseProtocol ( device, &efi_pxe_base_code_protocol_guid,
|
||||
efi_image_handle, NULL );
|
||||
err_open:
|
||||
return rc;
|
||||
}
|
||||
@ -22,10 +22,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/device.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/efi_driver.h>
|
||||
#include <ipxe/efi/efi_snp.h>
|
||||
#include <ipxe/efi/efi_autoboot.h>
|
||||
#include <ipxe/efi/efi_autoexec.h>
|
||||
#include <ipxe/efi/efi_cachedhcp.h>
|
||||
#include <ipxe/efi/efi_watchdog.h>
|
||||
#include <ipxe/efi/efi_veto.h>
|
||||
|
||||
@ -48,9 +51,6 @@ EFI_STATUS EFIAPI _efi_start ( EFI_HANDLE image_handle,
|
||||
if ( ( efirc = efi_init ( image_handle, systab ) ) != 0 )
|
||||
goto err_init;
|
||||
|
||||
/* Record autoboot device (if any) */
|
||||
efi_set_autoboot();
|
||||
|
||||
/* Claim SNP devices for use by iPXE */
|
||||
efi_snp_claim();
|
||||
|
||||
@ -72,6 +72,28 @@ EFI_STATUS EFIAPI _efi_start ( EFI_HANDLE image_handle,
|
||||
return efirc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise EFI application
|
||||
*
|
||||
*/
|
||||
static void efi_init_application ( void ) {
|
||||
EFI_HANDLE device = efi_loaded_image->DeviceHandle;
|
||||
|
||||
/* Identify autoboot device, if any */
|
||||
efi_set_autoboot_ll_addr ( device );
|
||||
|
||||
/* Store cached DHCP packet, if any */
|
||||
efi_cachedhcp_record ( device );
|
||||
|
||||
/* Load autoexec script, if any */
|
||||
efi_autoexec_load ( device );
|
||||
}
|
||||
|
||||
/** EFI application initialisation function */
|
||||
struct init_fn efi_init_application_fn __init_fn ( INIT_NORMAL ) = {
|
||||
.initialise = efi_init_application,
|
||||
};
|
||||
|
||||
/**
|
||||
* Probe EFI root bus
|
||||
*
|
||||
|
||||
@ -210,18 +210,19 @@ int uriboot ( struct uri *filename, struct uri **root_paths,
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all open net devices
|
||||
* Close all but one network device
|
||||
*
|
||||
* Called before a fresh boot attempt in order to free up memory. We
|
||||
* don't just close the device immediately after the boot fails,
|
||||
* because there may still be TCP connections in the process of
|
||||
* closing.
|
||||
*/
|
||||
static void close_all_netdevs ( void ) {
|
||||
struct net_device *netdev;
|
||||
static void close_other_netdevs ( struct net_device *netdev ) {
|
||||
struct net_device *other;
|
||||
|
||||
for_each_netdev ( netdev ) {
|
||||
ifclose ( netdev );
|
||||
for_each_netdev ( other ) {
|
||||
if ( other != netdev )
|
||||
ifclose ( other );
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,7 +389,7 @@ int netboot ( struct net_device *netdev ) {
|
||||
int rc;
|
||||
|
||||
/* Close all other network devices */
|
||||
close_all_netdevs();
|
||||
close_other_netdevs ( netdev );
|
||||
|
||||
/* Open device and display device status */
|
||||
if ( ( rc = ifopen ( netdev ) ) != 0 )
|
||||
|
||||
1
src/util/.gitignore
vendored
1
src/util/.gitignore
vendored
@ -6,5 +6,4 @@ elf2efi32
|
||||
elf2efi64
|
||||
efirom
|
||||
efifatbin
|
||||
iccfix
|
||||
einfo
|
||||
|
||||
@ -268,13 +268,27 @@ fi
|
||||
#
|
||||
if [ -n "${ISOIMG}" ] ; then
|
||||
MKISOFS=
|
||||
MKISOFS_MISSING=
|
||||
MKISOFS_NOTSUP=
|
||||
for CMD in genisoimage mkisofs xorrisofs ; do
|
||||
if "${CMD}" ${ISOARGS} --version "${ISODIR}" >/dev/null 2>&1 ; then
|
||||
MKISOFS="${CMD}"
|
||||
break
|
||||
if ! "${CMD}" --version >/dev/null 2>&1 ; then
|
||||
MKISOFS_MISSING="${MKISOFS_MISSING} ${CMD}"
|
||||
continue
|
||||
fi
|
||||
if ! "${CMD}" ${ISOARGS} --version "${ISODIR}" >/dev/null 2>&1 ; then
|
||||
MKISOFS_NOTSUP="${MKISOFS_NOTSUP} ${CMD}"
|
||||
continue
|
||||
fi
|
||||
MKISOFS="${CMD}"
|
||||
break
|
||||
done
|
||||
if [ -z "${MKISOFS}" ] ; then
|
||||
if [ -n "${MKISOFS_MISSING}" ] ; then
|
||||
echo "${0}:${MKISOFS_MISSING}: not installed" >&2
|
||||
fi
|
||||
if [ -n "${MKISOFS_NOTSUP}" ] ; then
|
||||
echo "${0}:${MKISOFS_NOTSUP}: cannot handle ${ISOARGS}" >&2
|
||||
fi
|
||||
echo "${0}: cannot find a suitable mkisofs or equivalent" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -1,157 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <elf.h>
|
||||
#include <ipxe/tables.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
|
||||
|
||||
#define dprintf(...) do { \
|
||||
if ( DEBUG ) \
|
||||
fprintf ( stderr, __VA_ARGS__ ); \
|
||||
} while ( 0 )
|
||||
|
||||
#ifdef SELF_INCLUDED
|
||||
|
||||
/**
|
||||
* Fix up ICC alignments
|
||||
*
|
||||
* @v elf ELF header
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* See comments in tables.h for an explanation of why this monstrosity
|
||||
* is necessary.
|
||||
*/
|
||||
static int ICCFIX ( void *elf ) {
|
||||
ELF_EHDR *ehdr = elf;
|
||||
ELF_SHDR *shdr = ( elf + ehdr->e_shoff );
|
||||
size_t shentsize = ehdr->e_shentsize;
|
||||
unsigned int shnum = ehdr->e_shnum;
|
||||
ELF_SHDR *strtab = ( ( ( void * ) shdr ) +
|
||||
( ehdr->e_shstrndx * shentsize ) );
|
||||
char *strings = ( elf + strtab->sh_offset );
|
||||
|
||||
for ( ; shnum-- ; shdr = ( ( ( void * ) shdr ) + shentsize ) ) {
|
||||
char *name = ( strings + shdr->sh_name );
|
||||
unsigned long align = shdr->sh_addralign;
|
||||
unsigned long new_align;
|
||||
|
||||
if ( ( strncmp ( name, ".tbl.", 5 ) == 0 ) &&
|
||||
( align >= ICC_ALIGN_HACK_FACTOR ) ) {
|
||||
new_align = ( align / ICC_ALIGN_HACK_FACTOR );
|
||||
shdr->sh_addralign = new_align;
|
||||
dprintf ( "Section \"%s\": alignment %ld->%ld\n",
|
||||
name, align, new_align );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* SELF_INCLUDED */
|
||||
|
||||
#define SELF_INCLUDED
|
||||
|
||||
/* Include iccfix32() function */
|
||||
#define ELF_EHDR Elf32_Ehdr
|
||||
#define ELF_SHDR Elf32_Shdr
|
||||
#define ICCFIX iccfix32
|
||||
#include "iccfix.c"
|
||||
#undef ELF_EHDR
|
||||
#undef ELF_SHDR
|
||||
#undef ICCFIX
|
||||
|
||||
/* Include iccfix64() function */
|
||||
#define ELF_EHDR Elf64_Ehdr
|
||||
#define ELF_SHDR Elf64_Shdr
|
||||
#define ICCFIX iccfix64
|
||||
#include "iccfix.c"
|
||||
#undef ELF_EHDR
|
||||
#undef ELF_SHDR
|
||||
#undef ICCFIX
|
||||
|
||||
static int iccfix ( const char *filename ) {
|
||||
int fd;
|
||||
struct stat stat;
|
||||
void *elf;
|
||||
unsigned char *eident;
|
||||
int rc;
|
||||
|
||||
/* Open and mmap file */
|
||||
fd = open ( filename, O_RDWR );
|
||||
if ( fd < 0 ) {
|
||||
eprintf ( "Could not open %s: %s\n",
|
||||
filename, strerror ( errno ) );
|
||||
rc = -1;
|
||||
goto err_open;
|
||||
}
|
||||
if ( fstat ( fd, &stat ) < 0 ) {
|
||||
eprintf ( "Could not determine size of %s: %s\n",
|
||||
filename, strerror ( errno ) );
|
||||
rc = -1;
|
||||
goto err_fstat;
|
||||
}
|
||||
elf = mmap ( NULL, stat.st_size, ( PROT_READ | PROT_WRITE ),
|
||||
MAP_SHARED, fd, 0 );
|
||||
if ( elf == MAP_FAILED ) {
|
||||
eprintf ( "Could not map %s: %s\n",
|
||||
filename, strerror ( errno ) );
|
||||
rc = -1;
|
||||
goto err_mmap;
|
||||
}
|
||||
|
||||
/* Perform fixups */
|
||||
eident = elf;
|
||||
switch ( eident[EI_CLASS] ) {
|
||||
case ELFCLASS32:
|
||||
rc = iccfix32 ( elf );
|
||||
break;
|
||||
case ELFCLASS64:
|
||||
rc = iccfix64 ( elf );
|
||||
break;
|
||||
default:
|
||||
eprintf ( "Unknown ELF class %d in %s\n",
|
||||
eident[EI_CLASS], filename );
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
munmap ( elf, stat.st_size );
|
||||
err_mmap:
|
||||
err_fstat:
|
||||
close ( fd );
|
||||
err_open:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main ( int argc, char **argv ) {
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
/* Parse command line */
|
||||
if ( argc < 2 ) {
|
||||
eprintf ( "Syntax: %s <object_file>...\n", argv[0] );
|
||||
exit ( 1 );
|
||||
}
|
||||
|
||||
/* Process each object in turn */
|
||||
for ( i = 1 ; i < argc ; i++ ) {
|
||||
if ( ( rc = iccfix ( argv[i] ) ) != 0 ) {
|
||||
eprintf ( "Could not fix up %s\n", argv[i] );
|
||||
exit ( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SELF_INCLUDED */
|
||||
Reference in New Issue
Block a user