mirror of
https://gitlab.com/qemu-project/ipxe.git
synced 2025-11-03 07:59:06 +08:00
Compare commits
1 Commits
mschapv2
...
simpletext
| Author | SHA1 | Date | |
|---|---|---|---|
| b5d8ed7e28 |
121
.github/workflows/build.yml
vendored
121
.github/workflows/build.yml
vendored
@ -1,121 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
|
||||
cache:
|
||||
name: Cache
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
restore-keys: |
|
||||
apt-cache-
|
||||
- name: Download packages
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y -d -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux \
|
||||
libc6-dev-i386 valgrind \
|
||||
gcc-arm-none-eabi gcc-aarch64-linux-gnu
|
||||
|
||||
x86:
|
||||
name: x86
|
||||
runs-on: ubuntu-22.04
|
||||
needs: cache
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update
|
||||
sudo apt install -y -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux \
|
||||
libc6-dev-i386 valgrind \
|
||||
libgcc-s1:i386 libc6-dbg:i386
|
||||
- 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-22.04
|
||||
needs: cache
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
- 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-22.04
|
||||
needs: cache
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
- 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
37
.github/workflows/coverity.yml
vendored
@ -1,37 +0,0 @@
|
||||
name: Coverity Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- coverity_scan
|
||||
|
||||
jobs:
|
||||
submit:
|
||||
name: Submit
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
- 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
Normal file
58
.travis.yml
Normal file
@ -0,0 +1,58 @@
|
||||
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
|
||||
@ -1,150 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from base64 import b64encode
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import date
|
||||
from hashlib import sha256
|
||||
from itertools import count
|
||||
import subprocess
|
||||
|
||||
import boto3
|
||||
|
||||
BLOCKSIZE = 512 * 1024
|
||||
|
||||
|
||||
def detect_architecture(image):
|
||||
"""Detect CPU architecture"""
|
||||
mdir = subprocess.run(['mdir', '-b', '-i', image, '::/EFI/BOOT'],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if any(b'BOOTAA64.EFI' in x for x in mdir.stdout.splitlines()):
|
||||
return 'arm64'
|
||||
return 'x86_64'
|
||||
|
||||
|
||||
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, overwrite):
|
||||
"""Import an AMI image"""
|
||||
client = boto3.client('ec2', region_name=region)
|
||||
resource = boto3.resource('ec2', region_name=region)
|
||||
description = '%s (%s)' % (name, architecture)
|
||||
images = client.describe_images(Filters=[{'Name': 'name',
|
||||
'Values': [description]}])
|
||||
if overwrite and images['Images']:
|
||||
images = images['Images'][0]
|
||||
image_id = images['ImageId']
|
||||
snapshot_id = images['BlockDeviceMappings'][0]['Ebs']['SnapshotId']
|
||||
resource.Image(image_id).deregister()
|
||||
resource.Snapshot(snapshot_id).delete()
|
||||
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
|
||||
|
||||
|
||||
def launch_link(region, image_id):
|
||||
"""Construct a web console launch link"""
|
||||
return ("https://console.aws.amazon.com/ec2/v2/home?"
|
||||
"region=%s#LaunchInstanceWizard:ami=%s" % (region, image_id))
|
||||
|
||||
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="Import AWS EC2 image (AMI)")
|
||||
parser.add_argument('--name', '-n',
|
||||
help="Image name")
|
||||
parser.add_argument('--public', '-p', action='store_true',
|
||||
help="Make image public")
|
||||
parser.add_argument('--overwrite', action='store_true',
|
||||
help="Overwrite any existing image with same name")
|
||||
parser.add_argument('--region', '-r', action='append',
|
||||
help="AWS region(s)")
|
||||
parser.add_argument('--wiki', '-w', metavar='FILE',
|
||||
help="Generate Dokuwiki table")
|
||||
parser.add_argument('image', nargs='+', help="iPXE disk image")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Detect CPU architectures
|
||||
architectures = {image: detect_architecture(image) for image in args.image}
|
||||
|
||||
# Use default name if none specified
|
||||
if not args.name:
|
||||
args.name = 'iPXE (%s)' % date.today().strftime('%Y-%m-%d')
|
||||
|
||||
# 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 import to maximise parallelism
|
||||
imports = [(region, image) for region in args.region for image in args.image]
|
||||
with ThreadPoolExecutor(max_workers=len(imports)) as executor:
|
||||
futures = {executor.submit(import_image,
|
||||
region=region,
|
||||
name=args.name,
|
||||
architecture=architectures[image],
|
||||
image=image,
|
||||
public=args.public,
|
||||
overwrite=args.overwrite): (region, image)
|
||||
for region, image in imports}
|
||||
results = {futures[future]: future.result()
|
||||
for future in as_completed(futures)}
|
||||
|
||||
# Construct Dokuwiki table
|
||||
wikitab = ["^ AWS region ^ CPU architecture ^ AMI ID ^\n"] + list(
|
||||
"| ''%s'' | ''%s'' | ''[[%s|%s]]'' |\n" % (
|
||||
region,
|
||||
architectures[image],
|
||||
launch_link(region, results[(region, image)]),
|
||||
results[(region, image)],
|
||||
) for region, image in imports)
|
||||
if args.wiki:
|
||||
with open(args.wiki, 'wt') as fh:
|
||||
fh.writelines(wikitab)
|
||||
|
||||
# Show created images
|
||||
for region, image in imports:
|
||||
print("%s %s %s %s" % (
|
||||
region, image, architectures[image], results[(region, image)]
|
||||
))
|
||||
@ -1,68 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
|
||||
import boto3
|
||||
|
||||
BLOCKSIZE = 512 * 1024
|
||||
|
||||
IPXELOG_OFFSET = 16 * 1024
|
||||
|
||||
IPXELOG_MAGIC = b'iPXE LOG'
|
||||
|
||||
|
||||
def create_snapshot(region, instance_id):
|
||||
"""Create root volume snapshot"""
|
||||
client = boto3.client('ec2', region_name=region)
|
||||
resource = boto3.resource('ec2', region_name=region)
|
||||
instance = resource.Instance(instance_id)
|
||||
volumes = list(instance.volumes.all())
|
||||
snapshot = volumes[0].create_snapshot()
|
||||
snapshot.wait_until_completed()
|
||||
return snapshot.id
|
||||
|
||||
|
||||
def get_snapshot_block(region, snapshot_id, index):
|
||||
"""Get block content from snapshot"""
|
||||
client = boto3.client('ebs', region_name=region)
|
||||
blocks = client.list_snapshot_blocks(SnapshotId=snapshot_id,
|
||||
StartingBlockIndex=index)
|
||||
token = blocks['Blocks'][0]['BlockToken']
|
||||
block = client.get_snapshot_block(SnapshotId=snapshot_id,
|
||||
BlockIndex=index,
|
||||
BlockToken=token)
|
||||
return block['BlockData'].read()
|
||||
|
||||
|
||||
def get_block0_content(region, instance_id):
|
||||
"""Get content of root volume block zero from instance"""
|
||||
client = boto3.client('ec2', region_name=region)
|
||||
resource = boto3.resource('ec2', region_name=region)
|
||||
snapshot_id = create_snapshot(region, instance_id)
|
||||
block = get_snapshot_block(region, snapshot_id, 0)
|
||||
resource.Snapshot(snapshot_id).delete()
|
||||
return block
|
||||
|
||||
|
||||
def get_int13con_output(region, instance_id):
|
||||
"""Get INT13 console output"""
|
||||
block = get_block0_content(region, instance_id)
|
||||
logpart = block[IPXELOG_OFFSET:]
|
||||
magic = logpart[:len(IPXELOG_MAGIC)]
|
||||
if magic != IPXELOG_MAGIC:
|
||||
raise ValueError("Invalid log magic signature")
|
||||
log = logpart[len(IPXELOG_MAGIC):].split(b'\0')[0]
|
||||
return log.decode()
|
||||
|
||||
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="Get AWS INT13 console output")
|
||||
parser.add_argument('--region', '-r', help="AWS region")
|
||||
parser.add_argument('id', help="Instance ID")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Get console output from INT13CON partition
|
||||
output = get_int13con_output(args.region, args.id)
|
||||
|
||||
# Print console output
|
||||
print(output)
|
||||
File diff suppressed because it is too large
Load Diff
2
src/.gitignore
vendored
2
src/.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
.toolcheck
|
||||
.echocheck
|
||||
TAGS*
|
||||
bin-*
|
||||
bin*
|
||||
|
||||
@ -10,7 +10,6 @@ LDFLAGS :=
|
||||
HOST_CFLAGS :=
|
||||
MAKEDEPS := Makefile
|
||||
CROSS_COMPILE ?= $(CROSS)
|
||||
SYMBOL_PREFIX :=
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -24,7 +23,6 @@ CP := cp
|
||||
ECHO := echo
|
||||
PRINTF := printf
|
||||
PERL := perl
|
||||
PYTHON := python
|
||||
TRUE := true
|
||||
CC := $(CROSS_COMPILE)gcc
|
||||
CPP := $(CC) -E
|
||||
@ -50,8 +48,9 @@ ELF2EFI32 := ./util/elf2efi32
|
||||
ELF2EFI64 := ./util/elf2efi64
|
||||
EFIROM := ./util/efirom
|
||||
EFIFATBIN := ./util/efifatbin
|
||||
ICCFIX := ./util/iccfix
|
||||
EINFO := ./util/einfo
|
||||
GENKEYMAP := ./util/genkeymap.py
|
||||
GENKEYMAP := ./util/genkeymap.pl
|
||||
DOXYGEN := doxygen
|
||||
LCAB := lcab
|
||||
QEMUIMG := qemu-img
|
||||
@ -191,7 +190,7 @@ vmware : bin/8086100f.mrom bin/808610d3.mrom bin/10222000.rom bin/15ad07b0.rom
|
||||
@$(ECHO) ' bin/10222000.rom -- vlance/pcnet32'
|
||||
@$(ECHO) ' bin/15ad07b0.rom -- vmxnet3'
|
||||
@$(ECHO)
|
||||
@$(ECHO) 'For more information, see https://ipxe.org/howto/vmware'
|
||||
@$(ECHO) 'For more information, see http://ipxe.org/howto/vmware'
|
||||
@$(ECHO)
|
||||
@$(ECHO) '==========================================================='
|
||||
|
||||
|
||||
@ -43,17 +43,12 @@ $(BIN)/%.drv.efi : $(BIN)/%.efidrv
|
||||
|
||||
$(BIN)/%.efirom : $(BIN)/%.efidrv $(EFIROM)
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)$(EFIROM) -v $(firstword $(TGT_PCI_VENDOR) 0) \
|
||||
-d $(firstword $(TGT_PCI_DEVICE) 0) -c $< $@
|
||||
$(Q)$(EFIROM) -v $(TGT_PCI_VENDOR) -d $(TGT_PCI_DEVICE) $< $@
|
||||
|
||||
$(BIN)/efidrv.cab : $(BIN)/alldrv.efis # $(ALL_drv.efi) is not yet defined
|
||||
$(QM)$(ECHO) " [CAB] $@"
|
||||
$(Q)$(LCAB) -n -q $(ALL_drv.efi) $@
|
||||
|
||||
$(BIN)/%.iso : $(BIN)/%.efi util/genfsimg
|
||||
$(QM)$(ECHO) " [GENFSIMG] $@"
|
||||
$(Q)util/genfsimg -o $@ $<
|
||||
|
||||
$(BIN)/%.usb : $(BIN)/%.efi util/genfsimg
|
||||
$(BIN)/%.iso $(BIN)/%.usb : $(BIN)/%.efi util/genfsimg
|
||||
$(QM)$(ECHO) " [GENFSIMG] $@"
|
||||
$(Q)util/genfsimg -o $@ $<
|
||||
|
||||
@ -76,7 +76,9 @@ CCDEFS := $(shell $(CC) -E -x c -c /dev/null -dM | cut -d" " -f2)
|
||||
ccdefs:
|
||||
@$(ECHO) $(CCDEFS)
|
||||
|
||||
ifeq ($(filter __GNUC__,$(CCDEFS)),__GNUC__)
|
||||
ifeq ($(filter __ICC,$(CCDEFS)),__ICC)
|
||||
CCTYPE := icc
|
||||
else
|
||||
CCTYPE := gcc
|
||||
endif
|
||||
cctype:
|
||||
@ -111,13 +113,6 @@ $(warning Use GNU ld instead)
|
||||
$(error Unsuitable build environment found)
|
||||
endif
|
||||
|
||||
OBJCOPY_ETC_BANNER := $(shell $(OBJCOPY) --version | grep 'elftoolchain')
|
||||
ifneq ($(OBJCOPY_ETC_BANNER),)
|
||||
$(warning The elftoolchain objcopy is unsuitable for building iPXE)
|
||||
$(warning Use binutils objcopy instead)
|
||||
$(error Unsuitable build environment found)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Check if $(eval ...) is available to use
|
||||
@ -369,43 +364,7 @@ endif
|
||||
# Include architecture-specific include path
|
||||
ifdef ARCH
|
||||
INCDIRS += arch/$(ARCH)/include
|
||||
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)
|
||||
INCDIRS += arch/$(ARCH)/include/$(PLATFORM)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
@ -461,9 +420,33 @@ ifeq ($(CCTYPE),gcc)
|
||||
CFLAGS += -ffreestanding
|
||||
CFLAGS += -fcommon
|
||||
CFLAGS += -Wall -W -Wformat-nonliteral
|
||||
CFLAGS += -Wno-array-bounds -Wno-dangling-pointer
|
||||
HOST_CFLAGS += -Wall -W -Wformat-nonliteral
|
||||
HOST_CFLAGS += -Wno-array-bounds -Wno-dangling-pointer
|
||||
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)
|
||||
@ -478,6 +461,35 @@ 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
|
||||
@ -502,13 +514,6 @@ LDFLAGS += --gc-sections
|
||||
#
|
||||
LDFLAGS += -static
|
||||
|
||||
# Use separate code segment if supported by linker
|
||||
#
|
||||
ZSC_TEST = $(LD) -z separate-code --version 2>&1 > /dev/null
|
||||
ZSC_FLAGS := $(shell [ -z "`$(ZSC_TEST)`" ] && \
|
||||
$(ECHO) '-z separate-code -z max-page-size=4096')
|
||||
LDFLAGS += $(ZSC_FLAGS)
|
||||
|
||||
# compiler.h is needed for our linking and debugging system
|
||||
#
|
||||
CFLAGS += -include include/compiler.h
|
||||
@ -518,10 +523,6 @@ CFLAGS += -include include/compiler.h
|
||||
#
|
||||
CFLAGS += -DASM_TCHAR='$(ASM_TCHAR)' -DASM_TCHAR_OPS='$(ASM_TCHAR_OPS)'
|
||||
|
||||
# Inhibit the default -Dlinux
|
||||
#
|
||||
CFLAGS += -Ulinux
|
||||
|
||||
# CFLAGS for specific object types
|
||||
#
|
||||
CFLAGS_c +=
|
||||
@ -539,6 +540,16 @@ 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)))
|
||||
@ -548,9 +559,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 $@
|
||||
RULE_c = $(Q)$(COMPILE_c) -c $< -o $@ $(POST_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 $@
|
||||
RULE_c_to_dbg%.o= $(Q)$(COMPILE_c) $(call DBGLVL,$*) -c $< -o $@ $(POST_O)
|
||||
RULE_c_to_c = $(Q)$(COMPILE_c) -E -c $< > $@
|
||||
RULE_c_to_s = $(Q)$(COMPILE_c) -S -g0 -c $< -o $@
|
||||
|
||||
@ -790,38 +801,6 @@ 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.
|
||||
@ -893,7 +872,7 @@ endef
|
||||
# $(3) is the source base name (e.g. "rtl8139")
|
||||
#
|
||||
define rules_template_parts
|
||||
$$(BIN)/$(3).o : $(1) $$(MAKEDEPS) $$($(3)_DEPS)
|
||||
$$(BIN)/$(3).o : $(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(3)_DEPS)
|
||||
$$(QM)$(ECHO) " [BUILD] $$@"
|
||||
$$(RULE_$(2))
|
||||
BOBJS += $$(BIN)/$(3).o
|
||||
@ -908,7 +887,7 @@ endef
|
||||
# $(4) is the destination type (e.g. "dbg%.o")
|
||||
#
|
||||
define rules_template_target
|
||||
$$(BIN)/$(3).$(4) : $(1) $$(MAKEDEPS) $$($(3)_DEPS)
|
||||
$$(BIN)/$(3).$(4) : $(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(3)_DEPS)
|
||||
$$(QM)$(ECHO) " [BUILD] $$@"
|
||||
$$(RULE_$(2)_to_$(4))
|
||||
$(TGT)_OBJS += $$(BIN)/$(3).$(4)
|
||||
@ -930,7 +909,7 @@ $(BIN)/deps/%.d : % $(MAKEDEPS)
|
||||
|
||||
# Calculate list of dependency files
|
||||
#
|
||||
AUTO_DEPS = $(patsubst %,$(BIN)/deps/%.d,$(AUTO_SRCS) core/version.c)
|
||||
AUTO_DEPS = $(patsubst %,$(BIN)/deps/%.d,$(AUTO_SRCS))
|
||||
autodeps :
|
||||
@$(ECHO) $(AUTO_DEPS)
|
||||
VERYCLEANUP += $(BIN)/deps
|
||||
@ -1009,7 +988,6 @@ endif
|
||||
# Device ID tables (using IDs from ROM definition file)
|
||||
#
|
||||
define obj_pci_id_asm
|
||||
.section ".note.GNU-stack", "", $(ASM_TCHAR)progbits
|
||||
.section ".pci_devlist.$(1)", "a", $(ASM_TCHAR)progbits
|
||||
.globl pci_devlist_$(1)
|
||||
pci_devlist_$(1):
|
||||
@ -1115,10 +1093,9 @@ TGT_LD_ENTRY = _$(TGT_PREFIX)_start
|
||||
#
|
||||
TGT_LD_FLAGS = $(foreach SYM,$(TGT_LD_ENTRY) $(TGT_LD_DRIVERS) \
|
||||
$(TGT_LD_DEVLIST) obj_config obj_config_$(PLATFORM),\
|
||||
-u $(SYMBOL_PREFIX)$(SYM) \
|
||||
--defsym check_$(SYM)=$(SYMBOL_PREFIX)$(SYM) ) \
|
||||
-u $(SYM) --defsym check_$(SYM)=$(SYM) ) \
|
||||
$(patsubst %,--defsym %,$(TGT_LD_IDS)) \
|
||||
-e $(SYMBOL_PREFIX)$(TGT_LD_ENTRY)
|
||||
-e $(TGT_LD_ENTRY)
|
||||
|
||||
# Calculate list of debugging versions of objects to be included in
|
||||
# the target.
|
||||
@ -1179,43 +1156,23 @@ BLIB = $(BIN)/blib.a
|
||||
$(BLIB) : $(BLIB_OBJS) $(BLIB_LIST) $(MAKEDEPS)
|
||||
$(Q)$(RM) $(BLIB)
|
||||
$(QM)$(ECHO) " [AR] $@"
|
||||
$(Q)$(AR) rcD $@ $(sort $(BLIB_OBJS))
|
||||
$(Q)$(OBJCOPY) --enable-deterministic-archives \
|
||||
--prefix-symbols=$(SYMBOL_PREFIX) $@
|
||||
$(Q)$(RANLIB) -D $@
|
||||
$(Q)$(AR) r $@ $(sort $(BLIB_OBJS))
|
||||
$(Q)$(RANLIB) $@
|
||||
blib : $(BLIB)
|
||||
|
||||
# Command to generate build ID. Must be unique for each $(BIN)/%.tmp,
|
||||
# even within the same build run.
|
||||
#
|
||||
# The build ID is supposed to be collision-free across all ROMs that
|
||||
# might ever end up installed in the same system. It doesn't just
|
||||
# disambiguate targets within a single build; it also disambiguates
|
||||
# different builds (such as builds for multiple ROMs all built from
|
||||
# the same blib.a).
|
||||
#
|
||||
BUILD_ID_CMD = cat $^ | cksum | awk '{print $$1}'
|
||||
BUILD_ID_CMD := perl -e 'printf "0x%08x", int ( rand ( 0xffffffff ) );'
|
||||
|
||||
# Build timestamp
|
||||
#
|
||||
# Used as a means to automatically select the newest version of iPXE
|
||||
# if multiple iPXE drivers are loaded concurrently in a UEFI system.
|
||||
#
|
||||
# It gets rounded down to the nearest minute when used for this
|
||||
# purpose.
|
||||
#
|
||||
ifdef SOURCE_DATE_EPOCH
|
||||
BUILD_TIMESTAMP := $(SOURCE_DATE_EPOCH)
|
||||
else ifdef GITVERSION
|
||||
BUILD_TIMESTAMP := $(shell git log -1 --pretty=%ct)
|
||||
else
|
||||
BUILD_TIMESTAMP := $(shell date +%s)
|
||||
endif
|
||||
|
||||
# Build version
|
||||
#
|
||||
GIT_INDEX := $(if $(GITVERSION),$(if $(wildcard ../.git/index),../.git/index))
|
||||
$(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(version_DEPS) $(GIT_INDEX)
|
||||
$(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(GIT_INDEX)
|
||||
$(QM)$(ECHO) " [VERSION] $@"
|
||||
$(Q)$(COMPILE_c) -DBUILD_NAME="\"$*\"" \
|
||||
-DVERSION_MAJOR=$(VERSION_MAJOR) \
|
||||
@ -1223,7 +1180,6 @@ $(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(version_DEPS) $(GIT_INDEX)
|
||||
-DVERSION_PATCH=$(VERSION_PATCH) \
|
||||
-DVERSION="\"$(VERSION)\"" \
|
||||
-c $< -o $@
|
||||
$(Q)$(OBJCOPY) --prefix-symbols=$(SYMBOL_PREFIX) $@
|
||||
|
||||
# Build an intermediate object file from the objects required for the
|
||||
# specified target.
|
||||
@ -1231,7 +1187,7 @@ $(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(version_DEPS) $(GIT_INDEX)
|
||||
$(BIN)/%.tmp : $(BIN)/version.%.o $(BLIB) $(MAKEDEPS) $(LDSCRIPT)
|
||||
$(QM)$(ECHO) " [LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT) $(TGT_LD_FLAGS) $< $(BLIB) -o $@ \
|
||||
--defsym _build_id=$(shell $(BUILD_ID_CMD)) \
|
||||
--defsym _build_id=`$(BUILD_ID_CMD)` \
|
||||
--defsym _build_timestamp=$(BUILD_TIMESTAMP) \
|
||||
-Map $(BIN)/$*.tmp.map
|
||||
$(Q)$(OBJDUMP) -ht $@ | $(PERL) $(SORTOBJDUMP) >> $(BIN)/$*.tmp.map
|
||||
@ -1442,7 +1398,7 @@ $(ELF2EFI64) : util/elf2efi.c $(MAKEDEPS)
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -DEFI_TARGET64 $< -o $@
|
||||
CLEANUP += $(ELF2EFI64)
|
||||
|
||||
$(EFIROM) : util/efirom.c util/eficompress.c $(MAKEDEPS)
|
||||
$(EFIROM) : util/efirom.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(EFIROM)
|
||||
@ -1452,6 +1408,15 @@ $(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
|
||||
@ -1576,7 +1541,7 @@ endif # defined(BIN)
|
||||
#
|
||||
|
||||
hci/keymap/keymap_%.c :
|
||||
$(Q)$(PYTHON) $(GENKEYMAP) $* > $@
|
||||
$(Q)$(PERL) $(GENKEYMAP) $* > $@
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -1591,14 +1556,13 @@ hci/keymap/keymap_%.c :
|
||||
#
|
||||
|
||||
ifeq ($(NUM_BINS),0)
|
||||
ALLBINS := bin bin-*
|
||||
ALLBIN = $(foreach B,$(ALLBINS),$(patsubst $(BIN)/%,$(B)/%,$(1)))
|
||||
CLEANUP := $(foreach C,$(CLEANUP),$(call ALLBIN,$(C)))
|
||||
VERYCLEANUP := $(foreach V,$(VERYCLEANUP),$(call ALLBIN,$(V)))
|
||||
ALLBINS := bin{,-*}
|
||||
CLEANUP := $(patsubst $(BIN)/%,$(ALLBINS)/%,$(CLEANUP))
|
||||
VERYCLEANUP := $(patsubst $(BIN)/%,$(ALLBINS)/%,$(VERYCLEANUP))
|
||||
endif
|
||||
|
||||
clean :
|
||||
$(RM) -r $(CLEANUP)
|
||||
$(RM) $(CLEANUP)
|
||||
|
||||
veryclean : clean
|
||||
$(RM) -r $(VERYCLEANUP)
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Prefix all iPXE symbols to avoid collisions with platform libraries
|
||||
#
|
||||
SYMBOL_PREFIX = _ipxe__
|
||||
|
||||
# Enable valgrind
|
||||
#
|
||||
CFLAGS += -UNVALGRIND
|
||||
|
||||
# The Linux linker script
|
||||
#
|
||||
LDSCRIPT = scripts/linux.lds
|
||||
|
||||
# Use a two-stage link
|
||||
#
|
||||
LDFLAGS += -r -d
|
||||
|
||||
# Source directories
|
||||
#
|
||||
SRCDIRS += drivers/linux
|
||||
SRCDIRS += interface/linux
|
||||
NON_AUTO_SRCS += interface/linux/linux_api.c
|
||||
|
||||
# Media types
|
||||
#
|
||||
NON_AUTO_MEDIA = linux
|
||||
|
||||
# Compiler flags for building host API wrapper
|
||||
#
|
||||
LINUX_CFLAGS += -Os -idirafter include -DSYMBOL_PREFIX=$(SYMBOL_PREFIX)
|
||||
|
||||
# Check for libslirp
|
||||
#
|
||||
LIBSLIRP_TEST = $(CC) $(LINUX_CFLAGS) -x c /dev/null -nostartfiles \
|
||||
-include slirp/libslirp.h -lslirp \
|
||||
-o /dev/null >/dev/null 2>&1
|
||||
WITH_LIBSLIRP := $(shell $(LIBSLIRP_TEST) && $(ECHO) yes)
|
||||
ifneq ($(WITH_LIBSLIRP),)
|
||||
LINUX_CFLAGS += -DHAVE_LIBSLIRP
|
||||
LINUX_LIBS += -lslirp
|
||||
endif
|
||||
|
||||
# Host API wrapper
|
||||
#
|
||||
$(BIN)/linux_api.o : interface/linux/linux_api.c include/ipxe/linux_api.h \
|
||||
include/ipxe/slirp.h $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [BUILD] $@"
|
||||
$(Q)$(CC) $(LINUX_CFLAGS) $(WORKAROUND_CFLAGS) -o $@ -c $<
|
||||
|
||||
# Rule to generate final binary
|
||||
#
|
||||
$(BIN)/%.linux : $(BIN)/%.linux.tmp $(BIN)/linux_api.o
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)$(CC) $(LINUX_CFLAGS) $(WORKAROUND_CFLAGS) -o $@ $^ $(LINUX_LIBS)
|
||||
@ -9,5 +9,4 @@ INCDIRS += arch/arm/include
|
||||
|
||||
# ARM-specific directories containing source files
|
||||
#
|
||||
SRCDIRS += arch/arm/core
|
||||
SRCDIRS += arch/arm/interface/efi
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += Makefile.linux
|
||||
include Makefile.linux
|
||||
@ -46,7 +46,7 @@ union arm32_io_qword {
|
||||
*
|
||||
* This is not atomic for ARM32.
|
||||
*/
|
||||
static __unused uint64_t arm32_readq ( volatile uint64_t *io_addr ) {
|
||||
static uint64_t arm32_readq ( volatile uint64_t *io_addr ) {
|
||||
volatile union arm32_io_qword *ptr =
|
||||
container_of ( io_addr, union arm32_io_qword, qword );
|
||||
union arm32_io_qword tmp;
|
||||
@ -64,8 +64,7 @@ static __unused uint64_t arm32_readq ( volatile uint64_t *io_addr ) {
|
||||
*
|
||||
* This is not atomic for ARM32.
|
||||
*/
|
||||
static __unused void arm32_writeq ( uint64_t data,
|
||||
volatile uint64_t *io_addr ) {
|
||||
static void arm32_writeq ( uint64_t data, volatile uint64_t *io_addr ) {
|
||||
volatile union arm32_io_qword *ptr =
|
||||
container_of ( io_addr, union arm32_io_qword, qword );
|
||||
union arm32_io_qword tmp;
|
||||
@ -83,6 +82,7 @@ PROVIDE_IOAPI_INLINE ( arm, readl );
|
||||
PROVIDE_IOAPI_INLINE ( arm, writeb );
|
||||
PROVIDE_IOAPI_INLINE ( arm, writew );
|
||||
PROVIDE_IOAPI_INLINE ( arm, writel );
|
||||
PROVIDE_IOAPI_INLINE ( arm, iodelay );
|
||||
PROVIDE_IOAPI_INLINE ( arm, mb );
|
||||
#ifdef __aarch64__
|
||||
PROVIDE_IOAPI_INLINE ( arm, readq );
|
||||
@ -91,4 +91,3 @@ PROVIDE_IOAPI_INLINE ( arm, writeq );
|
||||
PROVIDE_IOAPI ( arm, readq, arm32_readq );
|
||||
PROVIDE_IOAPI ( arm, writeq, arm32_writeq );
|
||||
#endif
|
||||
PROVIDE_DUMMY_PIO ( arm );
|
||||
|
||||
12
src/arch/arm/include/bits/entropy.h
Normal file
12
src/arch/arm/include/bits/entropy.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_ENTROPY_H
|
||||
#define _BITS_ENTROPY_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* ARM-specific entropy API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_ENTROPY_H */
|
||||
@ -9,9 +9,6 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
#include <ipxe/arm_io.h>
|
||||
|
||||
#endif /* _BITS_IO_H */
|
||||
|
||||
@ -9,4 +9,6 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/io.h>
|
||||
|
||||
#endif /* _BITS_PCI_IO_H */
|
||||
|
||||
@ -15,13 +15,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define IOAPI_PREFIX_arm __arm_
|
||||
#endif
|
||||
|
||||
#include <ipxe/dummy_pio.h>
|
||||
|
||||
/*
|
||||
* Memory space mappings
|
||||
*
|
||||
*/
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
/*
|
||||
* Physical<->Bus address mappings
|
||||
*
|
||||
@ -79,6 +80,55 @@ ARM_WRITEX ( w, uint16_t, "h", "" );
|
||||
ARM_WRITEX ( l, uint32_t, "", "" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy PIO reads and writes up to 32 bits
|
||||
*
|
||||
* There is no common standard for I/O-space access for ARM, and
|
||||
* non-MMIO peripherals are vanishingly rare. Provide dummy
|
||||
* implementations that will allow code to link and should cause
|
||||
* drivers to simply fail to detect hardware at runtime.
|
||||
*
|
||||
*/
|
||||
|
||||
#define ARM_INX( _suffix, _type ) \
|
||||
static inline __always_inline _type \
|
||||
IOAPI_INLINE ( arm, in ## _suffix ) ( volatile _type *io_addr __unused) { \
|
||||
return ~( (_type) 0 ); \
|
||||
} \
|
||||
static inline __always_inline void \
|
||||
IOAPI_INLINE ( arm, ins ## _suffix ) ( volatile _type *io_addr __unused, \
|
||||
_type *data, unsigned int count ) { \
|
||||
memset ( data, 0xff, count * sizeof ( *data ) ); \
|
||||
}
|
||||
ARM_INX ( b, uint8_t );
|
||||
ARM_INX ( w, uint16_t );
|
||||
ARM_INX ( l, uint32_t );
|
||||
|
||||
#define ARM_OUTX( _suffix, _type ) \
|
||||
static inline __always_inline void \
|
||||
IOAPI_INLINE ( arm, out ## _suffix ) ( _type data __unused, \
|
||||
volatile _type *io_addr __unused ) { \
|
||||
/* Do nothing */ \
|
||||
} \
|
||||
static inline __always_inline void \
|
||||
IOAPI_INLINE ( arm, outs ## _suffix ) ( volatile _type *io_addr __unused, \
|
||||
const _type *data __unused, \
|
||||
unsigned int count __unused ) { \
|
||||
/* Do nothing */ \
|
||||
}
|
||||
ARM_OUTX ( b, uint8_t );
|
||||
ARM_OUTX ( w, uint16_t );
|
||||
ARM_OUTX ( l, uint32_t );
|
||||
|
||||
/*
|
||||
* Slow down I/O
|
||||
*
|
||||
*/
|
||||
static inline __always_inline void
|
||||
IOAPI_INLINE ( arm, iodelay ) ( void ) {
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/*
|
||||
* Memory barrier
|
||||
*
|
||||
@ -93,7 +143,4 @@ IOAPI_INLINE ( arm, mb ) ( void ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Dummy PIO */
|
||||
DUMMY_PIO ( arm );
|
||||
|
||||
#endif /* _IPXE_ARM_IO_H */
|
||||
|
||||
@ -46,12 +46,8 @@ static void efiarm_cpu_nap ( void ) {
|
||||
* The EFI shell doesn't seem to bother sleeping the CPU; it
|
||||
* just sits there idly burning power.
|
||||
*
|
||||
* If a shutdown is in progess, there may be nothing to
|
||||
* generate an interrupt since the timer is disabled in the
|
||||
* first step of ExitBootServices().
|
||||
*/
|
||||
if ( ! efi_shutdown_in_progress )
|
||||
__asm__ __volatile__ ( "wfi" );
|
||||
__asm__ __volatile__ ( "wfi" );
|
||||
}
|
||||
|
||||
PROVIDE_NAP ( efiarm, cpu_nap, efiarm_cpu_nap );
|
||||
|
||||
@ -5,7 +5,7 @@ SRCDIRS += arch/arm32/libgcc
|
||||
|
||||
# ARM32-specific flags
|
||||
#
|
||||
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs
|
||||
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs -mfloat-abi=soft
|
||||
CFLAGS += -mword-relocations
|
||||
ASFLAGS += -mthumb -mcpu=cortex-a15
|
||||
|
||||
@ -13,11 +13,6 @@ ASFLAGS += -mthumb -mcpu=cortex-a15
|
||||
#
|
||||
CFLAGS += -fshort-wchar
|
||||
|
||||
# EFI requires that enums are always 32 bits, and nothing else
|
||||
# currently cares
|
||||
#
|
||||
CFLAGS += -fno-short-enums
|
||||
|
||||
# Include common ARM Makefile
|
||||
MAKEDEPS += arch/arm/Makefile
|
||||
include arch/arm/Makefile
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# EFI uses the soft float ABI
|
||||
# UEFI requires that enums are always 32 bits
|
||||
#
|
||||
CFLAGS += -mfloat-abi=soft
|
||||
CFLAGS += -fno-short-enums
|
||||
|
||||
# Specify EFI image builder
|
||||
#
|
||||
|
||||
@ -36,23 +36,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
* Multiply big integers
|
||||
*
|
||||
* @v multiplicand0 Element 0 of big integer to be multiplied
|
||||
* @v multiplicand_size Number of elements in multiplicand
|
||||
* @v multiplier0 Element 0 of big integer to be multiplied
|
||||
* @v multiplier_size Number of elements in multiplier
|
||||
* @v result0 Element 0 of big integer to hold result
|
||||
* @v size Number of elements
|
||||
*/
|
||||
void bigint_multiply_raw ( const uint32_t *multiplicand0,
|
||||
unsigned int multiplicand_size,
|
||||
const uint32_t *multiplier0,
|
||||
unsigned int multiplier_size,
|
||||
uint32_t *result0 ) {
|
||||
unsigned int result_size = ( multiplicand_size + multiplier_size );
|
||||
const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
|
||||
*multiplicand = ( ( const void * ) multiplicand0 );
|
||||
const bigint_t ( multiplier_size ) __attribute__ (( may_alias ))
|
||||
*multiplier = ( ( const void * ) multiplier0 );
|
||||
bigint_t ( result_size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
uint32_t *result0, unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
|
||||
( ( const void * ) multiplicand0 );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
|
||||
( ( const void * ) multiplier0 );
|
||||
bigint_t ( size * 2 ) __attribute__ (( may_alias )) *result =
|
||||
( ( void * ) result0 );
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
uint32_t multiplicand_element;
|
||||
@ -66,9 +62,9 @@ void bigint_multiply_raw ( const uint32_t *multiplicand0,
|
||||
memset ( result, 0, sizeof ( *result ) );
|
||||
|
||||
/* Multiply integers one element at a time */
|
||||
for ( i = 0 ; i < multiplicand_size ; i++ ) {
|
||||
for ( i = 0 ; i < size ; i++ ) {
|
||||
multiplicand_element = multiplicand->element[i];
|
||||
for ( j = 0 ; j < multiplier_size ; j++ ) {
|
||||
for ( j = 0 ; j < size ; j++ ) {
|
||||
multiplier_element = multiplier->element[j];
|
||||
result_elements = &result->element[ i + j ];
|
||||
/* Perform a single multiply, and add the
|
||||
@ -77,7 +73,7 @@ void bigint_multiply_raw ( const uint32_t *multiplicand0,
|
||||
* never overflow beyond the end of the
|
||||
* result, since:
|
||||
*
|
||||
* a < 2^{n}, b < 2^{m} => ab < 2^{n+m}
|
||||
* a < 2^{n}, b < 2^{n} => ab < 2^{2n}
|
||||
*/
|
||||
__asm__ __volatile__ ( "umull %1, %2, %5, %6\n\t"
|
||||
"ldr %3, [%0]\n\t"
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
.arm
|
||||
|
||||
|
||||
@ -310,9 +310,7 @@ bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
|
||||
}
|
||||
|
||||
extern void bigint_multiply_raw ( const uint32_t *multiplicand0,
|
||||
unsigned int multiplicand_size,
|
||||
const uint32_t *multiplier0,
|
||||
unsigned int multiplier_size,
|
||||
uint32_t *value0 );
|
||||
uint32_t *value0, unsigned int size );
|
||||
|
||||
#endif /* _BITS_BIGINT_H */
|
||||
|
||||
@ -8,9 +8,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "c"
|
||||
|
||||
#define __asmcall
|
||||
#define __libgcc
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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
|
||||
@ -19,33 +21,20 @@
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <config/entropy.h>
|
||||
#ifndef _DHCP_ARCH_H
|
||||
#define _DHCP_ARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Entropy configuration options
|
||||
*
|
||||
* Architecture-specific DHCP options
|
||||
*/
|
||||
|
||||
PROVIDE_REQUIRING_SYMBOL();
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM32
|
||||
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
/*
|
||||
* Drag in entropy sources
|
||||
*/
|
||||
#ifdef ENTROPY_RTC
|
||||
REQUIRE_OBJECT ( rtc_entropy );
|
||||
#endif
|
||||
#ifdef ENTROPY_EFITICK
|
||||
REQUIRE_OBJECT ( efi_entropy );
|
||||
#endif
|
||||
#ifdef ENTROPY_EFIRNG
|
||||
REQUIRE_OBJECT ( efi_rng );
|
||||
#endif
|
||||
#ifdef ENTROPY_LINUX
|
||||
REQUIRE_OBJECT ( linux_entropy );
|
||||
#endif
|
||||
#ifdef ENTROPY_RDRAND
|
||||
REQUIRE_OBJECT ( rdrand );
|
||||
#endif
|
||||
@ -1,20 +0,0 @@
|
||||
#ifndef _IPXE_EFI_DHCPARCH_H
|
||||
#define _IPXE_EFI_DHCPARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DHCP client architecture definitions
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
/** DHCP client architecture */
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM32
|
||||
|
||||
/** DHCP client network device interface */
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
#endif /* _IPXE_EFI_DHCPARCH_H */
|
||||
@ -1,6 +1,6 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
.thumb
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
.arm
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Avoid untranslatable relocations
|
||||
#
|
||||
CFLAGS += -fno-pic
|
||||
|
||||
# Specify EFI image builder
|
||||
#
|
||||
ELF2EFI = $(ELF2EFI64)
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Starting virtual address
|
||||
#
|
||||
LDFLAGS += -Ttext=0x400000
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += arch/arm/Makefile.linux
|
||||
include arch/arm/Makefile.linux
|
||||
@ -36,23 +36,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
* Multiply big integers
|
||||
*
|
||||
* @v multiplicand0 Element 0 of big integer to be multiplied
|
||||
* @v multiplicand_size Number of elements in multiplicand
|
||||
* @v multiplier0 Element 0 of big integer to be multiplied
|
||||
* @v multiplier_size Number of elements in multiplier
|
||||
* @v result0 Element 0 of big integer to hold result
|
||||
* @v size Number of elements
|
||||
*/
|
||||
void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
unsigned int multiplicand_size,
|
||||
const uint64_t *multiplier0,
|
||||
unsigned int multiplier_size,
|
||||
uint64_t *result0 ) {
|
||||
unsigned int result_size = ( multiplicand_size + multiplier_size );
|
||||
const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
|
||||
*multiplicand = ( ( const void * ) multiplicand0 );
|
||||
const bigint_t ( multiplier_size ) __attribute__ (( may_alias ))
|
||||
*multiplier = ( ( const void * ) multiplier0 );
|
||||
bigint_t ( result_size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
uint64_t *result0, unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
|
||||
( ( const void * ) multiplicand0 );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
|
||||
( ( const void * ) multiplier0 );
|
||||
bigint_t ( size * 2 ) __attribute__ (( may_alias )) *result =
|
||||
( ( void * ) result0 );
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
uint64_t multiplicand_element;
|
||||
@ -67,9 +63,9 @@ void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
memset ( result, 0, sizeof ( *result ) );
|
||||
|
||||
/* Multiply integers one element at a time */
|
||||
for ( i = 0 ; i < multiplicand_size ; i++ ) {
|
||||
for ( i = 0 ; i < size ; i++ ) {
|
||||
multiplicand_element = multiplicand->element[i];
|
||||
for ( j = 0 ; j < multiplier_size ; j++ ) {
|
||||
for ( j = 0 ; j < size ; j++ ) {
|
||||
multiplier_element = multiplier->element[j];
|
||||
result_elements = &result->element[ i + j ];
|
||||
/* Perform a single multiply, and add the
|
||||
@ -78,7 +74,7 @@ void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
* never overflow beyond the end of the
|
||||
* result, since:
|
||||
*
|
||||
* a < 2^{n}, b < 2^{m} => ab < 2^{n+m}
|
||||
* a < 2^{n}, b < 2^{n} => ab < 2^{2n}
|
||||
*/
|
||||
__asm__ __volatile__ ( "mul %1, %6, %7\n\t"
|
||||
"umulh %2, %6, %7\n\t"
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
|
||||
/* Must match jmp_buf structure layout */
|
||||
|
||||
@ -311,9 +311,7 @@ bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
|
||||
}
|
||||
|
||||
extern void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
unsigned int multiplicand_size,
|
||||
const uint64_t *multiplier0,
|
||||
unsigned int multiplier_size,
|
||||
uint64_t *value0 );
|
||||
uint64_t *value0, unsigned int size );
|
||||
|
||||
#endif /* _BITS_BIGINT_H */
|
||||
|
||||
@ -8,9 +8,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "c"
|
||||
|
||||
#define __asmcall
|
||||
#define __libgcc
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
* Copyright (C) 2015 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
|
||||
@ -21,25 +21,20 @@
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
#ifndef _DHCP_ARCH_H
|
||||
#define _DHCP_ARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Architecture-specific DHCP options
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/x25519.h>
|
||||
#include <ipxe/asn1.h>
|
||||
#include <ipxe/tls.h>
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
/** "x25519" object identifier */
|
||||
static uint8_t oid_x25519[] = { ASN1_OID_X25519 };
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM64
|
||||
|
||||
/** "x25519" OID-identified algorithm */
|
||||
struct asn1_algorithm x25519_algorithm __asn1_algorithm = {
|
||||
.name = "x25519",
|
||||
.curve = &x25519_curve,
|
||||
.oid = ASN1_CURSOR ( oid_x25519 ),
|
||||
};
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
/** X25519 named curve */
|
||||
struct tls_named_curve tls_x25519_named_curve __tls_named_curve ( 01 ) = {
|
||||
.curve = &x25519_curve,
|
||||
.code = htons ( TLS_NAMED_CURVE_X25519 ),
|
||||
};
|
||||
#endif
|
||||
@ -1,20 +0,0 @@
|
||||
#ifndef _IPXE_EFI_DHCPARCH_H
|
||||
#define _IPXE_EFI_DHCPARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DHCP client architecture definitions
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
/** DHCP client architecture */
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM64
|
||||
|
||||
/** DHCP client network device interface */
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
#endif /* _IPXE_EFI_DHCPARCH_H */
|
||||
@ -69,6 +69,22 @@ 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
|
||||
|
||||
@ -1,14 +1,6 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
LDSCRIPT = arch/i386/scripts/linux.lds
|
||||
|
||||
# Starting virtual address
|
||||
#
|
||||
LDFLAGS += -Ttext=0x08048000
|
||||
SRCDIRS += arch/i386/core/linux
|
||||
|
||||
# Compiler flags for building host API wrapper
|
||||
#
|
||||
LINUX_CFLAGS += -m32
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += arch/x86/Makefile.linux
|
||||
include arch/x86/Makefile.linux
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
* Interrupt handlers
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".note.GNU-stack", "", @progbits
|
||||
.section ".text", "ax", @progbits
|
||||
.code32
|
||||
|
||||
|
||||
45
src/arch/i386/core/linux/linux_syscall.S
Normal file
45
src/arch/i386/core/linux/linux_syscall.S
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
.section ".data"
|
||||
.globl linux_errno
|
||||
|
||||
linux_errno: .int 0
|
||||
|
||||
.section ".text"
|
||||
.code32
|
||||
.globl linux_syscall
|
||||
.type linux_syscall, @function
|
||||
|
||||
linux_syscall:
|
||||
/* Save registers */
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %ebp
|
||||
|
||||
movl 20(%esp), %eax // C arg1 -> syscall number
|
||||
movl 24(%esp), %ebx // C arg2 -> syscall arg1
|
||||
movl 28(%esp), %ecx // C arg3 -> syscall arg2
|
||||
movl 32(%esp), %edx // C arg4 -> syscall arg3
|
||||
movl 36(%esp), %esi // C arg5 -> syscall arg4
|
||||
movl 40(%esp), %edi // C arg6 -> syscall arg5
|
||||
movl 44(%esp), %ebp // C arg7 -> syscall arg6
|
||||
|
||||
int $0x80
|
||||
|
||||
/* Restore registers */
|
||||
popl %ebp
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
|
||||
cmpl $-4095, %eax
|
||||
jae 1f
|
||||
ret
|
||||
|
||||
1:
|
||||
negl %eax
|
||||
movl %eax, linux_errno
|
||||
movl $-1, %eax
|
||||
ret
|
||||
|
||||
.size linux_syscall, . - linux_syscall
|
||||
28
src/arch/i386/core/linux/linuxprefix.S
Normal file
28
src/arch/i386/core/linux/linuxprefix.S
Normal file
@ -0,0 +1,28 @@
|
||||
#include <linux/unistd.h>
|
||||
|
||||
.section ".text"
|
||||
.code32
|
||||
.globl _linux_start
|
||||
.type _linux_start, @function
|
||||
|
||||
_linux_start:
|
||||
xorl %ebp, %ebp
|
||||
|
||||
popl %esi // save argc
|
||||
movl %esp, %edi // save argv
|
||||
|
||||
andl $~15, %esp // 16-byte align the stack
|
||||
|
||||
pushl %edi // argv -> C arg2
|
||||
pushl %esi // argc -> C arg1
|
||||
|
||||
call save_args
|
||||
|
||||
/* Our main doesn't use any arguments */
|
||||
call main
|
||||
|
||||
movl %eax, %ebx // rc -> syscall arg1
|
||||
movl $__NR_exit, %eax
|
||||
int $0x80
|
||||
|
||||
.size _linux_start, . - _linux_start
|
||||
@ -1,9 +1,8 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", @progbits
|
||||
.text
|
||||
.code32
|
||||
.arch i386
|
||||
.code32
|
||||
|
||||
/* Must match jmp_buf structure layout */
|
||||
.struct 0
|
||||
|
||||
@ -8,11 +8,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "c"
|
||||
|
||||
/** Declare a function with standard calling conventions */
|
||||
#define __asmcall __attribute__ (( cdecl, regparm(0) ))
|
||||
#define __asmcall __attribute__ (( used, cdecl, regparm(0) ))
|
||||
|
||||
/**
|
||||
* Declare a function with libgcc implicit linkage
|
||||
|
||||
6
src/arch/i386/include/bits/linux_api.h
Normal file
6
src/arch/i386/include/bits/linux_api.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _I386_LINUX_API_H
|
||||
#define _I386_LINUX_API_H
|
||||
|
||||
#define __SYSCALL_mmap __NR_mmap2
|
||||
|
||||
#endif /* _I386_LINUX_API_H */
|
||||
40
src/arch/i386/include/efi/ipxe/dhcp_arch.h
Normal file
40
src/arch/i386/include/efi/ipxe/dhcp_arch.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2010 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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 (at your option) 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.
|
||||
*/
|
||||
|
||||
#ifndef _DHCP_ARCH_H
|
||||
#define _DHCP_ARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Architecture-specific DHCP options
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_IA32
|
||||
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
#endif
|
||||
@ -1,20 +0,0 @@
|
||||
#ifndef _IPXE_EFI_DHCPARCH_H
|
||||
#define _IPXE_EFI_DHCPARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DHCP client architecture definitions
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
/** DHCP client architecture */
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_IA32
|
||||
|
||||
/** DHCP client network device interface */
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
#endif /* _IPXE_EFI_DHCPARCH_H */
|
||||
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2010 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
@ -19,18 +21,20 @@
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <config/general.h>
|
||||
#ifndef _DHCP_ARCH_H
|
||||
#define _DHCP_ARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Archive image configuration
|
||||
*
|
||||
* Architecture-specific DHCP options
|
||||
*/
|
||||
|
||||
PROVIDE_REQUIRING_SYMBOL();
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
|
||||
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
|
||||
|
||||
#ifdef IMAGE_ARCHIVE_CMD
|
||||
REQUIRE_OBJECT ( image_archive_cmd );
|
||||
#endif
|
||||
@ -136,8 +136,6 @@ SECTIONS {
|
||||
*(.note.*)
|
||||
*(.discard)
|
||||
*(.discard.*)
|
||||
*(.sbat)
|
||||
*(.sbat.*)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
/* -*- sh -*- */
|
||||
|
||||
/*
|
||||
* Linker script for Linux images
|
||||
* Linker script for i386 Linux images
|
||||
*
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
|
||||
OUTPUT_ARCH ( i386 )
|
||||
|
||||
SECTIONS {
|
||||
_max_align = 32;
|
||||
|
||||
. = 0x08048000;
|
||||
|
||||
/*
|
||||
* The text section
|
||||
*
|
||||
@ -81,18 +86,19 @@ SECTIONS {
|
||||
_assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" );
|
||||
|
||||
/*
|
||||
* Dispose of unwanted sections to make the link map easier to read
|
||||
* Dispose of the comment and note sections to make the link map
|
||||
* easier to read
|
||||
*
|
||||
*/
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.comment.*)
|
||||
*(.note)
|
||||
*(.note.*)
|
||||
*(.rel)
|
||||
*(.rel.*)
|
||||
*(.discard)
|
||||
*(.discard.*)
|
||||
*(.sbat)
|
||||
*(.sbat.*)
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,3 @@
|
||||
.section ".note.GNU-stack", "", @progbits
|
||||
.code32
|
||||
.arch i386
|
||||
|
||||
.section ".data", "aw", @progbits
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
# Assembler section type character
|
||||
#
|
||||
ASM_TCHAR := @
|
||||
ASM_TCHAR_OPS := @
|
||||
|
||||
# LoongArch64-specific flags
|
||||
#
|
||||
CFLAGS += -fstrength-reduce -fomit-frame-pointer
|
||||
CFLAGS += -falign-jumps=1 -falign-loops=1 -falign-functions=1
|
||||
|
||||
# Check if -mno-explicit-relocs is valid
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
MNER_TEST = $(CC) -mno-explicit-relocs -x c -c /dev/null -o /dev/null >/dev/null 2>&1
|
||||
MNER_FLAGS := $(shell $(MNER_TEST) && $(ECHO) '-mno-explicit-relocs')
|
||||
WORKAROUND_CFLAGS += $(MNER_FLAGS)
|
||||
endif
|
||||
|
||||
# EFI requires -fshort-wchar, and nothing else currently uses wchar_t
|
||||
CFLAGS += -fshort-wchar
|
||||
|
||||
# LoongArch64-specific directories containing source files
|
||||
SRCDIRS += arch/loong64/core
|
||||
SRCDIRS += arch/loong64/interface/efi
|
||||
|
||||
# Include platform-specific Makefile
|
||||
MAKEDEPS += arch/loong64/Makefile.$(PLATFORM)
|
||||
include arch/loong64/Makefile.$(PLATFORM)
|
||||
@ -1,14 +0,0 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Specify EFI image builder
|
||||
#
|
||||
ELF2EFI = $(ELF2EFI64)
|
||||
|
||||
# Specify EFI boot file
|
||||
#
|
||||
EFI_BOOT_FILE = bootloongarch64.efi
|
||||
|
||||
# Include generic EFI Makefile
|
||||
#
|
||||
MAKEDEPS += Makefile.efi
|
||||
include Makefile.efi
|
||||
@ -1,10 +0,0 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Starting virtual address
|
||||
#
|
||||
LDFLAGS += -Ttext=0x120000000
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += Makefile.linux
|
||||
include Makefile.linux
|
||||
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
* Copyright (c) 2023, Xiaotian Wu <wuxiaotian@loongson.cn>
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <ipxe/bigint.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Big integer support
|
||||
*/
|
||||
|
||||
/**
|
||||
* Multiply big integers
|
||||
*
|
||||
* @v multiplicand0 Element 0 of big integer to be multiplied
|
||||
* @v multiplicand_size Number of elements in multiplicand
|
||||
* @v multiplier0 Element 0 of big integer to be multiplied
|
||||
* @v multiplier_size Number of elements in multiplier
|
||||
* @v result0 Element 0 of big integer to hold result
|
||||
*/
|
||||
void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
unsigned int multiplicand_size,
|
||||
const uint64_t *multiplier0,
|
||||
unsigned int multiplier_size,
|
||||
uint64_t *result0 ) {
|
||||
unsigned int result_size = ( multiplicand_size + multiplier_size );
|
||||
const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
|
||||
*multiplicand = ( ( const void * ) multiplicand0 );
|
||||
const bigint_t ( multiplier_size ) __attribute__ (( may_alias ))
|
||||
*multiplier = ( ( const void * ) multiplier0 );
|
||||
bigint_t ( result_size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
uint64_t multiplicand_element;
|
||||
uint64_t multiplier_element;
|
||||
uint64_t *result_elements;
|
||||
uint64_t discard_low;
|
||||
uint64_t discard_high;
|
||||
uint64_t discard_temp_low;
|
||||
uint64_t discard_temp_high;
|
||||
|
||||
/* Zero result */
|
||||
memset ( result, 0, sizeof ( *result ) );
|
||||
|
||||
/* Multiply integers one element at a time */
|
||||
for ( i = 0 ; i < multiplicand_size ; i++ ) {
|
||||
multiplicand_element = multiplicand->element[i];
|
||||
for ( j = 0 ; j < multiplier_size ; j++ ) {
|
||||
multiplier_element = multiplier->element[j];
|
||||
result_elements = &result->element[ i + j ];
|
||||
/* Perform a single multiply, and add the
|
||||
* resulting double-element into the result,
|
||||
* carrying as necessary. The carry can
|
||||
* never overflow beyond the end of the
|
||||
* result, since:
|
||||
*
|
||||
* a < 2^{n}, b < 2^{m} => ab < 2^{n+m}
|
||||
*/
|
||||
__asm__ __volatile__ ( "mul.d %1, %6, %7\n\t"
|
||||
"mulh.du %2, %6, %7\n\t"
|
||||
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"ld.d %4, %0, 8\n\t"
|
||||
|
||||
"add.d %3, %3, %1\n\t"
|
||||
"sltu $t0, %3, %1\n\t"
|
||||
|
||||
"add.d %4, %4, %2\n\t"
|
||||
"sltu $t1, %4, %2\n\t"
|
||||
|
||||
"add.d %4, %4, $t0\n\t"
|
||||
"sltu $t0, %4, $t0\n\t"
|
||||
"or $t0, $t0, $t1\n\t"
|
||||
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"st.d %4, %0, 8\n\t"
|
||||
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"beqz $t0, 2f\n"
|
||||
"1:\n\t"
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"add.d %3, %3, $t0\n\t"
|
||||
"sltu $t0, %3, $t0\n\t"
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"bnez $t0, 1b\n"
|
||||
"2:"
|
||||
: "+r" ( result_elements ),
|
||||
"=&r" ( discard_low ),
|
||||
"=&r" ( discard_high ),
|
||||
"=r" ( discard_temp_low ),
|
||||
"=r" ( discard_temp_high ),
|
||||
"+m" ( *result )
|
||||
: "r" ( multiplicand_element ),
|
||||
"r" ( multiplier_element )
|
||||
: "t0", "t1" );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Xiaotian Wu <wuxiaotian@loongson.cn>
|
||||
*
|
||||
* 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 <ipxe/io.h>
|
||||
#include <ipxe/loong64_io.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* iPXE I/O API for LoongArch64
|
||||
*
|
||||
*/
|
||||
|
||||
PROVIDE_IOAPI_INLINE ( loong64, phys_to_bus );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, bus_to_phys );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, readb );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, readw );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, readl );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, readq );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, writeb );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, writew );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, writel );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, writeq );
|
||||
PROVIDE_IOAPI_INLINE ( loong64, mb );
|
||||
PROVIDE_DUMMY_PIO ( loong64 );
|
||||
@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
* Copyright (c) 2023, Xiaotian Wu <wuxiaotian@loongson.cn>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Optimised string operations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Copy memory area
|
||||
*
|
||||
* @v dest Destination address
|
||||
* @v src Source address
|
||||
* @v len Length
|
||||
* @ret dest Destination address
|
||||
*/
|
||||
void loong64_memcpy ( void *dest, const void *src, size_t len ) {
|
||||
void *discard_dest;
|
||||
void *discard_end;
|
||||
const void *discard_src;
|
||||
size_t discard_offset;
|
||||
unsigned long discard_data;
|
||||
unsigned long discard_low;
|
||||
unsigned long discard_high;
|
||||
|
||||
/* If length is too short, then just copy individual bytes.
|
||||
*/
|
||||
if ( len < 16 ) {
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"ldx.b %1, %3, %0\n\t"
|
||||
"stx.b %1, %2, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset ),
|
||||
"=&r" ( discard_data )
|
||||
: "r" ( dest ), "r" ( src ), "0" ( len )
|
||||
: "memory", "t0" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy 16 bytes at a time: one initial
|
||||
* potentially unaligned access, multiple destination-aligned
|
||||
* accesses, one final potentially unaligned access.
|
||||
*/
|
||||
__asm__ __volatile__ ( "ld.d %3, %1, 0\n\t"
|
||||
"ld.d %4, %1, 8\n\t"
|
||||
"addi.d %1, %1, 16\n\t"
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"st.d %4, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"andi %3, %0, 15\n\t"
|
||||
"sub.d %0, %0, %3\n\t"
|
||||
"sub.d %1, %1, %3\n\t"
|
||||
"addi.d $t0, $zero, 0xf\n\t"
|
||||
"andn %2, %5, $t0\n\t"
|
||||
"b 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"ld.d %3, %1, 0\n\t"
|
||||
"ld.d %4, %1, 8\n\t"
|
||||
"addi.d %1, %1, 16\n\t"
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"st.d %4, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"\n2:\n\t"
|
||||
"bne %0, %2, 1b\n\t"
|
||||
"ld.d %3, %6, -16\n\t"
|
||||
"ld.d %4, %6, -8\n\t"
|
||||
"st.d %3, %5, -16\n\t"
|
||||
"st.d %4, %5, -8\n\t"
|
||||
: "=&r" ( discard_dest ),
|
||||
"=&r" ( discard_src ),
|
||||
"=&r" ( discard_end ),
|
||||
"=&r" ( discard_low ),
|
||||
"=&r" ( discard_high )
|
||||
: "r" ( dest + len ), "r" ( src + len ),
|
||||
"0" ( dest ), "1" ( src )
|
||||
: "memory", "t0" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_bzero ( void *dest, size_t len ) {
|
||||
size_t discard_offset;
|
||||
void *discard_dest;
|
||||
void *discard_end;
|
||||
|
||||
/* If length is too short, then just zero individual bytes.
|
||||
*/
|
||||
if ( len < 16 ) {
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"stx.b $zero, %1, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset )
|
||||
: "r" ( dest ), "0" ( len )
|
||||
: "memory" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* To zero 16 bytes at a time: one initial
|
||||
* potentially unaligned access, multiple aligned accesses,
|
||||
* one final potentially unaligned access.
|
||||
*/
|
||||
|
||||
__asm__ __volatile__ ( "st.d $zero, %0, 0\n\t"
|
||||
"st.d $zero, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"addi.w $t0, $zero, 15\n\t"
|
||||
"andn %0, %0, $t0\n\t"
|
||||
"addi.w $t0, $zero, 15\n\t"
|
||||
"andn %1, %2, $t0\n\t"
|
||||
"b 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"st.d $zero, %0, 0\n\t"
|
||||
"st.d $zero, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"\n2:\n\t"
|
||||
"bne %0, %1, 1b\n\t"
|
||||
"st.d $zero, %2, -16\n\t"
|
||||
"st.d $zero, %2, -8\n\t"
|
||||
: "=&r" ( discard_dest ),
|
||||
"=&r" ( discard_end )
|
||||
: "r" ( dest + len ), "0" ( dest )
|
||||
: "memory", "t0" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v len Length
|
||||
* @v character Fill character
|
||||
*
|
||||
* The unusual parameter order is to allow for more efficient
|
||||
* tail-calling to loong64_memset() when zeroing a region.
|
||||
*/
|
||||
void loong64_memset ( void *dest, size_t len, int character ) {
|
||||
size_t discard_offset;
|
||||
|
||||
/* Use optimised zeroing code if applicable */
|
||||
if ( character == 0 ) {
|
||||
loong64_bzero ( dest, len );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fill one byte at a time. Calling memset() with a non-zero
|
||||
* value is relatively rare and unlikely to be
|
||||
* performance-critical.
|
||||
*/
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"stx.b %2, %1, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset )
|
||||
: "r" ( dest ), "r" ( character ), "0" ( len )
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region forwards
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_memmove_forwards ( void *dest, const void *src, size_t len ) {
|
||||
void *discard_dest;
|
||||
const void *discard_src;
|
||||
unsigned long discard_data;
|
||||
|
||||
/* Assume memmove() is not performance-critical, and perform a
|
||||
* bytewise copy for simplicity.
|
||||
*/
|
||||
__asm__ __volatile__ ( "b 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"ld.b %2, %1, 0\n\t"
|
||||
"addi.d %1, %1, 1\n\t"
|
||||
"st.b %2, %0, 0\n\t"
|
||||
"addi.d %0, %0, 1\n\t"
|
||||
"\n2:\n\t"
|
||||
"bne %0, %3, 1b\n\t"
|
||||
: "=&r" ( discard_dest ),
|
||||
"=&r" ( discard_src ),
|
||||
"=&r" ( discard_data )
|
||||
: "r" ( dest + len ), "0" ( dest ), "1" ( src )
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region backwards
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_memmove_backwards ( void *dest, const void *src, size_t len ) {
|
||||
size_t discard_offset;
|
||||
unsigned long discard_data;
|
||||
|
||||
/* Assume memmove() is not performance-critical, and perform a
|
||||
* bytewise copy for simplicity.
|
||||
*/
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"ldx.b %1, %3, %0\n\t"
|
||||
"stx.b %1, %2, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset ),
|
||||
"=&r" ( discard_data )
|
||||
: "r" ( dest ), "r" ( src ), "0" ( len )
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_memmove ( void *dest, const void *src, size_t len ) {
|
||||
|
||||
if ( dest <= src ) {
|
||||
loong64_memmove_forwards ( dest, src, len );
|
||||
} else {
|
||||
loong64_memmove_backwards ( dest, src, len );
|
||||
}
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
/*
|
||||
int setjmp(jmp_buf env);
|
||||
*/
|
||||
.globl setjmp
|
||||
.type setjmp, %function
|
||||
setjmp:
|
||||
/* Store registers */
|
||||
st.d $s0, $a0, 0x0
|
||||
st.d $s1, $a0, 0x8
|
||||
st.d $s2, $a0, 0x10
|
||||
st.d $s3, $a0, 0x18
|
||||
st.d $s4, $a0, 0x20
|
||||
st.d $s5, $a0, 0x28
|
||||
st.d $s6, $a0, 0x30
|
||||
st.d $s7, $a0, 0x38
|
||||
st.d $s8, $a0, 0x40
|
||||
st.d $fp, $a0, 0x48
|
||||
st.d $sp, $a0, 0x50
|
||||
st.d $ra, $a0, 0x58
|
||||
|
||||
move $a0, $zero
|
||||
jirl $zero, $ra, 0
|
||||
.size setjmp, . - setjmp
|
||||
|
||||
/*
|
||||
void longjmp(jmp_buf env, int val);
|
||||
*/
|
||||
.globl longjmp
|
||||
.type longjmp, %function
|
||||
longjmp:
|
||||
/* Restore registers */
|
||||
ld.d $s0, $a0, 0x0
|
||||
ld.d $s1, $a0, 0x8
|
||||
ld.d $s2, $a0, 0x10
|
||||
ld.d $s3, $a0, 0x18
|
||||
ld.d $s4, $a0, 0x20
|
||||
ld.d $s5, $a0, 0x28
|
||||
ld.d $s6, $a0, 0x30
|
||||
ld.d $s7, $a0, 0x38
|
||||
ld.d $s8, $a0, 0x40
|
||||
ld.d $fp, $a0, 0x48
|
||||
ld.d $sp, $a0, 0x50
|
||||
ld.d $ra, $a0, 0x58
|
||||
addi.d $a0, $zero, 1 # a0 = 1
|
||||
beqz $a1, .exit # if (a1 == 0); goto L0
|
||||
move $a0, $a1 # a0 = a1
|
||||
.exit:
|
||||
jirl $zero, $ra, 0
|
||||
.size longjmp, . - longjmp
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_ACPI_H
|
||||
#define _BITS_ACPI_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific ACPI API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_ACPI_H */
|
||||
@ -1,366 +0,0 @@
|
||||
#ifndef _BITS_BIGINT_H
|
||||
#define _BITS_BIGINT_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Big integer support
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
/** Element of a big integer */
|
||||
typedef uint64_t bigint_element_t;
|
||||
|
||||
/**
|
||||
* Initialise big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer to initialise
|
||||
* @v size Number of elements
|
||||
* @v data Raw data
|
||||
* @v len Length of raw data
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_init_raw ( uint64_t *value0, unsigned int size,
|
||||
const void *data, size_t len ) {
|
||||
size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
|
||||
uint8_t *value_byte = ( ( void * ) value0 );
|
||||
const uint8_t *data_byte = ( data + len );
|
||||
|
||||
/* Copy raw data in reverse order, padding with zeros */
|
||||
while ( len-- )
|
||||
*(value_byte++) = *(--data_byte);
|
||||
while ( pad_len-- )
|
||||
*(value_byte++) = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add big integers
|
||||
*
|
||||
* @v addend0 Element 0 of big integer to add
|
||||
* @v value0 Element 0 of big integer to be added to
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_add_raw ( const uint64_t *addend0, uint64_t *value0,
|
||||
unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_addend;
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_addend_i;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load addend[i] and value[i] */
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"ld.d %4, %1, 0\n\t"
|
||||
/* Add carry flag and addend */
|
||||
"add.d %4, %4, %5\n\t"
|
||||
"sltu %6, %4, %5\n\t"
|
||||
"add.d %4, %4, %3\n\t"
|
||||
"sltu %5, %4, %3\n\t"
|
||||
"or %5, %5, %6\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %4, %1, 0\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"addi.d %1, %1, 8\n\t"
|
||||
"addi.w %2, %2, -1\n\t"
|
||||
"bnez %2, 1b\n\t"
|
||||
: "=r" ( discard_addend ),
|
||||
"=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_addend_i ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( addend0 ), "1" ( value0 ),
|
||||
"2" ( size ), "5" ( 0 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract big integers
|
||||
*
|
||||
* @v subtrahend0 Element 0 of big integer to subtract
|
||||
* @v value0 Element 0 of big integer to be subtracted from
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_subtract_raw ( const uint64_t *subtrahend0, uint64_t *value0,
|
||||
unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_subtrahend;
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_subtrahend_i;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load subtrahend[i] and value[i] */
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"ld.d %4, %1, 0\n\t"
|
||||
/* Subtract carry flag and subtrahend */
|
||||
"sltu %6, %4, %5\n\t"
|
||||
"sub.d %4, %4, %5\n\t"
|
||||
"sltu %5, %4, %3\n\t"
|
||||
"sub.d %4, %4, %3\n\t"
|
||||
"or %5, %5, %6\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %4, %1, 0\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"addi.d %1, %1, 8\n\t"
|
||||
"addi.w %2, %2, -1\n\t"
|
||||
"bnez %2, 1b\n\t"
|
||||
: "=r" ( discard_subtrahend ),
|
||||
"=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_subtrahend_i ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( subtrahend0 ), "1" ( value0 ),
|
||||
"2" ( size ), "5" ( 0 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate big integer left
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_rol_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
"ld.d %2, %0, 0\n\t"
|
||||
/* Shift left */
|
||||
"rotri.d %2, %2, 63\n\t"
|
||||
"andi %4, %2, 1\n\t"
|
||||
"xor %2, %2, %4\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"move %3, %4\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %2, %0, 0\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"addi.w %1, %1, -1\n\t"
|
||||
"bnez %1, 1b\n\t"
|
||||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 ), "1" ( size ), "3" ( 0 )
|
||||
: "cc" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate big integer right
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_ror_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
"ld.d %2, %0, -8\n\t"
|
||||
/* Shift right */
|
||||
"andi %4, %2, 1\n\t"
|
||||
"xor %2, %2, %4\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"move %3, %4\n\t"
|
||||
"rotri.d %2, %2, 1\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %2, %0, -8\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, -8\n\t"
|
||||
"addi.w %1, %1, -1\n\t"
|
||||
"bnez %1, 1b\n\t"
|
||||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 + size ), "1" ( size ), "3" ( 0 )
|
||||
: "cc" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if big integer is equal to zero
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret is_zero Big integer is equal to zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline, pure )) int
|
||||
bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) {
|
||||
const uint64_t *value = value0;
|
||||
uint64_t value_i;
|
||||
|
||||
do {
|
||||
value_i = *(value++);
|
||||
if ( value_i )
|
||||
break;
|
||||
} while ( --size );
|
||||
|
||||
return ( value_i == 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare big integers
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v reference0 Element 0 of reference big integer
|
||||
* @v size Number of elements
|
||||
* @ret geq Big integer is greater than or equal to the reference
|
||||
*/
|
||||
static inline __attribute__ (( always_inline, pure )) int
|
||||
bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0,
|
||||
unsigned int size ) {
|
||||
const uint64_t *value = ( value0 + size );
|
||||
const uint64_t *reference = ( reference0 + size );
|
||||
uint64_t value_i;
|
||||
uint64_t reference_i;
|
||||
|
||||
do {
|
||||
value_i = *(--value);
|
||||
reference_i = *(--reference);
|
||||
if ( value_i != reference_i )
|
||||
break;
|
||||
} while ( --size );
|
||||
|
||||
return ( value_i >= reference_i );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if bit is set in big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @v bit Bit to test
|
||||
* @ret is_set Bit is set
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_bit_is_set_raw ( const uint64_t *value0, unsigned int size,
|
||||
unsigned int bit ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( const void * ) value0 );
|
||||
unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
|
||||
unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
|
||||
|
||||
return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find highest bit set in big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret max_bit Highest bit set + 1 (or 0 if no bits set)
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) {
|
||||
const uint64_t *value = ( value0 + size );
|
||||
int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
|
||||
uint64_t value_i;
|
||||
|
||||
do {
|
||||
value_i = *(--value);
|
||||
max_bit -= ( 64 - fls ( value_i ) );
|
||||
if ( value_i )
|
||||
break;
|
||||
} while ( --size );
|
||||
|
||||
return max_bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grow big integer
|
||||
*
|
||||
* @v source0 Element 0 of source big integer
|
||||
* @v source_size Number of elements in source big integer
|
||||
* @v dest0 Element 0 of destination big integer
|
||||
* @v dest_size Number of elements in destination big integer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_grow_raw ( const uint64_t *source0, unsigned int source_size,
|
||||
uint64_t *dest0, unsigned int dest_size ) {
|
||||
unsigned int pad_size = ( dest_size - source_size );
|
||||
|
||||
memcpy ( dest0, source0, sizeof ( bigint_t ( source_size ) ) );
|
||||
memset ( ( dest0 + source_size ), 0, sizeof ( bigint_t ( pad_size ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shrink big integer
|
||||
*
|
||||
* @v source0 Element 0 of source big integer
|
||||
* @v source_size Number of elements in source big integer
|
||||
* @v dest0 Element 0 of destination big integer
|
||||
* @v dest_size Number of elements in destination big integer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_shrink_raw ( const uint64_t *source0, unsigned int source_size __unused,
|
||||
uint64_t *dest0, unsigned int dest_size ) {
|
||||
|
||||
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalise big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer to finalise
|
||||
* @v size Number of elements
|
||||
* @v out Output buffer
|
||||
* @v len Length of output buffer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
|
||||
void *out, size_t len ) {
|
||||
const uint8_t *value_byte = ( ( const void * ) value0 );
|
||||
uint8_t *out_byte = ( out + len );
|
||||
|
||||
/* Copy raw data in reverse order */
|
||||
while ( len-- )
|
||||
*(--out_byte) = *(value_byte++);
|
||||
}
|
||||
|
||||
extern void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
unsigned int multiplicand_size,
|
||||
const uint64_t *multiplier0,
|
||||
unsigned int multiplier_size,
|
||||
uint64_t *value0 );
|
||||
|
||||
#endif /* _BITS_BIGINT_H */
|
||||
@ -1,102 +0,0 @@
|
||||
#ifndef _BITS_BITOPS_H
|
||||
#define _BITS_BITOPS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* loongArch bit operations
|
||||
*
|
||||
* We perform atomic bit set and bit clear operations using "ll"
|
||||
* and "sc". We use the output constraint to inform the
|
||||
* compiler that any memory from the start of the bit field up to and
|
||||
* including the byte containing the bit may be modified. (This is
|
||||
* overkill but shouldn't matter in practice since we're unlikely to
|
||||
* subsequently read other bits from the same bit field.)
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Test and set bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
* @ret old Old value of bit (zero or non-zero)
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
test_and_set_bit ( unsigned int bit, volatile void *bits ) {
|
||||
unsigned int index = ( bit / 64 );
|
||||
unsigned int offset = ( bit % 64 );
|
||||
volatile uint64_t *qword = ( ( ( volatile uint64_t * ) bits ) + index );
|
||||
uint64_t mask = ( 1UL << offset );
|
||||
uint64_t old;
|
||||
uint64_t new;
|
||||
|
||||
__asm__ __volatile__ ( "1: \n\t"
|
||||
"ll.d %[old], %[qword] \n\t"
|
||||
"or %[new], %[old], %[mask] \n\t"
|
||||
"sc.d %[new], %[qword] \n\t"
|
||||
"beqz %[new], 1b \n\t"
|
||||
: [old] "=&r" ( old ),
|
||||
[new] "=&r" ( new ),
|
||||
[qword] "+m" ( *qword )
|
||||
: [mask] "r" ( mask )
|
||||
: "cc", "memory");
|
||||
return ( !! ( old & mask ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test and clear bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
* @ret old Old value of bit (zero or non-zero)
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
|
||||
unsigned int index = ( bit / 64 );
|
||||
unsigned int offset = ( bit % 64 );
|
||||
volatile uint64_t *qword = ( ( ( volatile uint64_t * ) bits ) + index );
|
||||
uint64_t mask = ( 1UL << offset );
|
||||
uint64_t old;
|
||||
uint64_t new;
|
||||
|
||||
__asm__ __volatile__ ( "1: \n\t"
|
||||
"ll.d %[old], %[qword] \n\t"
|
||||
"andn %[new], %[old], %[mask] \n\t"
|
||||
"sc.d %[new], %[qword] \n\t"
|
||||
"beqz %[new], 1b \n\t"
|
||||
: [old] "=&r" ( old ),
|
||||
[new] "=&r" ( new ),
|
||||
[qword] "+m" ( *qword )
|
||||
: [mask] "r" ( mask )
|
||||
: "cc", "memory");
|
||||
return ( !! ( old & mask ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
set_bit ( unsigned int bit, volatile void *bits ) {
|
||||
|
||||
test_and_set_bit ( bit, bits );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
clear_bit ( unsigned int bit, volatile void *bits ) {
|
||||
|
||||
test_and_clear_bit ( bit, bits );
|
||||
}
|
||||
|
||||
#endif /* _BITS_BITOPS_H */
|
||||
@ -1,47 +0,0 @@
|
||||
#ifndef _BITS_BYTESWAP_H
|
||||
#define _BITS_BYTESWAP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Byte-order swapping functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
static inline __attribute__ (( always_inline, const )) uint16_t
|
||||
__bswap_variable_16 ( uint16_t x ) {
|
||||
__asm__ ( "revb.2h %0, %1" : "=r" ( x ) : "r" ( x ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
__bswap_16s ( uint16_t *x ) {
|
||||
*x = __bswap_variable_16 ( *x );
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline, const )) uint32_t
|
||||
__bswap_variable_32 ( uint32_t x ) {
|
||||
__asm__ ( "revb.2w %0, %1" : "=r" ( x ) : "r" ( x ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
__bswap_32s ( uint32_t *x ) {
|
||||
*x = __bswap_variable_32 ( *x );
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline, const )) uint64_t
|
||||
__bswap_variable_64 ( uint64_t x ) {
|
||||
__asm__ ( "revb.d %0, %1" : "=r" ( x ) : "r" ( x ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
__bswap_64s ( uint64_t *x ) {
|
||||
*x = __bswap_variable_64 ( *x );
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,19 +0,0 @@
|
||||
#ifndef _BITS_COMPILER_H
|
||||
#define _BITS_COMPILER_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Dummy relocation type */
|
||||
#define RELOC_TYPE_NONE R_LARCH_NONE
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "a"
|
||||
|
||||
#define __asmcall
|
||||
#define __libgcc
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
|
||||
#endif /*_BITS_COMPILER_H */
|
||||
@ -1,8 +0,0 @@
|
||||
#ifndef _BITS_ENDIAN_H
|
||||
#define _BITS_ENDIAN_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
|
||||
#endif /* _BITS_ENDIAN_H */
|
||||
@ -1,19 +0,0 @@
|
||||
#ifndef _BITS_ERRFILE_H
|
||||
#define _BITS_ERRFILE_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific error file identifiers
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/**
|
||||
* @addtogroup errfile Error file identifiers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _BITS_ERRFILE_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_HYPERV_H
|
||||
#define _BITS_HYPERV_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Hyper-V interface
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_HYPERV_H */
|
||||
@ -1,17 +0,0 @@
|
||||
#ifndef _BITS_IO_H
|
||||
#define _BITS_IO_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific I/O API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
#include <ipxe/loong64_io.h>
|
||||
|
||||
#endif /* _BITS_IO_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_IOMAP_H
|
||||
#define _BITS_IOMAP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific I/O mapping API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_IOMAP_H */
|
||||
@ -1,14 +0,0 @@
|
||||
#ifndef _BITS_NAP_H
|
||||
#define _BITS_NAP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific CPU sleeping API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/efi/efiloong64_nap.h>
|
||||
|
||||
#endif /* _BITS_NAP_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_PCI_IO_H
|
||||
#define _BITS_PCI_IO_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific PCI I/O API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_PCI_IO_H */
|
||||
@ -1,28 +0,0 @@
|
||||
#ifndef _BITS_PROFILE_H
|
||||
#define _BITS_PROFILE_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Profiling
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Get profiling timestamp
|
||||
*
|
||||
* @ret timestamp Timestamp
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) uint64_t
|
||||
profile_timestamp ( void ) {
|
||||
uint64_t cycles;
|
||||
|
||||
/* Read cycle counter */
|
||||
__asm__ __volatile__ ( "rdtime.d %0, $zero\n\t" : "=r" ( cycles ) );
|
||||
return cycles;
|
||||
}
|
||||
|
||||
#endif /* _BITS_PROFILE_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_REBOOT_H
|
||||
#define _BITS_REBOOT_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific reboot API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_REBOOT_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_SANBOOT_H
|
||||
#define _BITS_SANBOOT_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific sanboot API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_SANBOOT_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_SMBIOS_H
|
||||
#define _BITS_SMBIOS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific SMBIOS API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_SMBIOS_H */
|
||||
@ -1,23 +0,0 @@
|
||||
#ifndef _BITS_STDINT_H
|
||||
#define _BITS_STDINT_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef signed long ssize_t;
|
||||
typedef signed long off_t;
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef signed long long int64_t;
|
||||
|
||||
typedef unsigned long physaddr_t;
|
||||
typedef unsigned long intptr_t;
|
||||
|
||||
#endif /* _BITS_STDINT_H */
|
||||
@ -1,61 +0,0 @@
|
||||
#ifndef _BITS_STRING_H
|
||||
#define _BITS_STRING_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* String functions
|
||||
*
|
||||
*/
|
||||
|
||||
extern void loong64_bzero ( void *dest, size_t len );
|
||||
extern void loong64_memset ( void *dest, size_t len, int character );
|
||||
extern void loong64_memcpy ( void *dest, const void *src, size_t len );
|
||||
extern void loong64_memmove_forwards ( void *dest, const void *src, size_t len );
|
||||
extern void loong64_memmove_backwards ( void *dest, const void *src, size_t len );
|
||||
extern void loong64_memmove ( void *dest, const void *src, size_t len );
|
||||
|
||||
/**
|
||||
* Fill memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v character Fill character
|
||||
* @v len Length
|
||||
* @ret dest Destination region
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void *
|
||||
memset ( void *dest, int character, size_t len ) {
|
||||
loong64_memset ( dest, len, character );
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
* @ret dest Destination region
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void *
|
||||
memcpy ( void *dest, const void *src, size_t len ) {
|
||||
loong64_memcpy ( dest, src, len );
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
* @ret dest Destination region
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void *
|
||||
memmove ( void *dest, const void *src, size_t len ) {
|
||||
loong64_memmove ( dest, src, len );
|
||||
return dest;
|
||||
}
|
||||
|
||||
#endif /* _BITS_STRING_H */
|
||||
@ -1,69 +0,0 @@
|
||||
#ifndef _BITS_STRINGS_H
|
||||
#define _BITS_STRINGS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* String functions
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/**
|
||||
* Find first (i.e. least significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret lsb Least significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
|
||||
unsigned long long bits = value;
|
||||
unsigned long long lsb;
|
||||
unsigned int lz;
|
||||
|
||||
/* Extract least significant set bit */
|
||||
lsb = ( bits & -bits );
|
||||
|
||||
/* Count number of leading zeroes before LSB */
|
||||
__asm__ ( "clz.d %0, %1" : "=r" ( lz ) : "r" ( lsb ) );
|
||||
|
||||
return ( 64 - lz );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first (i.e. least significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret lsb Least significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
|
||||
|
||||
return __ffsll ( value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
|
||||
unsigned int lz;
|
||||
|
||||
/* Count number of leading zeroes */
|
||||
__asm__ ( "clz.d %0, %1" : "=r" ( lz ) : "r" ( value ) );
|
||||
|
||||
return ( 64 - lz );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
||||
|
||||
return __flsll ( value );
|
||||
}
|
||||
|
||||
#endif /* _BITS_STRINGS_H */
|
||||
@ -1,19 +0,0 @@
|
||||
#ifndef _BITS_TCPIP_H
|
||||
#define _BITS_TCPIP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Transport-network layer interface
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
static inline __attribute__ (( always_inline )) uint16_t
|
||||
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
|
||||
|
||||
/* Not yet optimised */
|
||||
return generic_tcpip_continue_chksum ( partial, data, len );
|
||||
}
|
||||
|
||||
#endif /* _BITS_TCPIP_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_TIME_H
|
||||
#define _BITS_TIME_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific time API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_TIME_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_UACCESS_H
|
||||
#define _BITS_UACCESS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific user access API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_UACCESS_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_UART_H
|
||||
#define _BITS_UART_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* 16550-compatible UART
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_UART_H */
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_UMALLOC_H
|
||||
#define _BITS_UMALLOC_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific user memory allocation API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_UMALLOC_H */
|
||||
@ -1,13 +0,0 @@
|
||||
#ifndef _BITS_XEN_H
|
||||
#define _BITS_XEN_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Xen interface
|
||||
*
|
||||
*/
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/nonxen.h>
|
||||
|
||||
#endif /* _BITS_XEN_H */
|
||||
@ -1,45 +0,0 @@
|
||||
#ifndef GDBMACH_H
|
||||
#define GDBMACH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* GDB architecture specifics
|
||||
*
|
||||
* This file declares functions for manipulating the machine state and
|
||||
* debugging context.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned long gdbreg_t;
|
||||
|
||||
/* Register snapshot */
|
||||
enum {
|
||||
/* Not yet implemented */
|
||||
GDBMACH_NREGS,
|
||||
};
|
||||
|
||||
#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
|
||||
|
||||
static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
|
||||
/* Not yet implemented */
|
||||
( void ) regs;
|
||||
( void ) pc;
|
||||
}
|
||||
|
||||
static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
|
||||
/* Not yet implemented */
|
||||
( void ) regs;
|
||||
( void ) step;
|
||||
}
|
||||
|
||||
static inline void gdbmach_breakpoint ( void ) {
|
||||
/* Not yet implemented */
|
||||
}
|
||||
|
||||
extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
|
||||
int enable );
|
||||
extern void gdbmach_init ( void );
|
||||
|
||||
#endif /* GDBMACH_H */
|
||||
@ -1,20 +0,0 @@
|
||||
#ifndef _IPXE_EFI_DHCPARCH_H
|
||||
#define _IPXE_EFI_DHCPARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DHCP client architecture definitions
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
/** DHCP client architecture */
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_LOONG64
|
||||
|
||||
/** DHCP client network device interface */
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
#endif /* _IPXE_EFI_DHCPARCH_H */
|
||||
@ -1,18 +0,0 @@
|
||||
#ifndef _IPXE_EFILOONG64_NAP_H
|
||||
#define _IPXE_EFILOONG64_NAP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI CPU sleeping
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifdef NAP_EFILOONG64
|
||||
#define NAP_PREFIX_efiloong64
|
||||
#else
|
||||
#define NAP_PREFIX_efiloong64 __efiloong64_
|
||||
#endif
|
||||
|
||||
#endif /* _IPXE_EFILOONG64_NAP_H */
|
||||
@ -1,82 +0,0 @@
|
||||
#ifndef _IPXE_LOONG64_IO_H
|
||||
#define _IPXE_LOONG64_IO_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* iPXE I/O API for LoongArch64
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifdef IOAPI_LOONG64
|
||||
#define IOAPI_PREFIX_loong64
|
||||
#else
|
||||
#define IOAPI_PREFIX_loong64 __loong64_
|
||||
#endif
|
||||
|
||||
#include <ipxe/dummy_pio.h>
|
||||
|
||||
/*
|
||||
* Memory space mappings
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Physical<->Bus address mappings
|
||||
*
|
||||
*/
|
||||
|
||||
static inline __always_inline unsigned long
|
||||
IOAPI_INLINE ( loong64, phys_to_bus ) ( unsigned long phys_addr ) {
|
||||
return phys_addr;
|
||||
}
|
||||
|
||||
static inline __always_inline unsigned long
|
||||
IOAPI_INLINE ( loong64, bus_to_phys ) ( unsigned long bus_addr ) {
|
||||
return bus_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* MMIO reads and writes up to native word size
|
||||
*
|
||||
*/
|
||||
|
||||
#define LOONG64_READX( _suffix, _type, _insn_suffix ) \
|
||||
static inline __always_inline _type \
|
||||
IOAPI_INLINE ( loong64, read ## _suffix ) ( volatile _type *io_addr ) { \
|
||||
_type data; \
|
||||
__asm__ __volatile__ ( "ld." _insn_suffix " %0, %1" \
|
||||
: "=r" ( data ) : "m" ( *io_addr ) ); \
|
||||
return data; \
|
||||
}
|
||||
LOONG64_READX ( b, uint8_t, "bu");
|
||||
LOONG64_READX ( w, uint16_t, "hu");
|
||||
LOONG64_READX ( l, uint32_t, "wu");
|
||||
LOONG64_READX ( q, uint64_t, "d");
|
||||
|
||||
#define LOONG64_WRITEX( _suffix, _type, _insn_suffix ) \
|
||||
static inline __always_inline void \
|
||||
IOAPI_INLINE ( loong64, write ## _suffix ) ( _type data, \
|
||||
volatile _type *io_addr ) { \
|
||||
__asm__ __volatile__ ( "st." _insn_suffix " %0, %1" \
|
||||
: : "r" ( data ), "m" ( *io_addr ) ); \
|
||||
}
|
||||
LOONG64_WRITEX ( b, uint8_t, "b");
|
||||
LOONG64_WRITEX ( w, uint16_t, "h");
|
||||
LOONG64_WRITEX ( l, uint32_t, "w" );
|
||||
LOONG64_WRITEX ( q, uint64_t, "d");
|
||||
|
||||
/*
|
||||
* Memory barrier
|
||||
*
|
||||
*/
|
||||
static inline __always_inline void
|
||||
IOAPI_INLINE ( loong64, mb ) ( void ) {
|
||||
__asm__ __volatile__ ( "dbar 0" );
|
||||
}
|
||||
|
||||
/* Dummy PIO */
|
||||
DUMMY_PIO ( loong64 );
|
||||
|
||||
#endif /* _IPXE_LOONG64_IO_H */
|
||||
@ -1,53 +0,0 @@
|
||||
#ifndef LIMITS_H
|
||||
#define LIMITS_H 1
|
||||
|
||||
/* Number of bits in a `char' */
|
||||
#define CHAR_BIT 8
|
||||
|
||||
/* Minimum and maximum values a `signed char' can hold */
|
||||
#define SCHAR_MIN (-128)
|
||||
#define SCHAR_MAX 127
|
||||
|
||||
/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
|
||||
#define UCHAR_MAX 255
|
||||
|
||||
/* Minimum and maximum values a `char' can hold */
|
||||
#define CHAR_MIN SCHAR_MIN
|
||||
#define CHAR_MAX SCHAR_MAX
|
||||
|
||||
/* Minimum and maximum values a `signed short int' can hold */
|
||||
#define SHRT_MIN (-32768)
|
||||
#define SHRT_MAX 32767
|
||||
|
||||
/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
|
||||
#define USHRT_MAX 65535
|
||||
|
||||
/* Minimum and maximum values a `signed int' can hold */
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
#define INT_MAX 2147483647
|
||||
|
||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
||||
#define UINT_MAX 4294967295U
|
||||
|
||||
/* Minimum and maximum values a `signed int' can hold */
|
||||
#define INT_MAX 2147483647
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
|
||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
||||
#define UINT_MAX 4294967295U
|
||||
|
||||
/* Minimum and maximum values a `signed long' can hold */
|
||||
#define LONG_MAX 9223372036854775807L
|
||||
#define LONG_MIN (-LONG_MAX - 1L)
|
||||
|
||||
/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
|
||||
#define ULONG_MAX 18446744073709551615UL
|
||||
|
||||
/* Minimum and maximum values a `signed long long' can hold */
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#define LLONG_MIN (-LONG_MAX - 1LL)
|
||||
|
||||
/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
|
||||
#define ULLONG_MAX 18446744073709551615ULL
|
||||
|
||||
#endif /* LIMITS_H */
|
||||
@ -1,31 +0,0 @@
|
||||
#ifndef _SETJMP_H
|
||||
#define _SETJMP_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** jump buffer env*/
|
||||
typedef struct {
|
||||
uint64_t s0;
|
||||
uint64_t s1;
|
||||
uint64_t s2;
|
||||
uint64_t s3;
|
||||
uint64_t s4;
|
||||
uint64_t s5;
|
||||
uint64_t s6;
|
||||
uint64_t s7;
|
||||
uint64_t s8;
|
||||
|
||||
uint64_t fp;
|
||||
uint64_t sp;
|
||||
uint64_t ra;
|
||||
} jmp_buf[1];
|
||||
|
||||
extern int __asmcall __attribute__ (( returns_twice ))
|
||||
setjmp ( jmp_buf env );
|
||||
|
||||
extern void __asmcall __attribute__ (( noreturn ))
|
||||
longjmp ( jmp_buf env, int val );
|
||||
|
||||
#endif /* _SETJMP_H */
|
||||
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Xiaotian Wu <wuxiaotian@loongson.cn>
|
||||
*
|
||||
* 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 <ipxe/nap.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* iPXE CPU sleeping API for EFI
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sleep until next interrupt
|
||||
*
|
||||
*/
|
||||
static void efiloong64_cpu_nap ( void ) {
|
||||
/*
|
||||
* I can't find any EFI API that allows us to put the CPU to
|
||||
* sleep. The CpuSleep() function is defined in CpuLib.h, but
|
||||
* isn't part of any exposed protocol so we have no way to
|
||||
* call it.
|
||||
*
|
||||
* The EFI shell doesn't seem to bother sleeping the CPU; it
|
||||
* just sits there idly burning power.
|
||||
*
|
||||
* If a shutdown is in progess, there may be nothing to
|
||||
* generate an interrupt since the timer is disabled in the
|
||||
* first step of ExitBootServices().
|
||||
*/
|
||||
if ( ! efi_shutdown_in_progress )
|
||||
__asm__ __volatile__ ( "idle 0" );
|
||||
}
|
||||
|
||||
PROVIDE_NAP ( efiloong64, cpu_nap, efiloong64_cpu_nap );
|
||||
@ -22,6 +22,9 @@ SRCDIRS += arch/x86/drivers/xen
|
||||
SRCDIRS += arch/x86/drivers/hyperv
|
||||
SRCDIRS += arch/x86/transitions
|
||||
|
||||
# breaks building some of the linux-related objects
|
||||
CFLAGS += -Ulinux
|
||||
|
||||
# disable valgrind
|
||||
CFLAGS += -DNVALGRIND
|
||||
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
MEDIA = linux
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += Makefile.linux
|
||||
include Makefile.linux
|
||||
# enable valgrind
|
||||
CFLAGS += -UNVALGRIND
|
||||
|
||||
INCDIRS += arch/x86/include/linux
|
||||
SRCDIRS += interface/linux
|
||||
SRCDIRS += drivers/linux
|
||||
SRCDIRS += arch/x86/core/linux
|
||||
|
||||
$(BIN)/%.linux : $(BIN)/%.linux.tmp
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)$(CP) $< $@
|
||||
|
||||
@ -4,21 +4,17 @@
|
||||
#
|
||||
SRCDIRS += arch/x86/drivers/net
|
||||
|
||||
# The linker scripts
|
||||
# The i386 linker script
|
||||
#
|
||||
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
|
||||
|
||||
# Do not warn about RWX segments (required by most prefixes)
|
||||
# Prefix always starts at address zero
|
||||
#
|
||||
WRWX_TEST = $(LD) --warn-rwx-segments --version 2>&1 > /dev/null
|
||||
WRWX_FLAGS := $(shell [ -z "`$(WRWX_TEST)`" ] && \
|
||||
$(ECHO) '--no-warn-rwx-segments')
|
||||
LDFLAGS += $(WRWX_FLAGS)
|
||||
LDFLAGS += --section-start=.prefix=0
|
||||
|
||||
# Media types.
|
||||
#
|
||||
@ -61,15 +57,9 @@ LIST_NAME_mrom := ROMS
|
||||
LIST_NAME_pcirom := ROMS
|
||||
LIST_NAME_isarom := ROMS
|
||||
|
||||
# ISO images
|
||||
# ISO or FAT filesystem images
|
||||
NON_AUTO_MEDIA += iso
|
||||
$(BIN)/%.iso : $(BIN)/%.lkrn util/genfsimg
|
||||
$(QM)$(ECHO) " [GENFSIMG] $@"
|
||||
$(Q)util/genfsimg -o $@ $<
|
||||
|
||||
# FAT filesystem images (via syslinux)
|
||||
NON_AUTO_MEDIA += sdsk
|
||||
$(BIN)/%.sdsk : $(BIN)/%.lkrn util/genfsimg
|
||||
$(BIN)/%.iso $(BIN)/%.sdsk: $(BIN)/%.lkrn util/genfsimg
|
||||
$(QM)$(ECHO) " [GENFSIMG] $@"
|
||||
$(Q)util/genfsimg -o $@ $<
|
||||
|
||||
@ -83,12 +73,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) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
|
||||
|
||||
# rule to make a USB disk image
|
||||
$(BIN)/usbdisk.tmp : $(BIN)/usbdisk.o
|
||||
$(QM)$(ECHO) " [LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
|
||||
|
||||
NON_AUTO_MEDIA += usb
|
||||
%usb: $(BIN)/usbdisk.bin %hd
|
||||
|
||||
179
src/arch/x86/core/cachedhcp.c
Normal file
179
src/arch/x86/core/cachedhcp.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <ipxe/dhcppkt.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/netdevice.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 */
|
||||
static struct dhcp_packet *cached_dhcpack;
|
||||
|
||||
/**
|
||||
* Cached DHCPACK startup function
|
||||
*
|
||||
*/
|
||||
static void cachedhcp_init ( void ) {
|
||||
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;
|
||||
}
|
||||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
|
||||
copy_from_user ( dhcphdr, phys_to_user ( cached_dhcpack_phys ), 0,
|
||||
max_len );
|
||||
dhcppkt_init ( dhcppkt, dhcphdr, max_len );
|
||||
|
||||
/* Shrink packet to required length. If reallocation fails,
|
||||
* just continue to use the original packet and waste the
|
||||
* unused space.
|
||||
*/
|
||||
len = dhcppkt_len ( dhcppkt );
|
||||
assert ( len <= max_len );
|
||||
tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) );
|
||||
if ( tmp )
|
||||
dhcppkt = tmp;
|
||||
|
||||
/* Reinitialise packet at new address */
|
||||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
|
||||
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 );
|
||||
cached_dhcpack = dhcppkt;
|
||||
cached_dhcpack_phys = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached DHCPACK startup function
|
||||
*
|
||||
*/
|
||||
static void cachedhcp_startup ( void ) {
|
||||
|
||||
/* If cached DHCP packet was not claimed by any network device
|
||||
* during startup, then free it.
|
||||
*/
|
||||
if ( cached_dhcpack ) {
|
||||
DBGC ( colour, "CACHEDHCP freeing unclaimed cached DHCPACK\n" );
|
||||
dhcppkt_put ( cached_dhcpack );
|
||||
cached_dhcpack = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** 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",
|
||||
.startup = cachedhcp_startup,
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply cached DHCPACK to network device, if applicable
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int cachedhcp_probe ( struct net_device *netdev ) {
|
||||
struct ll_protocol *ll_protocol = netdev->ll_protocol;
|
||||
int rc;
|
||||
|
||||
/* Do nothing unless we have a cached DHCPACK */
|
||||
if ( ! cached_dhcpack )
|
||||
return 0;
|
||||
|
||||
/* Do nothing unless cached DHCPACK's MAC address matches this
|
||||
* network device.
|
||||
*/
|
||||
if ( memcmp ( netdev->ll_addr, cached_dhcpack->dhcphdr->chaddr,
|
||||
ll_protocol->ll_addr_len ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP cached DHCPACK does not match %s\n",
|
||||
netdev->name );
|
||||
return 0;
|
||||
}
|
||||
DBGC ( colour, "CACHEDHCP cached DHCPACK is for %s\n", netdev->name );
|
||||
|
||||
/* Register as DHCP settings for this network device */
|
||||
if ( ( rc = register_settings ( &cached_dhcpack->settings,
|
||||
netdev_settings ( netdev ),
|
||||
DHCP_SETTINGS_NAME ) ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP could not register settings: %s\n",
|
||||
strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Claim cached DHCPACK */
|
||||
dhcppkt_put ( cached_dhcpack );
|
||||
cached_dhcpack = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Cached DHCP packet network device driver */
|
||||
struct net_driver cachedhcp_driver __net_driver = {
|
||||
.name = "cachedhcp",
|
||||
.probe = cachedhcp_probe,
|
||||
};
|
||||
149
src/arch/x86/core/linux/linux_api.c
Normal file
149
src/arch/x86/core/linux/linux_api.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Implementation of most of the linux API.
|
||||
*/
|
||||
|
||||
#include <linux_api.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
int linux_open ( const char *pathname, int flags ) {
|
||||
return linux_syscall ( __NR_open, pathname, flags );
|
||||
}
|
||||
|
||||
int linux_close ( int fd ) {
|
||||
return linux_syscall ( __NR_close, fd );
|
||||
}
|
||||
|
||||
off_t linux_lseek ( int fd, off_t offset, int whence ) {
|
||||
return linux_syscall ( __NR_lseek, fd, offset, whence );
|
||||
}
|
||||
|
||||
__kernel_ssize_t linux_read ( int fd, void *buf, __kernel_size_t count ) {
|
||||
return linux_syscall ( __NR_read, fd, buf, count );
|
||||
}
|
||||
|
||||
__kernel_ssize_t linux_write ( int fd, const void *buf,
|
||||
__kernel_size_t count ) {
|
||||
return linux_syscall ( __NR_write, fd, buf, count );
|
||||
}
|
||||
|
||||
int linux_fcntl ( int fd, int cmd, ... ) {
|
||||
long arg;
|
||||
va_list list;
|
||||
|
||||
va_start ( list, cmd );
|
||||
arg = va_arg ( list, long );
|
||||
va_end ( list );
|
||||
|
||||
return linux_syscall ( __NR_fcntl, fd, cmd, arg );
|
||||
}
|
||||
|
||||
int linux_ioctl ( int fd, int request, ... ) {
|
||||
void *arg;
|
||||
va_list list;
|
||||
|
||||
va_start ( list, request );
|
||||
arg = va_arg ( list, void * );
|
||||
va_end ( list );
|
||||
|
||||
return linux_syscall ( __NR_ioctl, fd, request, arg );
|
||||
}
|
||||
|
||||
int linux_poll ( struct pollfd *fds, nfds_t nfds, int timeout ) {
|
||||
return linux_syscall ( __NR_poll, fds, nfds, timeout );
|
||||
}
|
||||
|
||||
int linux_nanosleep ( const struct timespec *req, struct timespec *rem ) {
|
||||
return linux_syscall ( __NR_nanosleep, req, rem );
|
||||
}
|
||||
|
||||
int linux_usleep ( useconds_t usec ) {
|
||||
struct timespec ts = {
|
||||
.tv_sec = ( ( long ) ( usec / 1000000 ) ),
|
||||
.tv_nsec = ( ( long ) ( usec % 1000000 ) * 1000UL ),
|
||||
};
|
||||
|
||||
return linux_nanosleep ( &ts, NULL );
|
||||
}
|
||||
|
||||
int linux_gettimeofday ( struct timeval *tv, struct timezone *tz ) {
|
||||
return linux_syscall ( __NR_gettimeofday, tv, tz );
|
||||
}
|
||||
|
||||
void * linux_mmap ( void *addr, __kernel_size_t length, int prot, int flags,
|
||||
int fd, __kernel_off_t offset ) {
|
||||
return ( void * ) linux_syscall ( __SYSCALL_mmap, addr, length, prot,
|
||||
flags, fd, offset );
|
||||
}
|
||||
|
||||
void * linux_mremap ( void *old_address, __kernel_size_t old_size,
|
||||
__kernel_size_t new_size, int flags ) {
|
||||
return ( void * ) linux_syscall ( __NR_mremap, old_address, old_size,
|
||||
new_size, flags );
|
||||
}
|
||||
|
||||
int linux_munmap ( void *addr, __kernel_size_t length ) {
|
||||
return linux_syscall ( __NR_munmap, addr, length );
|
||||
}
|
||||
|
||||
int linux_socket ( int domain, int type_, int protocol ) {
|
||||
#ifdef __NR_socket
|
||||
return linux_syscall ( __NR_socket, domain, type_, protocol );
|
||||
#else
|
||||
#ifndef SOCKOP_socket
|
||||
# define SOCKOP_socket 1
|
||||
#endif
|
||||
unsigned long sc_args[] = { domain, type_, protocol };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_socket, sc_args );
|
||||
#endif
|
||||
}
|
||||
|
||||
int linux_bind ( int fd, const struct sockaddr *addr, socklen_t addrlen ) {
|
||||
#ifdef __NR_bind
|
||||
return linux_syscall ( __NR_bind, fd, addr, addrlen );
|
||||
#else
|
||||
#ifndef SOCKOP_bind
|
||||
# define SOCKOP_bind 2
|
||||
#endif
|
||||
unsigned long sc_args[] = { fd, (unsigned long)addr, addrlen };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_bind, sc_args );
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t linux_sendto ( int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *daddr, socklen_t addrlen ) {
|
||||
#ifdef __NR_sendto
|
||||
return linux_syscall ( __NR_sendto, fd, buf, len, flags,
|
||||
daddr, addrlen );
|
||||
#else
|
||||
#ifndef SOCKOP_sendto
|
||||
# define SOCKOP_sendto 11
|
||||
#endif
|
||||
unsigned long sc_args[] = { fd, (unsigned long)buf, len,
|
||||
flags, (unsigned long)daddr, addrlen };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_sendto, sc_args );
|
||||
#endif
|
||||
}
|
||||
169
src/arch/x86/core/linux/linux_strerror.c
Normal file
169
src/arch/x86/core/linux/linux_strerror.c
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
FILE_LICENCE(GPL2_OR_LATER);
|
||||
|
||||
/** @file
|
||||
*
|
||||
* linux_strerror implementation
|
||||
*/
|
||||
|
||||
#include <linux_api.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/** Error names from glibc */
|
||||
static const char *errors[] = {
|
||||
"Success",
|
||||
"Operation not permitted",
|
||||
"No such file or directory",
|
||||
"No such process",
|
||||
"Interrupted system call",
|
||||
"Input/output error",
|
||||
"No such device or address",
|
||||
"Argument list too long",
|
||||
"Exec format error",
|
||||
"Bad file descriptor",
|
||||
"No child processes",
|
||||
"Resource temporarily unavailable",
|
||||
"Cannot allocate memory",
|
||||
"Permission denied",
|
||||
"Bad address",
|
||||
"Block device required",
|
||||
"Device or resource busy",
|
||||
"File exists",
|
||||
"Invalid cross-device link",
|
||||
"No such device",
|
||||
"Not a directory",
|
||||
"Is a directory",
|
||||
"Invalid argument",
|
||||
"Too many open files in system",
|
||||
"Too many open files",
|
||||
"Inappropriate ioctl for device",
|
||||
"Text file busy",
|
||||
"File too large",
|
||||
"No space left on device",
|
||||
"Illegal seek",
|
||||
"Read-only file system",
|
||||
"Too many links",
|
||||
"Broken pipe",
|
||||
"Numerical argument out of domain",
|
||||
"Numerical result out of range",
|
||||
"Resource deadlock avoided",
|
||||
"File name too long",
|
||||
"No locks available",
|
||||
"Function not implemented",
|
||||
"Directory not empty",
|
||||
"Too many levels of symbolic links",
|
||||
"",
|
||||
"No message of desired type",
|
||||
"Identifier removed",
|
||||
"Channel number out of range",
|
||||
"Level 2 not synchronized",
|
||||
"Level 3 halted",
|
||||
"Level 3 reset",
|
||||
"Link number out of range",
|
||||
"Protocol driver not attached",
|
||||
"No CSI structure available",
|
||||
"Level 2 halted",
|
||||
"Invalid exchange",
|
||||
"Invalid request descriptor",
|
||||
"Exchange full",
|
||||
"No anode",
|
||||
"Invalid request code",
|
||||
"Invalid slot",
|
||||
"",
|
||||
"Bad font file format",
|
||||
"Device not a stream",
|
||||
"No data available",
|
||||
"Timer expired",
|
||||
"Out of streams resources",
|
||||
"Machine is not on the network",
|
||||
"Package not installed",
|
||||
"Object is remote",
|
||||
"Link has been severed",
|
||||
"Advertise error",
|
||||
"Srmount error",
|
||||
"Communication error on send",
|
||||
"Protocol error",
|
||||
"Multihop attempted",
|
||||
"RFS specific error",
|
||||
"Bad message",
|
||||
"Value too large for defined data type",
|
||||
"Name not unique on network",
|
||||
"File descriptor in bad state",
|
||||
"Remote address changed",
|
||||
"Can not access a needed shared library",
|
||||
"Accessing a corrupted shared library",
|
||||
".lib section in a.out corrupted",
|
||||
"Attempting to link in too many shared libraries",
|
||||
"Cannot exec a shared library directly",
|
||||
"Invalid or incomplete multibyte or wide character",
|
||||
"Interrupted system call should be restarted",
|
||||
"Streams pipe error",
|
||||
"Too many users",
|
||||
"Socket operation on non-socket",
|
||||
"Destination address required",
|
||||
"Message too long",
|
||||
"Protocol wrong type for socket",
|
||||
"Protocol not available",
|
||||
"Protocol not supported",
|
||||
"Socket type not supported",
|
||||
"Operation not supported",
|
||||
"Protocol family not supported",
|
||||
"Address family not supported by protocol",
|
||||
"Address already in use",
|
||||
"Cannot assign requested address",
|
||||
"Network is down",
|
||||
"Network is unreachable",
|
||||
"Network dropped connection on reset",
|
||||
"Software caused connection abort",
|
||||
"Connection reset by peer",
|
||||
"No buffer space available",
|
||||
"Transport endpoint is already connected",
|
||||
"Transport endpoint is not connected",
|
||||
"Cannot send after transport endpoint shutdown",
|
||||
"Too many references: cannot splice",
|
||||
"Connection timed out",
|
||||
"Connection refused",
|
||||
"Host is down",
|
||||
"No route to host",
|
||||
"Operation already in progress",
|
||||
"Operation now in progress",
|
||||
"Stale NFS file handle",
|
||||
"Structure needs cleaning",
|
||||
"Not a XENIX named type file",
|
||||
"No XENIX semaphores available",
|
||||
"Is a named type file",
|
||||
"Remote I/O error",
|
||||
"Disk quota exceeded",
|
||||
"No medium found",
|
||||
"Wrong medium type",
|
||||
};
|
||||
|
||||
const char *linux_strerror(int errnum)
|
||||
{
|
||||
static char errbuf[64];
|
||||
static int errors_size = sizeof(errors) / sizeof(*errors);
|
||||
|
||||
if (errnum >= errors_size || errnum < 0) {
|
||||
snprintf(errbuf, sizeof(errbuf), "Error %#08x", errnum);
|
||||
return errbuf;
|
||||
} else {
|
||||
return errors[errnum];
|
||||
}
|
||||
}
|
||||
@ -22,9 +22,9 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", @progbits
|
||||
.code16
|
||||
.text
|
||||
.arch i386
|
||||
.code16
|
||||
|
||||
/****************************************************************************
|
||||
* Set/clear CF on the stack as appropriate, assumes stack is as it should
|
||||
|
||||
@ -45,7 +45,7 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) {
|
||||
PCIDIRECT_CONFIG_ADDRESS );
|
||||
}
|
||||
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_discover );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_num_bus );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
|
||||
@ -53,5 +53,3 @@ PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
|
||||
|
||||
struct pci_api pcidirect_api = PCIAPI_RUNTIME ( direct );
|
||||
|
||||
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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 );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Hardware random number generator
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
#include <ipxe/entropy.h>
|
||||
#include <ipxe/drbg.h>
|
||||
|
||||
struct entropy_source rdrand_entropy __entropy_source ( ENTROPY_PREFERRED );
|
||||
|
||||
/** Number of times to retry RDRAND instruction */
|
||||
#define RDRAND_RETRY_COUNT 16
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &rdrand_entropy
|
||||
|
||||
/**
|
||||
* Enable entropy gathering
|
||||
*
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rdrand_entropy_enable ( void ) {
|
||||
struct x86_features features;
|
||||
|
||||
/* Check that RDRAND is supported */
|
||||
x86_features ( &features );
|
||||
if ( ! ( features.intel.ecx & CPUID_FEATURES_INTEL_ECX_RDRAND ) ) {
|
||||
DBGC ( colour, "RDRAND not supported\n" );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Data returned by RDRAND is theoretically full entropy, up
|
||||
* to a security strength of 128 bits, so assume that each
|
||||
* sample contains exactly 8 bits of entropy.
|
||||
*/
|
||||
if ( DRBG_SECURITY_STRENGTH > 128 )
|
||||
return -ENOTSUP;
|
||||
entropy_init ( &rdrand_entropy, MIN_ENTROPY ( 8.0 ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get noise sample
|
||||
*
|
||||
* @ret noise Noise sample
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rdrand_get_noise ( noise_sample_t *noise ) {
|
||||
unsigned int result;
|
||||
unsigned int discard_c;
|
||||
unsigned int ok;
|
||||
|
||||
/* Issue RDRAND, retrying until CF is set */
|
||||
__asm__ ( "\n1:\n\t"
|
||||
"rdrand %0\n\t"
|
||||
"sbb %1, %1\n\t"
|
||||
"loopz 1b\n\t"
|
||||
: "=r" ( result ), "=r" ( ok ), "=c" ( discard_c )
|
||||
: "2" ( RDRAND_RETRY_COUNT ) );
|
||||
if ( ! ok ) {
|
||||
DBGC ( colour, "RDRAND failed to become ready\n" );
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
*noise = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Hardware random number generator entropy source */
|
||||
struct entropy_source rdrand_entropy __entropy_source ( ENTROPY_PREFERRED ) = {
|
||||
.name = "rdrand",
|
||||
.enable = rdrand_entropy_enable,
|
||||
.get_noise = rdrand_get_noise,
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", @progbits
|
||||
.arch i386
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define STACK_SIZE 8192
|
||||
@ -13,7 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".stack", "aw", @nobits
|
||||
.balign 8
|
||||
.align 8
|
||||
.globl _stack
|
||||
_stack:
|
||||
.space STACK_SIZE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user