Compare commits

..

1 Commits
shim4 ... cc

Author SHA1 Message Date
ddc1923ab8 [build] Respect value of $(CC) variable
On FreeBSD the gcc package installs a versioned binary such as
"gcc12".  There is no plain "gcc" binary.

Simplify building on such systems by respecting the $(CC) variable.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-01 21:43:33 +00:00
145 changed files with 1959 additions and 7960 deletions

View File

@ -4,53 +4,21 @@ 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
runs-on: ubuntu-20.04
steps:
- name: Check out code
uses: actions/checkout@v3
uses: actions/checkout@v2
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
libc6-dev-i386 libc6-dbg:i386 valgrind
- name: Build (BIOS)
run: |
make -j 4 -C src
@ -64,21 +32,12 @@ jobs:
arm32:
name: ARM32
runs-on: ubuntu-22.04
needs: cache
runs-on: ubuntu-20.04
steps:
- name: Check out code
uses: actions/checkout@v3
uses: actions/checkout@v2
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
@ -93,21 +52,12 @@ jobs:
arm64:
name: ARM64
runs-on: ubuntu-22.04
needs: cache
runs-on: ubuntu-20.04
steps:
- name: Check out code
uses: actions/checkout@v3
uses: actions/checkout@v2
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

View File

@ -8,10 +8,10 @@ on:
jobs:
submit:
name: Submit
runs-on: ubuntu-22.04
runs-on: ubuntu-20.04
steps:
- name: Check out code
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Download Coverity Scan
run: |
curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \

View File

@ -16,7 +16,7 @@ SYMBOL_PREFIX :=
#
# Locations of tools
#
HOST_CC := gcc
HOST_CC := $(CC)
RM := rm -f
TOUCH := touch
MKDIR := mkdir
@ -26,7 +26,7 @@ PRINTF := printf
PERL := perl
PYTHON := python
TRUE := true
CC := $(CROSS_COMPILE)gcc
CC := $(CROSS_COMPILE)$(CC)
CPP := $(CC) -E
AS := $(CROSS_COMPILE)as
LD := $(CROSS_COMPILE)ld

View 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 */

View File

@ -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 */

View File

@ -20,6 +20,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
/** Page shift */
#define PAGE_SHIFT 12
/*
* Physical<->Bus address mappings
*

View File

@ -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

View File

@ -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

View File

@ -8,9 +8,6 @@ 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) ))

View File

@ -1,26 +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
# Include platform-specific Makefile
MAKEDEPS += arch/loong64/Makefile.$(PLATFORM)
include arch/loong64/Makefile.$(PLATFORM)

View File

@ -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

View File

@ -1,120 +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 multiplier0 Element 0 of big integer to be multiplied
* @v result0 Element 0 of big integer to hold result
* @v size Number of elements
*/
void bigint_multiply_raw ( const uint64_t *multiplicand0,
const uint64_t *multiplier0,
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;
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 < size ; i++ ) {
multiplicand_element = multiplicand->element[i];
for ( j = 0 ; j < 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^{n} => ab < 2^{2n}
*/
__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" );
}
}
}

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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 */

View File

@ -1,336 +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;
unsigned int discard_size;
__asm__ __volatile__ ( "move $t0, $zero\n"
"1:\n\t"
"ld.d %3, %0, 0\n\t"
"addi.d %0, %0, 8\n\t"
"ld.d %4, %1, 0\n\t"
"add.d %4, %4, $t0\n\t"
"sltu $t0, %4, $t0\n\t"
"add.d %4, %4, %3\n\t"
"sltu $t1, %4, %3\n\t"
"or $t0, $t0, $t1\n\t"
"st.d %4, %1, 0\n\t"
"addi.d %1, %1, 8\n\t"
"addi.w %2, %2, -1\n\t"
"bnez %2, 1b"
: "=r" ( discard_addend ),
"=r" ( discard_value ),
"=r" ( discard_size ),
"=r" ( discard_addend_i ),
"=r" ( discard_value_i ),
"+m" ( *value )
: "0" ( addend0 ),
"1" ( value0 ),
"2" ( size )
: "t0", "t1" );
}
/**
* 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 ) {
uint64_t *discard_subtrahend;
uint64_t *discard_value;
uint64_t discard_subtrahend_i;
uint64_t discard_value_i;
unsigned int discard_size;
unsigned int flag = 0;
discard_subtrahend = (uint64_t*) subtrahend0;
discard_value = value0;
discard_size = size;
do {
discard_subtrahend_i = *discard_subtrahend;
discard_subtrahend++;
discard_value_i = *discard_value;
discard_value_i = discard_value_i - discard_subtrahend_i - flag;
if ( *discard_value < (discard_subtrahend_i + flag)) {
flag = 1;
} else {
flag = 0;
}
*discard_value = discard_value_i;
discard_value++;
discard_size -= 1;
} while (discard_size != 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 ) {
uint64_t *discard_value;
uint64_t discard_value_i;
unsigned int discard_size;
uint64_t current_value_i;
unsigned int flag = 0;
discard_value = value0;
discard_size = size;
do {
discard_value_i = *discard_value;
current_value_i = discard_value_i;
discard_value_i += discard_value_i + flag;
if (discard_value_i < current_value_i) {
flag = 1;
} else {
flag = 0;
}
*discard_value = discard_value_i;
discard_value++;
discard_size -= 1;
} while ( discard_size != 0 );
}
/**
* 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 ) {
uint64_t *discard_value;
uint64_t discard_value_i;
uint64_t discard_value_j;
unsigned int discard_size;
discard_value = value0;
discard_size = size;
discard_value_j = 0;
do {
discard_size -= 1;
discard_value_i = *(discard_value + discard_size);
discard_value_j = (discard_value_j << 63) | (discard_value_i >> 1);
*(discard_value + discard_size) = discard_value_j;
discard_value_j = discard_value_i;
} while ( discard_size > 0 );
}
/**
* 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,
const uint64_t *multiplier0,
uint64_t *value0, unsigned int size );
#endif /* _BITS_BIGINT_H */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -1,15 +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
#endif /* _BITS_IO_H */

View File

@ -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 */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_NAP_H
#define _BITS_NAP_H
/** @file
*
* LoongArch64-specific CPU sleeping API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_MAP_H */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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,
};

View File

@ -247,17 +247,19 @@ static void bzimage_update_header ( struct image *image,
*
* @v image bzImage file
* @v bzimg bzImage context
* @v cmdline Kernel command line
* @ret rc Return status code
*/
static int bzimage_parse_cmdline ( struct image *image,
struct bzimage_context *bzimg ) {
const char *vga;
const char *mem;
struct bzimage_context *bzimg,
char *cmdline ) {
char *sep;
char *end;
char *vga;
char *mem;
/* Look for "vga=" */
if ( ( vga = image_argument ( image, "vga=" ) ) ) {
if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
vga += 4;
sep = strchr ( vga, ' ' );
if ( sep )
*sep = '\0';
@ -268,10 +270,10 @@ static int bzimage_parse_cmdline ( struct image *image,
} else if ( strcmp ( vga, "ask" ) == 0 ) {
bzimg->vid_mode = BZI_VID_MODE_ASK;
} else {
bzimg->vid_mode = strtoul ( vga, &end, 0 );
if ( *end ) {
bzimg->vid_mode = strtoul ( vga, &vga, 0 );
if ( *vga ) {
DBGC ( image, "bzImage %p strange \"vga=\" "
"terminator '%c'\n", image, *end );
"terminator '%c'\n", image, *vga );
}
}
if ( sep )
@ -279,9 +281,10 @@ static int bzimage_parse_cmdline ( struct image *image,
}
/* Look for "mem=" */
if ( ( mem = image_argument ( image, "mem=" ) ) ) {
bzimg->mem_limit = strtoul ( mem, &end, 0 );
switch ( *end ) {
if ( ( mem = strstr ( cmdline, "mem=" ) ) ) {
mem += 4;
bzimg->mem_limit = strtoul ( mem, &mem, 0 );
switch ( *mem ) {
case 'G':
case 'g':
bzimg->mem_limit <<= 10;
@ -299,7 +302,7 @@ static int bzimage_parse_cmdline ( struct image *image,
break;
default:
DBGC ( image, "bzImage %p strange \"mem=\" "
"terminator '%c'\n", image, *end );
"terminator '%c'\n", image, *mem );
break;
}
bzimg->mem_limit -= 1;
@ -313,10 +316,11 @@ static int bzimage_parse_cmdline ( struct image *image,
*
* @v image bzImage image
* @v bzimg bzImage context
* @v cmdline Kernel command line
*/
static void bzimage_set_cmdline ( struct image *image,
struct bzimage_context *bzimg ) {
const char *cmdline = ( image->cmdline ? image->cmdline : "" );
struct bzimage_context *bzimg,
const char *cmdline ) {
size_t cmdline_len;
/* Copy command line down to real-mode portion */
@ -355,8 +359,8 @@ static size_t bzimage_load_initrd ( struct image *image,
size_t offset;
size_t pad_len;
/* Skip hidden images */
if ( initrd->flags & IMAGE_HIDDEN )
/* Do not include kernel image itself as an initrd */
if ( initrd == image )
return 0;
/* Create cpio header for non-prebuilt images */
@ -406,6 +410,10 @@ static int bzimage_check_initrds ( struct image *image,
/* Calculate total loaded length of initrds */
for_each_image ( initrd ) {
/* Skip kernel */
if ( initrd == image )
continue;
/* Calculate length */
len += bzimage_load_initrd ( image, initrd, UNULL );
len = bzimage_align ( len );
@ -520,6 +528,7 @@ static void bzimage_load_initrds ( struct image *image,
*/
static int bzimage_exec ( struct image *image ) {
struct bzimage_context bzimg;
char *cmdline = ( image->cmdline ? image->cmdline : "" );
int rc;
/* Read and parse header from image */
@ -542,7 +551,7 @@ static int bzimage_exec ( struct image *image ) {
}
/* Parse command line for bootloader parameters */
if ( ( rc = bzimage_parse_cmdline ( image, &bzimg ) ) != 0)
if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0)
return rc;
/* Check that initrds can be loaded */
@ -559,7 +568,7 @@ static int bzimage_exec ( struct image *image ) {
bzimg.rm_filesz, bzimg.pm_sz );
/* Store command line */
bzimage_set_cmdline ( image, &bzimg );
bzimage_set_cmdline ( image, &bzimg, cmdline );
/* Prepare for exiting. Must do this before loading initrds,
* since loading the initrds will corrupt the external heap.

View File

@ -204,8 +204,8 @@ static int multiboot_add_modules ( struct image *image, physaddr_t start,
break;
}
/* Skip hidden images */
if ( module_image->flags & IMAGE_HIDDEN )
/* Do not include kernel image itself as a module */
if ( module_image == image )
continue;
/* Page-align the module */

View File

@ -0,0 +1,14 @@
#ifndef _BITS_ENTROPY_H
#define _BITS_ENTROPY_H
/** @file
*
* x86-specific entropy API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/rtc_entropy.h>
#endif /* _BITS_ENTROPY_H */

View File

@ -28,7 +28,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_cpuid ( ERRFILE_ARCH | ERRFILE_CORE | 0x00110000 )
#define ERRFILE_rdtsc_timer ( ERRFILE_ARCH | ERRFILE_CORE | 0x00120000 )
#define ERRFILE_acpi_timer ( ERRFILE_ARCH | ERRFILE_CORE | 0x00130000 )
#define ERRFILE_rdrand ( ERRFILE_ARCH | ERRFILE_CORE | 0x00140000 )
#define ERRFILE_bootsector ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_bzimage ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 )

View File

@ -9,9 +9,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Page shift */
#define PAGE_SHIFT 12
#include <ipxe/x86_io.h>
#endif /* _BITS_IO_H */

View File

@ -39,9 +39,6 @@ struct x86_features {
/** Get standard features */
#define CPUID_FEATURES 0x00000001UL
/** RDRAND instruction is supported */
#define CPUID_FEATURES_INTEL_ECX_RDRAND 0x40000000UL
/** Hypervisor is present */
#define CPUID_FEATURES_INTEL_ECX_HYPERVISOR 0x80000000UL

View File

@ -0,0 +1,62 @@
#ifndef _IPXE_RTC_ENTROPY_H
#define _IPXE_RTC_ENTROPY_H
/** @file
*
* RTC-based entropy source
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#ifdef ENTROPY_RTC
#define ENTROPY_PREFIX_rtc
#else
#define ENTROPY_PREFIX_rtc __rtc_
#endif
/**
* min-entropy per sample
*
* @ret min_entropy min-entropy of each sample
*/
static inline __always_inline min_entropy_t
ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
/* The min-entropy has been measured on several platforms
* using the entropy_sample test code. Modelling the samples
* as independent, and using a confidence level of 99.99%, the
* measurements were as follows:
*
* qemu-kvm : 7.38 bits
* VMware : 7.46 bits
* Physical hardware : 2.67 bits
*
* We choose the lowest of these (2.67 bits) and apply a 50%
* safety margin to allow for some potential non-independence
* of samples.
*/
return MIN_ENTROPY ( 1.3 );
}
extern uint8_t rtc_sample ( void );
/**
* Get noise sample
*
* @ret noise Noise sample
* @ret rc Return status code
*/
static inline __always_inline int
ENTROPY_INLINE ( rtc, get_noise ) ( noise_sample_t *noise ) {
/* Get sample */
*noise = rtc_sample();
/* Always successful */
return 0;
}
#endif /* _IPXE_RTC_ENTROPY_H */

View File

@ -28,6 +28,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
/** Page shift */
#define PAGE_SHIFT 12
/*
* Physical<->Bus address mappings
*

View File

@ -39,14 +39,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/cpuid.h>
#include <ipxe/entropy.h>
struct entropy_source rtc_entropy __entropy_source ( ENTROPY_NORMAL );
/** Maximum time to wait for an RTC interrupt, in milliseconds */
#define RTC_MAX_WAIT_MS 100
/** Number of RTC interrupts to check for */
#define RTC_CHECK_COUNT 3
/** RTC interrupt handler */
extern void rtc_isr ( void );
@ -150,7 +145,6 @@ static void rtc_disable_int ( void ) {
* @ret rc Return status code
*/
static int rtc_entropy_check ( void ) {
unsigned int count = 0;
unsigned int i;
/* Check that RTC interrupts are working */
@ -164,18 +158,14 @@ static int rtc_entropy_check ( void ) {
"cli\n\t" );
/* Check for RTC interrupt flag */
if ( rtc_flag ) {
rtc_flag = 0;
if ( ++count >= RTC_CHECK_COUNT )
return 0;
}
if ( rtc_flag )
return 0;
/* Delay */
mdelay ( 1 );
}
DBGC ( &rtc_flag, "RTC timed out waiting for interrupt %d/%d\n",
( count + 1 ), RTC_CHECK_COUNT );
DBGC ( &rtc_flag, "RTC timed out waiting for interrupt\n" );
return -ETIMEDOUT;
}
@ -205,21 +195,6 @@ static int rtc_entropy_enable ( void ) {
if ( ( rc = rtc_entropy_check() ) != 0 )
goto err_check;
/* The min-entropy has been measured on several platforms
* using the entropy_sample test code. Modelling the samples
* as independent, and using a confidence level of 99.99%, the
* measurements were as follows:
*
* qemu-kvm : 7.38 bits
* VMware : 7.46 bits
* Physical hardware : 2.67 bits
*
* We choose the lowest of these (2.67 bits) and apply a 50%
* safety margin to allow for some potential non-independence
* of samples.
*/
entropy_init ( &rtc_entropy, MIN_ENTROPY ( 1.3 ) );
return 0;
err_check:
@ -243,12 +218,11 @@ static void rtc_entropy_disable ( void ) {
}
/**
* Get noise sample
* Measure a single RTC tick
*
* @ret noise Noise sample
* @ret rc Return status code
* @ret delta Length of RTC tick (in TSC units)
*/
static int rtc_get_noise ( noise_sample_t *noise ) {
uint8_t rtc_sample ( void ) {
uint32_t before;
uint32_t after;
uint32_t temp;
@ -283,14 +257,10 @@ static int rtc_get_noise ( noise_sample_t *noise ) {
: "=a" ( after ), "=d" ( before ), "=Q" ( temp )
: "2" ( 0 ) );
*noise = ( after - before );
return 0;
return ( after - before );
}
/** RTC entropy source */
struct entropy_source rtc_entropy __entropy_source ( ENTROPY_NORMAL ) = {
.name = "rtc",
.enable = rtc_entropy_enable,
.disable = rtc_entropy_disable,
.get_noise = rtc_get_noise,
};
PROVIDE_ENTROPY_INLINE ( rtc, min_entropy_per_sample );
PROVIDE_ENTROPY ( rtc, entropy_enable, rtc_entropy_enable );
PROVIDE_ENTROPY ( rtc, entropy_disable, rtc_entropy_disable );
PROVIDE_ENTROPY_INLINE ( rtc, get_noise );

View File

@ -8,9 +8,6 @@ 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__ (( regparm(0) ))

View File

@ -290,9 +290,6 @@ REQUIRE_OBJECT ( cert_cmd );
#ifdef IMAGE_MEM_CMD
REQUIRE_OBJECT ( image_mem_cmd );
#endif
#ifdef SHIM_CMD
REQUIRE_OBJECT ( shim_cmd );
#endif
/*
* Drag in miscellaneous objects

View File

@ -49,6 +49,3 @@ REQUIRE_OBJECT ( eth_slow );
#ifdef NET_PROTO_EAPOL
REQUIRE_OBJECT ( eapol );
#endif
#ifdef NET_PROTO_LLDP
REQUIRE_OBJECT ( lldp );
#endif

View File

@ -39,7 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
//#define CONSOLE_SYSLOG /* Syslog console */
//#define CONSOLE_SYSLOGS /* Encrypted syslog console */
//#define CONSOLE_VMWARE /* VMware logfile console */
#define CONSOLE_DEBUGCON /* Bochs/QEMU/KVM debug port console */
//#define CONSOLE_DEBUGCON /* Bochs/QEMU/KVM debug port console */
//#define CONSOLE_INT13 /* INT13 disk log console */
/*

View File

@ -19,15 +19,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define SMBIOS_EFI
#define SANBOOT_EFI
#define BOFM_EFI
#define ENTROPY_EFITICK
#define ENTROPY_EFIRNG
#define ENTROPY_EFI
#define TIME_EFI
#define REBOOT_EFI
#define ACPI_EFI
#define FDT_EFI
#define NET_PROTO_IPV6 /* IPv6 protocol */
#define NET_PROTO_LLDP /* Link Layer Discovery protocol */
#define DOWNLOAD_PROTO_FILE /* Local filesystem access */
@ -47,12 +45,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define USB_BLOCK /* USB block devices */
#define REBOOT_CMD /* Reboot command */
#define SHIM_CMD /* EFI shim command */
#if defined ( __i386__ ) || defined ( __x86_64__ )
#define IOAPI_X86
#define NAP_EFIX86
#define ENTROPY_RDRAND
#define CPUID_CMD /* x86 CPU feature detection command */
#define UNSAFE_STD /* Avoid setting direction flag */
#endif

View File

@ -33,8 +33,4 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define SANBOOT_PROTO_FCP
#define SANBOOT_PROTO_HTTP
#if defined ( __i386__ ) || defined ( __x86_64__ )
#define ENTROPY_RDRAND
#endif
#endif /* CONFIG_DEFAULTS_LINUX_H */

View File

@ -20,7 +20,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define SMBIOS_PCBIOS
#define SANBOOT_PCBIOS
#define ENTROPY_RTC
#define ENTROPY_RDRAND
#define TIME_RTC
#define REBOOT_PCBIOS
#define ACPI_RSDP

View File

@ -40,7 +40,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define NET_PROTO_STP /* Spanning Tree protocol */
#define NET_PROTO_LACP /* Link Aggregation control protocol */
#define NET_PROTO_EAPOL /* EAP over LAN protocol */
//#define NET_PROTO_LLDP /* Link Layer Discovery protocol */
/*
* PXE support
@ -150,7 +149,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
//#define POWEROFF_CMD /* Power off command */
//#define IMAGE_TRUST_CMD /* Image trust management commands */
//#define PCI_CMD /* PCI commands */
//#define PARAM_CMD /* Request parameter commands */
//#define PARAM_CMD /* Form parameter commands */
//#define NEIGHBOUR_CMD /* Neighbour management commands */
//#define PING_CMD /* Ping command */
//#define CONSOLE_CMD /* Console command */
@ -160,7 +159,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
//#define CERT_CMD /* Certificate management commands */
//#define IMAGE_MEM_CMD /* Read memory command */
#define IMAGE_ARCHIVE_CMD /* Archive image management commands */
//#define SHIM_CMD /* EFI shim command */
/*
* ROM-specific options

View File

@ -77,12 +77,17 @@ size_t cpio_name_len ( struct image *image ) {
*/
static void cpio_parse_cmdline ( struct image *image,
struct cpio_header *cpio ) {
const char *arg;
const char *cmdline;
char *arg;
char *end;
unsigned int mode;
/* Skip image filename */
cmdline = ( cpio_name ( image ) + cpio_name_len ( image ) );
/* Look for "mode=" */
if ( ( arg = image_argument ( image, "mode=" ) ) ) {
if ( ( arg = strstr ( cmdline, "mode=" ) ) ) {
arg += 5;
mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
if ( *end && ( *end != ' ' ) ) {
DBGC ( image, "CPIO %p strange \"mode=\" "

View File

@ -27,7 +27,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <libgen.h>
@ -56,15 +55,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** List of registered images */
struct list_head images = LIST_HEAD_INIT ( images );
/** Image selected for execution */
struct image_tag selected_image __image_tag = {
.name = "SELECTED",
};
/** Currently-executing image */
struct image_tag current_image __image_tag = {
.name = "CURRENT",
};
struct image *current_image;
/** Current image trust requirement */
static int require_trusted_images = 0;
@ -79,13 +71,8 @@ static int require_trusted_images_permanent = 0;
*/
static void free_image ( struct refcnt *refcnt ) {
struct image *image = container_of ( refcnt, struct image, refcnt );
struct image_tag *tag;
DBGC ( image, "IMAGE %s freed\n", image->name );
for_each_table_entry ( tag, IMAGE_TAGS ) {
if ( tag->image == image )
tag->image = NULL;
}
free ( image->name );
free ( image->cmdline );
uri_put ( image->uri );
@ -273,6 +260,12 @@ int register_image ( struct image *image ) {
return rc;
}
/* Avoid ending up with multiple "selected" images on
* re-registration
*/
if ( image_find_selected() )
image->flags &= ~IMAGE_SELECTED;
/* Add to image list */
image_get ( image );
image->flags |= IMAGE_REGISTERED;
@ -318,7 +311,7 @@ void unregister_image ( struct image *image ) {
struct image * find_image ( const char *name ) {
struct image *image;
for_each_image ( image ) {
list_for_each_entry ( image, &images, list ) {
if ( strcmp ( image->name, name ) == 0 )
return image;
}
@ -326,23 +319,6 @@ struct image * find_image ( const char *name ) {
return NULL;
}
/**
* Find image by tag
*
* @v tag Image tag
* @ret image Executable image, or NULL
*/
struct image * find_image_tag ( struct image_tag *tag ) {
struct image *image;
for_each_image ( image ) {
if ( tag->image == image )
return image;
}
return NULL;
}
/**
* Execute image
*
@ -369,13 +345,14 @@ int image_exec ( struct image *image ) {
if ( image->uri )
churi ( image->uri );
/* Set as currently running image */
saved_current_image = image_tag ( image, &current_image );
/* Preserve record of any currently-running image */
saved_current_image = current_image;
/* Take out a temporary reference to the image, so that it
* does not get freed when temporarily unregistered.
/* Take out a temporary reference to the image. This allows
* the image to unregister itself if necessary, without
* automatically freeing itself.
*/
image_get ( image );
current_image = image_get ( image );
/* Check that this image can be executed */
if ( ! ( image->type && image->type->exec ) ) {
@ -393,9 +370,6 @@ int image_exec ( struct image *image ) {
/* Record boot attempt */
syslog ( LOG_NOTICE, "Executing \"%s\"\n", image->name );
/* Temporarily unregister the image during its execution */
unregister_image ( image );
/* Try executing the image */
if ( ( rc = image->type->exec ( image ) ) != 0 ) {
DBGC ( image, "IMAGE %s could not execute: %s\n",
@ -412,10 +386,6 @@ int image_exec ( struct image *image ) {
image->name, strerror ( rc ) );
}
/* Re-register image (unless due to be replaced) */
if ( ! image->replacement )
register_image ( image );
/* Pick up replacement image before we drop the original
* image's temporary reference. The replacement image must
* already be registered, so we don't need to hold a temporary
@ -442,7 +412,7 @@ int image_exec ( struct image *image ) {
image_put ( image );
/* Restore previous currently-running image */
image_tag ( saved_current_image, &current_image );
current_image = saved_current_image;
/* Reset current working directory */
churi ( old_cwuri );
@ -465,7 +435,7 @@ int image_exec ( struct image *image ) {
* registered until the currently-executing image returns.
*/
int image_replace ( struct image *replacement ) {
struct image *image = current_image.image;
struct image *image = current_image;
int rc;
/* Sanity check */
@ -501,17 +471,37 @@ int image_replace ( struct image *replacement ) {
* @ret rc Return status code
*/
int image_select ( struct image *image ) {
struct image *tmp;
/* Unselect all other images */
for_each_image ( tmp )
tmp->flags &= ~IMAGE_SELECTED;
/* Check that this image can be executed */
if ( ! ( image->type && image->type->exec ) )
return -ENOEXEC;
/* Mark image as selected */
image_tag ( image, &selected_image );
image->flags |= IMAGE_SELECTED;
return 0;
}
/**
* Find selected image
*
* @ret image Executable image, or NULL
*/
struct image * image_find_selected ( void ) {
struct image *image;
for_each_image ( image ) {
if ( image->flags & IMAGE_SELECTED )
return image;
}
return NULL;
}
/**
* Change image trust requirement
*
@ -579,33 +569,3 @@ struct image * image_memory ( const char *name, userptr_t data, size_t len ) {
err_alloc_image:
return NULL;
}
/**
* Find argument within image command line
*
* @v image Image
* @v key Argument search key (including trailing delimiter)
* @ret value Argument value, or NULL if not found
*/
const char * image_argument ( struct image *image, const char *key ) {
const char *cmdline = image->cmdline;
const char *search;
const char *match;
const char *next;
/* Find argument */
for ( search = cmdline ; search ; search = next ) {
/* Find next occurrence, if any */
match = strstr ( search, key );
if ( ! match )
break;
next = ( match + strlen ( key ) );
/* Check preceding delimiter, if any */
if ( ( match == cmdline ) || isspace ( match[-1] ) )
return next;
}
return NULL;
}

View File

@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
* Request parameters
* Form parameters
*
*/
@ -37,7 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static LIST_HEAD ( parameters );
/**
* Free request parameter list
* Free form parameter list
*
* @v refcnt Reference count
*/
@ -60,7 +60,7 @@ static void free_parameters ( struct refcnt *refcnt ) {
}
/**
* Find request parameter list by name
* Find form parameter list by name
*
* @v name Parameter list name (may be NULL)
* @ret params Parameter list, or NULL if not found
@ -78,7 +78,7 @@ struct parameters * find_parameters ( const char *name ) {
}
/**
* Create request parameter list
* Create form parameter list
*
* @v name Parameter list name (may be NULL)
* @ret params Parameter list, or NULL on failure
@ -118,17 +118,15 @@ struct parameters * create_parameters ( const char *name ) {
}
/**
* Add request parameter
* Add form parameter
*
* @v params Parameter list
* @v key Parameter key
* @v value Parameter value
* @v flags Parameter flags
* @ret param Parameter, or NULL on failure
*/
struct parameter * add_parameter ( struct parameters *params,
const char *key, const char *value,
unsigned int flags ) {
const char *key, const char *value ) {
struct parameter *param;
size_t key_len;
size_t value_len;
@ -149,14 +147,11 @@ struct parameter * add_parameter ( struct parameters *params,
param->key = key_copy;
strcpy ( value_copy, value );
param->value = value_copy;
param->flags = flags;
/* Add to list of parameters */
list_add_tail ( &param->list, &params->entries );
DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"%s%s\n",
params->name, param->key, param->value,
( ( param->flags & PARAMETER_FORM ) ? " (form)" : "" ),
( ( param->flags & PARAMETER_HEADER ) ? " (header)" : "" ) );
DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"\n",
params->name, param->key, param->value );
return param;
}

View File

@ -302,7 +302,7 @@ int parse_autovivified_setting ( char *text, struct named_setting *setting ) {
}
/**
* Parse request parameter list name
* Parse form parameter list name
*
* @v text Text
* @ret params Parameter list

View File

@ -51,33 +51,59 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
__einfo_uniqify ( EINFO_EPIPE, 0x02, "Adaptive proportion test failed" )
/**
* Initialise repetition count test
* Calculate cutoff value for the repetition count test
*
* @v source Entropy source
* @ret cutoff Cutoff value
*
* This is the cutoff value for the Repetition Count Test defined in
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
*/
static void repetition_count_test_init ( struct entropy_source *source ) {
struct entropy_repetition_count_test *test =
&source->repetition_count_test;
static inline __attribute__ (( always_inline )) unsigned int
repetition_count_cutoff ( void ) {
double max_repetitions;
unsigned int cutoff;
/* Sanity checks */
assert ( test->repetition_count == 0 );
assert ( test->cutoff > 0 );
/* The cutoff formula for the repetition test is:
*
* C = ( 1 + ( -log2(W) / H_min ) )
*
* where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
* 2011 Draft) Section 8.5.2.1.3.1).
*/
max_repetitions = ( 1 + ( MIN_ENTROPY ( 30 ) /
min_entropy_per_sample() ) );
/* Round up to a whole number of repetitions. We don't have
* the ceil() function available, so do the rounding by hand.
*/
cutoff = max_repetitions;
if ( cutoff < max_repetitions )
cutoff++;
linker_assert ( ( cutoff >= max_repetitions ), rounding_error );
/* Floating-point operations are not allowed in iPXE since we
* never set up a suitable environment. Abort the build
* unless the calculated number of repetitions is a
* compile-time constant.
*/
linker_assert ( __builtin_constant_p ( cutoff ),
repetition_count_cutoff_not_constant );
return cutoff;
}
/**
* Perform repetition count test
*
* @v source Entropy source
* @v sample Noise sample
* @ret rc Return status code
*
* This is the Repetition Count Test defined in ANS X9.82 Part 2
* (October 2011 Draft) Section 8.5.2.1.2.
*/
static int repetition_count_test ( struct entropy_source *source,
noise_sample_t sample ) {
struct entropy_repetition_count_test *test =
&source->repetition_count_test;
static int repetition_count_test ( noise_sample_t sample ) {
static noise_sample_t most_recent_sample;
static unsigned int repetition_count = 0;
/* A = the most recently seen sample value
* B = the number of times that value A has been seen in a row
@ -90,71 +116,158 @@ static int repetition_count_test ( struct entropy_source *source,
* the initial value of most_recent_sample is treated as being
* undefined.)
*/
if ( ( sample == test->most_recent_sample ) &&
( test->repetition_count > 0 ) ) {
if ( ( sample == most_recent_sample ) && ( repetition_count > 0 ) ) {
/* a) If the new sample = A, then B is incremented by one. */
test->repetition_count++;
repetition_count++;
/* i. If B >= C, then an error condition is raised
* due to a failure of the test
*/
if ( test->repetition_count >= test->cutoff ) {
DBGC ( source, "ENTROPY %s excessively repeated "
"value %d (%d/%d)\n", source->name, sample,
test->repetition_count, test->cutoff );
if ( repetition_count >= repetition_count_cutoff() )
return -EPIPE_REPETITION_COUNT_TEST;
}
} else {
/* b) Else:
* i. A = new sample
*/
test->most_recent_sample = sample;
most_recent_sample = sample;
/* ii. B = 1 */
test->repetition_count = 1;
repetition_count = 1;
}
return 0;
}
/**
* Initialise adaptive proportion test
* Window size for the adaptive proportion test
*
* @v source Entropy source
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.1 allows
* five possible window sizes: 16, 64, 256, 4096 and 65536.
*
* We expect to generate relatively few (<256) entropy samples during
* a typical iPXE run; the use of a large window size would mean that
* the test would never complete a single cycle. We use a window size
* of 64, which is the smallest window size that permits values of
* H_min down to one bit per sample.
*/
static void adaptive_proportion_test_init ( struct entropy_source *source ) {
struct entropy_adaptive_proportion_test *test =
&source->adaptive_proportion_test;
#define ADAPTIVE_PROPORTION_WINDOW_SIZE 64
/* Sanity checks */
assert ( test->sample_count == 0 );
assert ( test->repetition_count == 0 );
assert ( test->cutoff > 0 );
/**
* Combine adaptive proportion test window size and min-entropy
*
* @v n N (window size)
* @v h H (min-entropy)
* @ret n_h (N,H) combined value
*/
#define APC_N_H( n, h ) ( ( (n) << 8 ) | (h) )
/* Ensure that a new test run starts immediately */
test->sample_count = ADAPTIVE_PROPORTION_WINDOW_SIZE;
/**
* Define a row of the adaptive proportion cutoff table
*
* @v h H (min-entropy)
* @v c16 Cutoff for N=16
* @v c64 Cutoff for N=64
* @v c256 Cutoff for N=256
* @v c4096 Cutoff for N=4096
* @v c65536 Cutoff for N=65536
*/
#define APC_TABLE_ROW( h, c16, c64, c256, c4096, c65536) \
case APC_N_H ( 16, h ) : return c16; \
case APC_N_H ( 64, h ) : return c64; \
case APC_N_H ( 256, h ) : return c256; \
case APC_N_H ( 4096, h ) : return c4096; \
case APC_N_H ( 65536, h ) : return c65536;
/** Value used to represent "N/A" in adaptive proportion cutoff table */
#define APC_NA 0
/**
* Look up value in adaptive proportion test cutoff table
*
* @v n N (window size)
* @v h H (min-entropy)
* @ret cutoff Cutoff
*
* This is the table of cutoff values defined in ANS X9.82 Part 2
* (October 2011 Draft) Section 8.5.2.1.3.1.2.
*/
static inline __attribute__ (( always_inline )) unsigned int
adaptive_proportion_cutoff_lookup ( unsigned int n, unsigned int h ) {
switch ( APC_N_H ( n, h ) ) {
APC_TABLE_ROW ( 1, APC_NA, 51, 168, 2240, 33537 );
APC_TABLE_ROW ( 2, APC_NA, 35, 100, 1193, 17053 );
APC_TABLE_ROW ( 3, 10, 24, 61, 643, 8705 );
APC_TABLE_ROW ( 4, 8, 16, 38, 354, 4473 );
APC_TABLE_ROW ( 5, 6, 12, 25, 200, 2321 );
APC_TABLE_ROW ( 6, 5, 9, 17, 117, 1220 );
APC_TABLE_ROW ( 7, 4, 7, 15, 71, 653 );
APC_TABLE_ROW ( 8, 4, 5, 9, 45, 358 );
APC_TABLE_ROW ( 9, 3, 4, 7, 30, 202 );
APC_TABLE_ROW ( 10, 3, 4, 5, 21, 118 );
APC_TABLE_ROW ( 11, 2, 3, 4, 15, 71 );
APC_TABLE_ROW ( 12, 2, 3, 4, 11, 45 );
APC_TABLE_ROW ( 13, 2, 2, 3, 9, 30 );
APC_TABLE_ROW ( 14, 2, 2, 3, 7, 21 );
APC_TABLE_ROW ( 15, 1, 2, 2, 6, 15 );
APC_TABLE_ROW ( 16, 1, 2, 2, 5, 11 );
APC_TABLE_ROW ( 17, 1, 1, 2, 4, 9 );
APC_TABLE_ROW ( 18, 1, 1, 2, 4, 7 );
APC_TABLE_ROW ( 19, 1, 1, 1, 3, 6 );
APC_TABLE_ROW ( 20, 1, 1, 1, 3, 5 );
default:
return APC_NA;
}
}
/**
* Calculate cutoff value for the adaptive proportion test
*
* @ret cutoff Cutoff value
*
* This is the cutoff value for the Adaptive Proportion Test defined
* in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.2.
*/
static inline __attribute__ (( always_inline )) unsigned int
adaptive_proportion_cutoff ( void ) {
unsigned int h;
unsigned int n;
unsigned int cutoff;
/* Look up cutoff value in cutoff table */
n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
h = ( min_entropy_per_sample() / MIN_ENTROPY_SCALE );
cutoff = adaptive_proportion_cutoff_lookup ( n, h );
/* Fail unless cutoff value is a build-time constant */
linker_assert ( __builtin_constant_p ( cutoff ),
adaptive_proportion_cutoff_not_constant );
/* Fail if cutoff value is N/A */
linker_assert ( ( cutoff != APC_NA ),
adaptive_proportion_cutoff_not_applicable );
return cutoff;
}
/**
* Perform adaptive proportion test
*
* @v source Entropy source
* @v sample Noise sample
* @ret rc Return status code
*
* This is the Adaptive Proportion Test for the Most Common Value
* defined in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.
*/
static int adaptive_proportion_test ( struct entropy_source *source,
noise_sample_t sample ) {
struct entropy_adaptive_proportion_test *test =
&source->adaptive_proportion_test;
static int adaptive_proportion_test ( noise_sample_t sample ) {
static noise_sample_t current_counted_sample;
static unsigned int sample_count = ADAPTIVE_PROPORTION_WINDOW_SIZE;
static unsigned int repetition_count;
/* A = the sample value currently being counted
* S = the number of samples examined in this run of the test so far
* B = the number of samples examined in this run of the test so far
* N = the total number of samples that must be observed in
* one run of the test, also known as the "window size" of
* the test
@ -171,41 +284,37 @@ static int adaptive_proportion_test ( struct entropy_source *source,
*/
/* 2. If S = N, then a new run of the test begins: */
if ( test->sample_count == ADAPTIVE_PROPORTION_WINDOW_SIZE ) {
if ( sample_count == ADAPTIVE_PROPORTION_WINDOW_SIZE ) {
/* a. A = the current sample */
test->current_counted_sample = sample;
current_counted_sample = sample;
/* b. S = 0 */
test->sample_count = 0;
sample_count = 0;
/* c. B = 0 */
test->repetition_count = 0;
repetition_count = 0;
} else {
/* Else: (the test is already running)
* a. S = S + 1
*/
test->sample_count++;
sample_count++;
/* b. If A = the current sample, then: */
if ( sample == test->current_counted_sample ) {
if ( sample == current_counted_sample ) {
/* i. B = B + 1 */
test->repetition_count++;
repetition_count++;
/* ii. If S (sic) > C then raise an error
* condition, because the test has
* detected a failure
*/
if ( test->repetition_count > test->cutoff ) {
DBGC ( source, "ENTROPY %s excessively "
"repeated value %d (%d/%d)\n",
source->name, sample,
test->repetition_count, test->cutoff );
if ( repetition_count > adaptive_proportion_cutoff() )
return -EPIPE_ADAPTIVE_PROPORTION_TEST;
}
}
}
@ -215,180 +324,62 @@ static int adaptive_proportion_test ( struct entropy_source *source,
/**
* Get entropy sample
*
* @v source Entropy source
* @ret entropy Entropy sample
* @ret rc Return status code
*
* This is the GetEntropy function defined in ANS X9.82 Part 2
* (October 2011 Draft) Section 6.5.1.
*/
static int get_entropy ( struct entropy_source *source,
entropy_sample_t *entropy ) {
static int get_entropy ( entropy_sample_t *entropy ) {
static int rc = 0;
noise_sample_t noise;
int rc;
/* Any failure is permanent */
if ( ( rc = source->rc ) != 0 )
goto err_broken;
if ( rc != 0 )
return rc;
/* Get noise sample */
if ( ( rc = get_noise ( source, &noise ) ) != 0 )
goto err_get_noise;
if ( ( rc = get_noise ( &noise ) ) != 0 )
return rc;
/* Perform Repetition Count Test and Adaptive Proportion Test
* as mandated by ANS X9.82 Part 2 (October 2011 Draft)
* Section 8.5.2.1.1.
*/
if ( ( rc = repetition_count_test ( source, noise ) ) != 0 )
goto err_repetition_count_test;
if ( ( rc = adaptive_proportion_test ( source, noise ) ) != 0 )
goto err_adaptive_proportion_test;
if ( ( rc = repetition_count_test ( noise ) ) != 0 )
return rc;
if ( ( rc = adaptive_proportion_test ( noise ) ) != 0 )
return rc;
/* We do not use any optional conditioning component */
*entropy = noise;
return 0;
err_adaptive_proportion_test:
err_repetition_count_test:
err_get_noise:
source->rc = rc;
err_broken:
return rc;
}
/**
* Initialise startup test
* Calculate number of samples required for startup tests
*
* @v source Entropy source
*/
static void startup_test_init ( struct entropy_source *source ) {
struct entropy_startup_test *test = &source->startup_test;
/* Sanity check */
assert ( test->tested == 0 );
assert ( test->count > 0 );
}
/**
* Perform startup test
* @ret num_samples Number of samples required
*
* @v source Entropy source
* @ret rc Return status code
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
* that at least one full cycle of the continuous tests must be
* performed at start-up.
*/
static int startup_test ( struct entropy_source *source ) {
struct entropy_startup_test *test = &source->startup_test;
entropy_sample_t sample;
int rc;
static inline __attribute__ (( always_inline )) unsigned int
startup_test_count ( void ) {
unsigned int num_samples;
/* Perform mandatory number of startup tests */
for ( ; test->tested < test->count ; test->tested++ ) {
if ( ( rc = get_entropy ( source, &sample ) ) != 0 ) {
DBGC ( source, "ENTROPY %s failed: %s\n",
source->name, strerror ( rc ) );
return rc;
}
}
/* At least max(N,C) samples shall be generated by the noise
* source for start-up testing.
*/
num_samples = repetition_count_cutoff();
if ( num_samples < adaptive_proportion_cutoff() )
num_samples = adaptive_proportion_cutoff();
linker_assert ( __builtin_constant_p ( num_samples ),
startup_test_count_not_constant );
return 0;
}
/**
* Enable entropy gathering
*
* @v source Entropy source
* @ret rc Return status code
*/
int entropy_enable ( struct entropy_source *source ) {
int rc;
/* Refuse to enable a previously failed source */
if ( ( rc = source->rc ) != 0 )
return rc;
/* Enable entropy source */
if ( ( rc = source->enable() ) != 0 ) {
DBGC ( source, "ENTROPY %s could not enable: %s\n",
source->name, strerror ( rc ) );
source->rc = rc;
return rc;
}
/* Sanity check */
assert ( source->min_entropy_per_sample > 0 );
/* Initialise test state if this source has not previously been used */
if ( source->startup_test.tested == 0 ) {
repetition_count_test_init ( source );
adaptive_proportion_test_init ( source );
startup_test_init ( source );
}
DBGC ( source, "ENTROPY %s enabled\n", source->name );
return 0;
}
/**
* Enable and test entropy source
*
* @v source Entropy source
* @ret rc Return status code
*/
static int entropy_enable_and_test ( struct entropy_source *source ) {
int rc;
/* Enable source */
if ( ( rc = entropy_enable ( source ) ) != 0 )
goto err_enable;
/* Test source */
if ( ( rc = startup_test ( source ) ) != 0 )
goto err_test;
DBGC ( source, "ENTROPY %s passed %d startup tests\n",
source->name, source->startup_test.count );
return 0;
err_test:
entropy_disable ( source );
err_enable:
assert ( source->rc == rc );
return rc;
}
/**
* Enable first working entropy source
*
* @v source Entropy source to fill in
* @ret rc Return status code
*/
static int entropy_enable_working ( struct entropy_source **source ) {
int rc;
/* Find the first working source */
rc = -ENOENT;
for_each_table_entry ( *source, ENTROPY_SOURCES ) {
if ( ( rc = entropy_enable_and_test ( *source ) ) == 0 )
return 0;
}
DBGC ( *source, "ENTROPY has no working sources: %s\n",
strerror ( rc ) );
return rc;
}
/**
* Disable entropy gathering
*
* @v source Entropy source
*/
void entropy_disable ( struct entropy_source *source ) {
/* Disable entropy gathering, if applicable */
if ( source->disable )
source->disable();
DBGC ( source, "ENTROPY %s disabled\n", source->name );
return num_samples;
}
/**
@ -411,7 +402,7 @@ static uint32_t make_next_nonce ( void ) {
/**
* Obtain entropy input temporary buffer
*
* @v min_entropy Min-entropy required
* @v num_samples Number of entropy samples
* @v tmp Temporary buffer
* @v tmp_len Length of temporary buffer
* @ret rc Return status code
@ -421,41 +412,47 @@ static uint32_t make_next_nonce ( void ) {
* and condensing each entropy source output after each GetEntropy
* call) as defined in ANS X9.82 Part 4 (April 2011 Draft) Section
* 13.3.4.2.
*
* To minimise code size, the number of samples required is calculated
* at compilation time.
*/
int get_entropy_input_tmp ( min_entropy_t min_entropy, uint8_t *tmp,
int get_entropy_input_tmp ( unsigned int num_samples, uint8_t *tmp,
size_t tmp_len ) {
struct entropy_source *source;
static unsigned int startup_tested = 0;
struct {
uint32_t nonce;
entropy_sample_t sample;
} __attribute__ (( packed )) data;;
uint8_t df_buf[tmp_len];
min_entropy_t entropy_total;
unsigned int num_samples;
unsigned int i;
int rc;
/* Enable entropy gathering */
if ( ( rc = entropy_enable_working ( &source ) ) != 0 )
goto err_enable_working;
if ( ( rc = entropy_enable() ) != 0 )
return rc;
/* Sanity checks */
assert ( source->startup_test.count > 0 );
assert ( source->startup_test.tested >= source->startup_test.count );
/* Perform mandatory startup tests, if not yet performed */
for ( ; startup_tested < startup_test_count() ; startup_tested++ ) {
if ( ( rc = get_entropy ( &data.sample ) ) != 0 )
goto err_get_entropy;
}
/* 3. entropy_total = 0 */
entropy_total = MIN_ENTROPY ( 0 );
/* 3. entropy_total = 0
*
* (Nothing to do; the number of entropy samples required has
* already been precalculated.)
*/
/* 4. tmp = a fixed n-bit value, such as 0^n */
memset ( tmp, 0, tmp_len );
/* 5. While ( entropy_total < min_entropy ) */
for ( num_samples = 0 ; entropy_total < min_entropy ; num_samples++ ) {
while ( num_samples-- ) {
/* 5.1. ( status, entropy_bitstring, assessed_entropy )
* = GetEntropy()
* 5.2. If status indicates an error, return ( status, Null )
*/
if ( ( rc = get_entropy ( source, &data.sample ) ) != 0 )
if ( ( rc = get_entropy ( &data.sample ) ) != 0 )
goto err_get_entropy;
/* 5.3. nonce = MakeNextNonce() */
@ -469,26 +466,19 @@ int get_entropy_input_tmp ( min_entropy_t min_entropy, uint8_t *tmp,
for ( i = 0 ; i < tmp_len ; i++ )
tmp[i] ^= df_buf[i];
/* 5.5. entropy_total = entropy_total + assessed_entropy */
entropy_total += source->min_entropy_per_sample;
/* 5.5. entropy_total = entropy_total + assessed_entropy
*
* (Nothing to do; the number of entropy samples
* required has already been precalculated.)
*/
}
/* Disable entropy gathering */
entropy_disable ( source );
entropy_disable();
DBGC ( source, "ENTROPY %s gathered %d bits in %d samples\n",
source->name, ( min_entropy / MIN_ENTROPY_SCALE ), num_samples );
return 0;
err_get_entropy:
entropy_disable ( source );
assert ( source->rc == rc );
err_enable_working:
entropy_disable();
return rc;
}
/* Drag in objects via entropy_enable */
REQUIRING_SYMBOL ( entropy_enable );
/* Drag in entropy configuration */
REQUIRE_OBJECT ( config_entropy );

View File

@ -1,8 +1,10 @@
/*
* Copyright (C) 2012 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 (at your option) any later version.
* 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
@ -21,31 +23,18 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <config/entropy.h>
/** @file
*
* Entropy configuration options
* Nonexistent entropy source
*
*
* This source provides no entropy and must NOT be used in a
* security-sensitive environment.
*/
PROVIDE_REQUIRING_SYMBOL();
#include <ipxe/entropy.h>
/*
* 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
PROVIDE_ENTROPY_INLINE ( null, min_entropy_per_sample );
PROVIDE_ENTROPY_INLINE ( null, entropy_enable );
PROVIDE_ENTROPY_INLINE ( null, entropy_disable );
PROVIDE_ENTROPY_INLINE ( null, get_noise );

View File

@ -609,7 +609,6 @@ static void scsicmd_read_capacity_cmd ( struct scsi_command *scsicmd,
*/
static void scsicmd_read_capacity_done ( struct scsi_command *scsicmd,
int rc ) {
struct scsi_device *scsidev = scsicmd->scsidev;
struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
@ -646,9 +645,6 @@ static void scsicmd_read_capacity_done ( struct scsi_command *scsicmd,
}
capacity.max_count = -1U;
/* Allow transport layer to update capacity */
block_capacity ( &scsidev->scsi, &capacity );
/* Return capacity to caller */
block_capacity ( &scsicmd->block, &capacity );

View File

@ -98,16 +98,8 @@ static void eisa_remove ( struct eisa_device *eisa ) {
static int eisabus_probe ( struct root_device *rootdev ) {
struct eisa_device *eisa = NULL;
unsigned int slot;
uint8_t system;
int rc;
/* Check for EISA system board */
system = inb ( EISA_VENDOR_ID );
if ( system & 0x80 ) {
DBG ( "No EISA system board (read %02x)\n", system );
return -ENODEV;
}
for ( slot = EISA_MIN_SLOT ; slot <= EISA_MAX_SLOT ; slot++ ) {
/* Allocate struct eisa_device */
if ( ! eisa )

View File

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

View File

@ -290,18 +290,6 @@ static int intel_reset ( struct intel_nic *intel ) {
pba, readl ( intel->regs + INTEL_PBA ) );
}
/* The Intel I210's packet buffer size registers reset only on
* power up. If an operating system changes these but then
* the computer recieves a reset signal without losing power,
* the registers will stay the same (but be incompatible with
* other register defaults), thus making the device unable to
* pass traffic.
*/
if ( intel->flags & INTEL_PBSIZE_RST ) {
writel ( INTEL_RXPBS_I210, intel->regs + INTEL_RXPBS );
writel ( INTEL_TXPBS_I210, intel->regs + INTEL_TXPBS );
}
/* Always reset MAC. Required to reset the TX and RX rings. */
writel ( ( ctrl | INTEL_CTRL_RST ), intel->regs + INTEL_CTRL );
mdelay ( INTEL_RESET_DELAY_MS );
@ -1151,7 +1139,7 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x1525, "82567v-4", "82567V-4", 0 ),
PCI_ROM ( 0x8086, 0x1526, "82576-5", "82576", 0 ),
PCI_ROM ( 0x8086, 0x1527, "82580-f2", "82580 Fiber", 0 ),
PCI_ROM ( 0x8086, 0x1533, "i210", "I210", INTEL_PBSIZE_RST ),
PCI_ROM ( 0x8086, 0x1533, "i210", "I210", 0 ),
PCI_ROM ( 0x8086, 0x1539, "i211", "I211", 0 ),
PCI_ROM ( 0x8086, 0x153a, "i217lm", "I217-LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x153b, "i217v", "I217-V", 0 ),
@ -1159,7 +1147,7 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x155a, "i218lm", "I218-LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x156f, "i219lm", "I219-LM", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x1570, "i219v", "I219-V", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x157b, "i210-2", "I210", INTEL_PBSIZE_RST ),
PCI_ROM ( 0x8086, 0x157b, "i210-2", "I210", 0 ),
PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", INTEL_NO_PHY_RST ),

View File

@ -138,10 +138,6 @@ struct intel_descriptor {
/** Packet Buffer Size */
#define INTEL_PBS 0x01008UL
/** Receive packet buffer size */
#define INTEL_RXPBS 0x02404UL
#define INTEL_RXPBS_I210 0x000000a2UL /**< I210 power-up default */
/** Receive Descriptor register block */
#define INTEL_RD 0x02800UL
@ -158,10 +154,6 @@ struct intel_descriptor {
/** Receive buffer length */
#define INTEL_RX_MAX_LEN 2048
/** Transmit packet buffer size */
#define INTEL_TXPBS 0x03404UL
#define INTEL_TXPBS_I210 0x04000014UL /**< I210 power-up default */
/** Transmit Descriptor register block */
#define INTEL_TD 0x03800UL
@ -327,8 +319,6 @@ enum intel_flags {
INTEL_NO_ASDE = 0x0008,
/** Reset may cause a complete device hang */
INTEL_RST_HANG = 0x0010,
/** PBSIZE registers must be explicitly reset */
INTEL_PBSIZE_RST = 0x0020,
};
/** The i219 has a seriously broken reset mechanism */

View File

@ -473,7 +473,6 @@ static struct pci_device_id intelx_nics[] = {
PCI_ROM ( 0x8086, 0x10f9, "82599-cx4", "82599 (CX4)", 0 ),
PCI_ROM ( 0x8086, 0x10fb, "82599-sfp", "82599 (SFI/SFP+)", 0 ),
PCI_ROM ( 0x8086, 0x10fc, "82599-xaui", "82599 (XAUI/BX4)", 0 ),
PCI_ROM ( 0x8086, 0x151c, "82599-tn", "82599 (TN)", 0 ),
PCI_ROM ( 0x8086, 0x1528, "x540t", "X540-AT2/X540-BT2", 0 ),
PCI_ROM ( 0x8086, 0x154d, "82599-sfp-sf2", "82599 (SFI/SFP+)", 0 ),
PCI_ROM ( 0x8086, 0x1557, "82599en-sfp", "82599 (Single Port SFI Only)", 0 ),

View File

@ -129,7 +129,7 @@ static int imgsingle_exec ( int argc, char **argv,
&image ) ) != 0 )
goto err_acquire;
} else {
image = find_image_tag ( &selected_image );
image = image_find_selected();
if ( ! image ) {
printf ( "No image selected\n" );
goto err_acquire;

View File

@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
* Request parameter commands
* Form parameter commands
*
*/
@ -90,16 +90,12 @@ static int params_exec ( int argc, char **argv ) {
struct param_options {
/** Parameter list name */
char *params;
/** Parameter is a header */
int header;
};
/** "param" option list */
static struct option_descriptor param_opts[] = {
OPTION_DESC ( "params", 'p', required_argument,
struct param_options, params, parse_string ),
OPTION_DESC ( "header", 'H', no_argument,
struct param_options, header, parse_flag ),
};
/** "param" command descriptor */
@ -118,7 +114,6 @@ static int param_exec ( int argc, char **argv ) {
struct param_options opts;
char *key;
char *value;
unsigned int flags;
struct parameters *params;
struct parameter *param;
int rc;
@ -137,15 +132,12 @@ static int param_exec ( int argc, char **argv ) {
goto err_parse_value;
}
/* Construct flags */
flags = ( opts.header ? PARAMETER_HEADER : PARAMETER_FORM );
/* Identify parameter list */
if ( ( rc = parse_parameters ( opts.params, &params ) ) != 0 )
goto err_parse_parameters;
/* Add parameter */
param = add_parameter ( params, key, value, flags );
param = add_parameter ( params, key, value );
if ( ! param ) {
rc = -ENOMEM;
goto err_add_parameter;
@ -162,7 +154,7 @@ static int param_exec ( int argc, char **argv ) {
return rc;
}
/** Request parameter commands */
/** Form parameter commands */
struct command param_commands[] __command = {
{
.name = "params",

View File

@ -1,117 +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 );
#include <getopt.h>
#include <ipxe/command.h>
#include <ipxe/parseopt.h>
#include <ipxe/efi/efi_image.h>
#include <usr/imgmgmt.h>
#include <usr/shimmgmt.h>
/** @file
*
* EFI shim command
*
*/
/** "shim" options */
struct shim_options {
/** Download timeout */
unsigned long timeout;
/** Require third party loader */
int require_loader;
/** Allow PXE base code protocol */
int allow_pxe;
/** Allow SBAT variable access */
int allow_sbat;
};
/** "shim" option list */
static struct option_descriptor shim_opts[] = {
OPTION_DESC ( "timeout", 't', required_argument,
struct shim_options, timeout, parse_timeout ),
OPTION_DESC ( "require-loader", 'l', no_argument,
struct shim_options, require_loader, parse_flag ),
OPTION_DESC ( "allow-pxe", 'p', no_argument,
struct shim_options, allow_pxe, parse_flag ),
OPTION_DESC ( "allow-sbat", 's', no_argument,
struct shim_options, allow_sbat, parse_flag ),
};
/** "shim" command descriptor */
static struct command_descriptor shim_cmd =
COMMAND_DESC ( struct shim_options, shim_opts, 0, 1, NULL );
/**
* The "shim" command
*
* @v argc Argument count
* @v argv Argument list
* @ret rc Return status code
*/
static int shim_exec ( int argc, char **argv ) {
struct shim_options opts;
struct image *image = NULL;
struct image *kernel;
char *name_uri;
int download;
int rc;
/* Parse options */
if ( ( rc = parse_options ( argc, argv, &shim_cmd, &opts ) ) != 0 )
goto err_parse;
/* Decide whether or not to download images */
kernel = find_image_tag ( &selected_image );
download = ( ! ( kernel && efi_can_load ( kernel ) ) );
/* Parse name/URI string */
name_uri = argv[optind];
/* Acquire image, if applicable */
if ( download && name_uri &&
( ( rc = imgacquire ( name_uri, opts.timeout,
&image ) ) != 0 ) ) {
goto err_image;
}
/* (Un)register as shim */
if ( ( rc = shim ( image, opts.require_loader, opts.allow_pxe,
opts.allow_sbat ) ) != 0 )
goto err_shim;
err_shim:
err_image:
err_parse:
return rc;
}
/** Shim commands */
struct command shim_commands[] __command = {
{
.name = "shim",
.exec = shim_exec,
},
};

View File

@ -31,8 +31,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/efi/efi_wrap.h>
#include <ipxe/efi/efi_pxe.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_image.h>
#include <ipxe/efi/efi_shim.h>
#include <ipxe/image.h>
#include <ipxe/init.h>
#include <ipxe/features.h>
@ -111,14 +109,18 @@ efi_image_path ( struct image *image, EFI_DEVICE_PATH_PROTOCOL *parent ) {
*/
static wchar_t * efi_image_cmdline ( struct image *image ) {
wchar_t *cmdline;
size_t len;
/* Allocate and construct command line */
if ( efi_asprintf ( &cmdline, "%s%s%s", image->name,
( image->cmdline ? " " : "" ),
( image->cmdline ? image->cmdline : "" ) ) < 0 ) {
len = ( strlen ( image->name ) +
( image->cmdline ?
( 1 /* " " */ + strlen ( image->cmdline ) ) : 0 ) );
cmdline = zalloc ( ( len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
if ( ! cmdline )
return NULL;
}
efi_snprintf ( cmdline, ( len + 1 /* NUL */ ), "%s%s%s",
image->name,
( image->cmdline ? " " : "" ),
( image->cmdline ? image->cmdline : "" ) );
return cmdline;
}
@ -136,65 +138,47 @@ static int efi_image_exec ( struct image *image ) {
EFI_LOADED_IMAGE_PROTOCOL *image;
void *interface;
} loaded;
struct image *shim;
struct image *exec;
EFI_HANDLE handle;
EFI_MEMORY_TYPE type;
wchar_t *cmdline;
unsigned int toggle;
EFI_STATUS efirc;
int rc;
/* Find an appropriate device handle to use */
snpdev = last_opened_snpdev();
if ( ! snpdev ) {
DBGC ( image, "EFIIMAGE %s could not identify SNP device\n",
image->name );
DBGC ( image, "EFIIMAGE %p could not identify SNP device\n",
image );
rc = -ENODEV;
goto err_no_snpdev;
}
/* Use shim instead of directly executing image if applicable */
shim = ( efi_can_load ( image ) ?
NULL : find_image_tag ( &efi_shim ) );
exec = ( shim ? shim : image );
if ( shim ) {
DBGC ( image, "EFIIMAGE %s executing via %s\n",
image->name, shim->name );
}
/* Re-register as a hidden image to allow for access via file I/O */
toggle = ( ~image->flags & IMAGE_HIDDEN );
image->flags |= IMAGE_HIDDEN;
if ( ( rc = register_image ( image ) ) != 0 )
goto err_register_image;
/* Install file I/O protocols */
if ( ( rc = efi_file_install ( snpdev->handle ) ) != 0 ) {
DBGC ( image, "EFIIMAGE %s could not install file protocol: "
"%s\n", image->name, strerror ( rc ) );
DBGC ( image, "EFIIMAGE %p could not install file protocol: "
"%s\n", image, strerror ( rc ) );
goto err_file_install;
}
/* Install PXE base code protocol */
if ( ( rc = efi_pxe_install ( snpdev->handle, snpdev->netdev ) ) != 0 ){
DBGC ( image, "EFIIMAGE %s could not install PXE protocol: "
"%s\n", image->name, strerror ( rc ) );
DBGC ( image, "EFIIMAGE %p could not install PXE protocol: "
"%s\n", image, strerror ( rc ) );
goto err_pxe_install;
}
/* Install iPXE download protocol */
if ( ( rc = efi_download_install ( snpdev->handle ) ) != 0 ) {
DBGC ( image, "EFIIMAGE %s could not install iPXE download "
"protocol: %s\n", image->name, strerror ( rc ) );
DBGC ( image, "EFIIMAGE %p could not install iPXE download "
"protocol: %s\n", image, strerror ( rc ) );
goto err_download_install;
}
/* Create device path for image */
path = efi_image_path ( exec, snpdev->path );
path = efi_image_path ( image, snpdev->path );
if ( ! path ) {
DBGC ( image, "EFIIMAGE %s could not create device path\n",
image->name );
DBGC ( image, "EFIIMAGE %p could not create device path\n",
image );
rc = -ENOMEM;
goto err_image_path;
}
@ -202,30 +186,21 @@ static int efi_image_exec ( struct image *image ) {
/* Create command line for image */
cmdline = efi_image_cmdline ( image );
if ( ! cmdline ) {
DBGC ( image, "EFIIMAGE %s could not create command line\n",
image->name );
DBGC ( image, "EFIIMAGE %p could not create command line\n",
image );
rc = -ENOMEM;
goto err_cmdline;
}
/* Install shim special handling if applicable */
if ( shim &&
( ( rc = efi_shim_install ( shim, snpdev->handle,
&cmdline ) ) != 0 ) ){
DBGC ( image, "EFIIMAGE %s could not install shim handling: "
"%s\n", image->name, strerror ( rc ) );
goto err_shim_install;
}
/* Attempt loading image */
handle = NULL;
if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path,
user_to_virt ( exec->data, 0 ),
exec->len, &handle ) ) != 0 ) {
user_to_virt ( image->data, 0 ),
image->len, &handle ) ) != 0 ) {
/* Not an EFI image */
rc = -EEFI_LOAD ( efirc );
DBGC ( image, "EFIIMAGE %s could not load: %s\n",
image->name, strerror ( rc ) );
DBGC ( image, "EFIIMAGE %p could not load: %s\n",
image, strerror ( rc ) );
if ( efirc == EFI_SECURITY_VIOLATION ) {
goto err_load_image_security_violation;
} else {
@ -245,8 +220,8 @@ static int efi_image_exec ( struct image *image ) {
/* Some EFI 1.10 implementations seem not to fill in DeviceHandle */
if ( loaded.image->DeviceHandle == NULL ) {
DBGC ( image, "EFIIMAGE %s filling in missing DeviceHandle\n",
image->name );
DBGC ( image, "EFIIMAGE %p filling in missing DeviceHandle\n",
image );
loaded.image->DeviceHandle = snpdev->handle;
}
@ -276,14 +251,14 @@ static int efi_image_exec ( struct image *image ) {
/* Start the image */
if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {
rc = -EEFI_START ( efirc );
DBGC ( image, "EFIIMAGE %s could not start (or returned with "
"error): %s\n", image->name, strerror ( rc ) );
DBGC ( image, "EFIIMAGE %p could not start (or returned with "
"error): %s\n", image, strerror ( rc ) );
goto err_start_image;
}
/* If image was a driver, connect it up to anything available */
if ( type == EfiBootServicesCode ) {
DBGC ( image, "EFIIMAGE %s connecting drivers\n", image->name );
DBGC ( image, "EFIIMAGE %p connecting drivers\n", image );
efi_driver_reconnect_all();
}
@ -311,9 +286,6 @@ static int efi_image_exec ( struct image *image ) {
if ( rc != 0 )
bs->UnloadImage ( handle );
err_load_image:
if ( shim )
efi_shim_uninstall();
err_shim_install:
free ( cmdline );
err_cmdline:
free ( path );
@ -324,9 +296,6 @@ static int efi_image_exec ( struct image *image ) {
err_pxe_install:
efi_file_uninstall ( snpdev->handle );
err_file_install:
unregister_image ( image );
err_register_image:
image->flags ^= toggle;
err_no_snpdev:
return rc;
}
@ -355,8 +324,8 @@ static int efi_image_probe ( struct image *image ) {
image->len, &handle ) ) != 0 ) {
/* Not an EFI image */
rc = -EEFI_LOAD ( efirc );
DBGC ( image, "EFIIMAGE %s could not load: %s\n",
image->name, strerror ( rc ) );
DBGC ( image, "EFIIMAGE %p could not load: %s\n",
image, strerror ( rc ) );
if ( efirc == EFI_SECURITY_VIOLATION ) {
goto err_load_image_security_violation;
} else {
@ -377,75 +346,9 @@ static int efi_image_probe ( struct image *image ) {
return rc;
}
/**
* Probe EFI PE image
*
* @v image EFI file
* @ret rc Return status code
*
* The extremely broken UEFI Secure Boot model provides no way for us
* to unambiguously determine that a valid EFI executable image was
* rejected by LoadImage() because it failed signature verification.
* We must therefore use heuristics to guess whether not an image that
* was rejected by LoadImage() could still be loaded via a separate PE
* loader such as the UEFI shim.
*/
static int efi_pe_image_probe ( struct image *image ) {
const UINT16 magic = ( ( sizeof ( UINTN ) == sizeof ( uint32_t ) ) ?
EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC :
EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC );
union {
EFI_IMAGE_DOS_HEADER dos;
EFI_IMAGE_OPTIONAL_HEADER_UNION pe;
} u;
/* Check for existence of DOS header */
if ( image->len < sizeof ( u.dos ) ) {
DBGC ( image, "EFIIMAGE %s too short for DOS header\n",
image->name );
return -ENOEXEC;
}
copy_from_user ( &u.dos, image->data, 0, sizeof ( u.dos ) );
if ( u.dos.e_magic != EFI_IMAGE_DOS_SIGNATURE ) {
DBGC ( image, "EFIIMAGE %s missing MZ signature\n",
image->name );
return -ENOEXEC;
}
/* Check for existence of PE header */
if ( ( image->len < u.dos.e_lfanew ) ||
( ( image->len - u.dos.e_lfanew ) < sizeof ( u.pe ) ) ) {
DBGC ( image, "EFIIMAGE %s too short for PE header\n",
image->name );
return -ENOEXEC;
}
copy_from_user ( &u.pe, image->data, u.dos.e_lfanew, sizeof ( u.pe ) );
if ( u.pe.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE ) {
DBGC ( image, "EFIIMAGE %s missing PE signature\n",
image->name );
return -ENOEXEC;
}
/* Check PE header magic */
if ( u.pe.Pe32.OptionalHeader.Magic != magic ) {
DBGC ( image, "EFIIMAGE %s incorrect magic %04x\n",
image->name, u.pe.Pe32.OptionalHeader.Magic );
return -ENOEXEC;
}
return 0;
}
/** EFI image types */
struct image_type efi_image_type[] __image_type ( PROBE_NORMAL ) = {
{
.name = "EFI",
.probe = efi_image_probe,
.exec = efi_image_exec,
},
{
.name = "EFIPE",
.probe = efi_pe_image_probe,
.exec = efi_image_exec,
},
/** EFI image type */
struct image_type efi_image_type __image_type ( PROBE_NORMAL ) = {
.name = "EFI",
.probe = efi_image_probe,
.exec = efi_image_exec,
};

View File

@ -197,6 +197,11 @@ static int script_exec ( struct image *image ) {
size_t saved_offset;
int rc;
/* Temporarily de-register image, so that a "boot" command
* doesn't throw us into an execution loop.
*/
unregister_image ( image );
/* Preserve state of any currently-running script */
saved_offset = script_offset;
@ -207,6 +212,10 @@ static int script_exec ( struct image *image ) {
/* Restore saved state */
script_offset = saved_offset;
/* Re-register image (unless we have been replaced) */
if ( ! image->replacement )
register_image ( image );
return rc;
}
@ -311,7 +320,6 @@ static int terminate_on_label_found ( int rc ) {
* @ret rc Return status code
*/
static int goto_exec ( int argc, char **argv ) {
struct image *image = current_image.image;
struct goto_options opts;
size_t saved_offset;
int rc;
@ -321,7 +329,7 @@ static int goto_exec ( int argc, char **argv ) {
return rc;
/* Sanity check */
if ( ! image ) {
if ( ! current_image ) {
rc = -ENOTTY;
printf ( "Not in a script: %s\n", strerror ( rc ) );
return rc;
@ -332,10 +340,10 @@ static int goto_exec ( int argc, char **argv ) {
/* Find label */
saved_offset = script_offset;
if ( ( rc = process_script ( image, goto_find_label,
if ( ( rc = process_script ( current_image, goto_find_label,
terminate_on_label_found ) ) != 0 ) {
script_offset = saved_offset;
DBGC ( image, "[%04zx] No such label :%s\n",
DBGC ( current_image, "[%04zx] No such label :%s\n",
script_offset, goto_label );
return rc;
}

View File

@ -262,10 +262,10 @@ static inline void eplatform_discard ( int dummy __unused, ... ) {}
".balign 8\n\t" \
"\n1:\n\t" \
".long ( 4f - 1b )\n\t" \
".long %" ASM_NO_PREFIX "0\n\t" \
".long %c0\n\t" \
".long ( 2f - 1b )\n\t" \
".long ( 3f - 1b )\n\t" \
".long %" ASM_NO_PREFIX "1\n\t" \
".long %c1\n\t" \
"\n2:\t.asciz \"" __einfo_desc ( einfo ) "\"\n\t" \
"\n3:\t.asciz \"" __FILE__ "\"\n\t" \
".balign 8\n\t" \

View File

@ -1,31 +0,0 @@
#ifndef _IPXE_EFI_SHIM_LOCK_PROTOCOL_H
#define _IPXE_EFI_SHIM_LOCK_PROTOCOL_H
/** @file
*
* EFI "shim lock" protocol
*
*/
FILE_LICENCE ( BSD3 );
#define EFI_SHIM_LOCK_PROTOCOL_GUID \
{ 0x605dab50, 0xe046, 0x4300, \
{ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }
#define SHIMAPI __asmcall
typedef
EFI_STATUS SHIMAPI
(*EFI_SHIM_LOCK_VERIFY) (
IN VOID *buffer,
IN UINT32 size
);
typedef struct _EFI_SHIM_LOCK_PROTOCOL {
EFI_SHIM_LOCK_VERIFY Verify;
VOID *Reserved1;
VOID *Reserved2;
} EFI_SHIM_LOCK_PROTOCOL;
#endif /*_IPXE_EFI_SHIM_LOCK_PROTOCOL_H */

View File

@ -197,7 +197,6 @@ extern EFI_GUID efi_pci_io_protocol_guid;
extern EFI_GUID efi_pci_root_bridge_io_protocol_guid;
extern EFI_GUID efi_pxe_base_code_protocol_guid;
extern EFI_GUID efi_serial_io_protocol_guid;
extern EFI_GUID efi_shim_lock_protocol_guid;
extern EFI_GUID efi_simple_file_system_protocol_guid;
extern EFI_GUID efi_simple_network_protocol_guid;
extern EFI_GUID efi_simple_pointer_protocol_guid;

View File

@ -11,7 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
extern int efi_autoexec_load ( EFI_HANDLE device,
EFI_DEVICE_PATH_PROTOCOL *path );
extern int efi_autoexec_load ( EFI_HANDLE device );
#endif /* _IPXE_EFI_AUTOEXEC_H */

View File

@ -0,0 +1,35 @@
#ifndef _IPXE_EFI_ENTROPY_H
#define _IPXE_EFI_ENTROPY_H
/** @file
*
* EFI entropy source
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#ifdef ENTROPY_EFI
#define ENTROPY_PREFIX_efi
#else
#define ENTROPY_PREFIX_efi __efi_
#endif
/**
* min-entropy per sample
*
* @ret min_entropy min-entropy of each sample
*/
static inline __always_inline min_entropy_t
ENTROPY_INLINE ( efi, min_entropy_per_sample ) ( void ) {
/* We use essentially the same mechanism as for the BIOS
* RTC-based entropy source, and so assume the same
* min-entropy per sample.
*/
return MIN_ENTROPY ( 1.3 );
}
#endif /* _IPXE_EFI_ENTROPY_H */

View File

@ -1,27 +0,0 @@
#ifndef _IPXE_EFI_IMAGE_H
#define _IPXE_EFI_IMAGE_H
/** @file
*
* EFI images
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/image.h>
extern struct image_type efi_image_type[] __image_type ( PROBE_NORMAL );
/**
* Check if EFI image can be loaded directly
*
* @v image EFI image
* @ret can_load EFI image can be loaded directly
*/
static inline int efi_can_load ( struct image *image ) {
return ( image->type == efi_image_type );
}
#endif /* _IPXE_EFI_IMAGE_H */

View File

@ -1,24 +0,0 @@
#ifndef _IPXE_EFI_SHIM_H
#define _IPXE_EFI_SHIM_H
/** @file
*
* UEFI shim special handling
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/image.h>
#include <ipxe/efi/efi.h>
extern int efi_shim_require_loader;
extern int efi_shim_allow_pxe;
extern int efi_shim_allow_sbat;
extern struct image_tag efi_shim __image_tag;
extern int efi_shim_install ( struct image *shim, EFI_HANDLE handle,
wchar_t **cmdline );
extern void efi_shim_uninstall ( void );
#endif /* _IPXE_EFI_SHIM_H */

View File

@ -19,8 +19,6 @@ extern int efi_vssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt,
va_list args );
extern int efi_ssnprintf ( wchar_t *wbuf, ssize_t swsize,
const char *fmt, ... );
extern int efi_vasprintf ( wchar_t **strp, const char *fmt, va_list args );
extern int efi_asprintf ( wchar_t **strp, const char *fmt, ... );
/**
* Write a formatted string to a wide-character buffer

View File

@ -12,11 +12,40 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <ipxe/api.h>
#include <ipxe/hash_df.h>
#include <ipxe/sha256.h>
#include <ipxe/tables.h>
#include <config/entropy.h>
/**
* Calculate static inline entropy API function name
*
* @v _prefix Subsystem prefix
* @v _api_func API function
* @ret _subsys_func Subsystem API function
*/
#define ENTROPY_INLINE( _subsys, _api_func ) \
SINGLE_API_INLINE ( ENTROPY_PREFIX_ ## _subsys, _api_func )
/**
* Provide a entropy API implementation
*
* @v _prefix Subsystem prefix
* @v _api_func API function
* @v _func Implementing function
*/
#define PROVIDE_ENTROPY( _subsys, _api_func, _func ) \
PROVIDE_SINGLE_API ( ENTROPY_PREFIX_ ## _subsys, _api_func, _func )
/**
* Provide a static inline entropy API implementation
*
* @v _prefix Subsystem prefix
* @v _api_func API function
*/
#define PROVIDE_ENTROPY_INLINE( _subsys, _api_func ) \
PROVIDE_SINGLE_API_INLINE ( ENTROPY_PREFIX_ ## _subsys, _api_func )
/** A noise sample */
typedef uint8_t noise_sample_t;
@ -42,148 +71,56 @@ typedef unsigned int min_entropy_t;
#define MIN_ENTROPY( bits ) \
( ( min_entropy_t ) ( (bits) * MIN_ENTROPY_SCALE ) )
/**
* Repetition count test state
*
* This is the state for the repetition Count Test defined in ANS
* X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
*/
struct entropy_repetition_count_test {
/**
* A = the most recently seen sample value
*/
noise_sample_t most_recent_sample;
/**
* B = the number of times that value A has been seen in a row
*/
unsigned int repetition_count;
/**
* C = the cutoff value above which the repetition test should fail
*
* Filled in by entropy_init().
*/
unsigned int cutoff;
};
/* Include all architecture-independent entropy API headers */
#include <ipxe/null_entropy.h>
#include <ipxe/efi/efi_entropy.h>
#include <ipxe/linux/linux_entropy.h>
/* Include all architecture-dependent entropy API headers */
#include <bits/entropy.h>
/**
* Adaptive proportion test state
* Enable entropy gathering
*
* This is the state for the Adaptive Proportion Test for the Most
* Common Value defined in ANS X9.82 Part 2 (October 2011 Draft)
* Section 8.5.2.1.3.
* @ret rc Return status code
*/
struct entropy_adaptive_proportion_test {
/**
* A = the sample value currently being counted
*/
noise_sample_t current_counted_sample;
/**
* S = the number of samples examined in this run of the test so far
*/
unsigned int sample_count;
/**
* B = the current number of times that S (sic) has been seen
* in the W (sic) samples examined so far
*/
unsigned int repetition_count;
/**
* C = the cutoff value above which the repetition test should fail
*
* Filled in by entropy_init().
*/
unsigned int cutoff;
};
int entropy_enable ( void );
/**
* Startup test state
* Disable entropy gathering
*
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
* that at least one full cycle of the continuous tests must be
* performed at start-up.
*/
struct entropy_startup_test {
/** Number of startup tests performed */
unsigned int tested;
/**
* Number of startup tests required for one full cycle
*
* Filled in by entropy_init().
*/
unsigned int count;
};
void entropy_disable ( void );
/** An entropy source */
struct entropy_source {
/** Name */
const char *name;
/**
* min-entropy per sample
*
* min-entropy is defined in ANS X9.82 Part 1-2006 Section 8.3 and in
* NIST SP 800-90 Appendix C.3 as
*
* H_min = -log2 ( p_max )
*
* where p_max is the probability of the most likely sample value.
*
* Filled in by entropy_init().
*/
min_entropy_t min_entropy_per_sample;
/** Repetition count test state */
struct entropy_repetition_count_test repetition_count_test;
/** Adaptive proportion test state */
struct entropy_adaptive_proportion_test adaptive_proportion_test;
/** Startup test state */
struct entropy_startup_test startup_test;
/**
* Failure status (if any)
*
* Any failure of an entropy source is regarded as permanent.
*/
int rc;
/**
* Enable entropy gathering
*
* @ret rc Return status code
*/
int ( * enable ) ( void );
/**
* Disable entropy gathering
*
*/
void ( * disable ) ( void );
/**
* Get noise sample
*
* @ret noise Noise sample
* @ret rc Return status code
*
* This is the GetNoise function defined in ANS X9.82 Part 2
* (October 2011 Draft) Section 6.5.2.
*/
int ( * get_noise ) ( noise_sample_t *noise );
};
/** Entropy source table */
#define ENTROPY_SOURCES __table ( struct entropy_source, "entropy_sources" )
/** Declare an entropy source */
#define __entropy_source( order ) __table_entry ( ENTROPY_SOURCES, order )
/** @defgroup entropy_source_order Entropy source order
/**
* min-entropy per sample
*
* @{
* @ret min_entropy min-entropy of each sample
*
* min-entropy is defined in ANS X9.82 Part 1-2006 Section 8.3 and in
* NIST SP 800-90 Appendix C.3 as
*
* H_min = -log2 ( p_max )
*
* where p_max is the probability of the most likely sample value.
*
* This must be a compile-time constant.
*/
min_entropy_t min_entropy_per_sample ( void );
#define ENTROPY_PREFERRED 01 /**< Preferred entropy source */
#define ENTROPY_NORMAL 02 /**< Normal entropy source */
#define ENTROPY_FALLBACK 03 /**< Fallback entropy source */
/**
* Get noise sample
*
* @ret noise Noise sample
* @ret rc Return status code
*
* This is the GetNoise function defined in ANS X9.82 Part 2
* (October 2011 Draft) Section 6.5.2.
*/
int get_noise ( noise_sample_t *noise );
/** @} */
extern int get_entropy_input_tmp ( min_entropy_t min_entropy, uint8_t *tmp,
size_t tmp_len );
extern int get_entropy_input_tmp ( unsigned int num_samples,
uint8_t *tmp, size_t tmp_len );
/** Use SHA-256 as the underlying hash algorithm for Hash_df
*
@ -194,22 +131,6 @@ extern int get_entropy_input_tmp ( min_entropy_t min_entropy, uint8_t *tmp,
/** Underlying hash algorithm output length (in bytes) */
#define ENTROPY_HASH_DF_OUTLEN_BYTES SHA256_DIGEST_SIZE
/**
* Get noise sample
*
* @v source Entropy source
* @ret noise Noise sample
* @ret rc Return status code
*
* This is the GetNoise function defined in ANS X9.82 Part 2
* (October 2011 Draft) Section 6.5.2.
*/
static inline __attribute__ (( always_inline )) int
get_noise ( struct entropy_source *source, noise_sample_t *noise ) {
return source->get_noise ( noise );
}
/**
* Obtain entropy input
*
@ -224,8 +145,8 @@ get_noise ( struct entropy_source *source, noise_sample_t *noise ) {
* each entropy source output after each GetEntropy call) as defined
* in ANS X9.82 Part 4 (April 2011 Draft) Section 13.3.4.2.
*
* This function is inlined since the entropy amount and length inputs
* are always compile-time constants.
* To minimise code size, the number of samples required is calculated
* at compilation time.
*/
static inline __attribute__ (( always_inline )) int
get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
@ -233,16 +154,41 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
size_t tmp_len = ( ( ( min_entropy_bits * 2 ) + 7 ) / 8 );
uint8_t tmp_buf[ tmp_len ];
uint8_t *tmp = ( ( tmp_len > max_len ) ? tmp_buf : data );
double min_samples;
unsigned int num_samples;
unsigned int n;
int rc;
/* Sanity check */
/* Sanity checks */
linker_assert ( ( min_entropy_per_sample() <=
MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ),
min_entropy_per_sample_is_impossibly_high );
linker_assert ( ( min_entropy_bits <= ( 8 * max_len ) ),
entropy_buffer_too_small );
/* Round up minimum entropy to an integral number of bytes */
min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 );
/* Calculate number of samples required to contain sufficient entropy */
min_samples = ( MIN_ENTROPY ( min_entropy_bits ) /
min_entropy_per_sample() );
/* Round up to a whole number of samples. We don't have the
* ceil() function available, so do the rounding by hand.
*/
num_samples = min_samples;
if ( num_samples < min_samples )
num_samples++;
linker_assert ( ( num_samples >= min_samples ), rounding_error );
/* Floating-point operations are not allowed in iPXE since we
* never set up a suitable environment. Abort the build
* unless the calculated number of samples is a compile-time
* constant.
*/
linker_assert ( __builtin_constant_p ( num_samples ),
num_samples_not_constant );
/* (Unnumbered). The output length of the hash function shall
* meet or exceed the security strength indicated by the
* min_entropy parameter.
@ -272,10 +218,8 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
linker_assert ( __builtin_constant_p ( tmp_len ),
tmp_len_not_constant );
linker_assert ( ( n == ( 8 * tmp_len ) ), tmp_len_mismatch );
if ( ( rc = get_entropy_input_tmp ( MIN_ENTROPY ( min_entropy_bits ),
tmp, tmp_len ) ) != 0 ) {
if ( ( rc = get_entropy_input_tmp ( num_samples, tmp, tmp_len ) ) != 0 )
return rc;
}
/* 6. If ( n < min_length ), then tmp = tmp || 0^(min_length-n)
* 7. If ( n > max_length ), then tmp = df ( tmp, max_length )
@ -298,231 +242,4 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
}
}
/**
* Calculate cutoff value for the repetition count test
*
* @v min_entropy_per_sample Min-entropy per sample
* @ret cutoff Cutoff value
*
* This is the cutoff value for the Repetition Count Test defined in
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
*/
static inline __attribute__ (( always_inline )) unsigned int
entropy_repetition_count_cutoff ( min_entropy_t min_entropy_per_sample ) {
double max_repetitions;
unsigned int cutoff;
/* The cutoff formula for the repetition test is:
*
* C = ( 1 + ( -log2(W) / H_min ) )
*
* where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
* 2011 Draft) Section 8.5.2.1.3.1).
*/
max_repetitions = ( 1 + ( MIN_ENTROPY ( 30 ) /
min_entropy_per_sample ) );
/* Round up to a whole number of repetitions. We don't have
* the ceil() function available, so do the rounding by hand.
*/
cutoff = max_repetitions;
if ( cutoff < max_repetitions )
cutoff++;
linker_assert ( ( cutoff >= max_repetitions ), rounding_error );
/* Floating-point operations are not allowed in iPXE since we
* never set up a suitable environment. Abort the build
* unless the calculated number of repetitions is a
* compile-time constant.
*/
linker_assert ( __builtin_constant_p ( cutoff ),
repetition_count_cutoff_not_constant );
return cutoff;
}
/**
* Window size for the adaptive proportion test
*
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.1 allows
* five possible window sizes: 16, 64, 256, 4096 and 65536.
*
* We expect to generate relatively few (<256) entropy samples during
* a typical iPXE run; the use of a large window size would mean that
* the test would never complete a single cycle. We use a window size
* of 64, which is the smallest window size that permits values of
* H_min down to one bit per sample.
*/
#define ADAPTIVE_PROPORTION_WINDOW_SIZE 64
/**
* Combine adaptive proportion test window size and min-entropy
*
* @v n N (window size)
* @v h H (min-entropy)
* @ret n_h (N,H) combined value
*/
#define APC_N_H( n, h ) ( ( (n) << 8 ) | (h) )
/**
* Define a row of the adaptive proportion cutoff table
*
* @v h H (min-entropy)
* @v c16 Cutoff for N=16
* @v c64 Cutoff for N=64
* @v c256 Cutoff for N=256
* @v c4096 Cutoff for N=4096
* @v c65536 Cutoff for N=65536
*/
#define APC_TABLE_ROW( h, c16, c64, c256, c4096, c65536) \
case APC_N_H ( 16, h ) : return c16; \
case APC_N_H ( 64, h ) : return c64; \
case APC_N_H ( 256, h ) : return c256; \
case APC_N_H ( 4096, h ) : return c4096; \
case APC_N_H ( 65536, h ) : return c65536;
/** Value used to represent "N/A" in adaptive proportion cutoff table */
#define APC_NA 0
/**
* Look up value in adaptive proportion test cutoff table
*
* @v n N (window size)
* @v h H (min-entropy)
* @ret cutoff Cutoff
*
* This is the table of cutoff values defined in ANS X9.82 Part 2
* (October 2011 Draft) Section 8.5.2.1.3.1.2.
*/
static inline __attribute__ (( always_inline )) unsigned int
entropy_adaptive_proportion_cutoff_lookup ( unsigned int n, unsigned int h ) {
switch ( APC_N_H ( n, h ) ) {
APC_TABLE_ROW ( 1, APC_NA, 51, 168, 2240, 33537 );
APC_TABLE_ROW ( 2, APC_NA, 35, 100, 1193, 17053 );
APC_TABLE_ROW ( 3, 10, 24, 61, 643, 8705 );
APC_TABLE_ROW ( 4, 8, 16, 38, 354, 4473 );
APC_TABLE_ROW ( 5, 6, 12, 25, 200, 2321 );
APC_TABLE_ROW ( 6, 5, 9, 17, 117, 1220 );
APC_TABLE_ROW ( 7, 4, 7, 15, 71, 653 );
APC_TABLE_ROW ( 8, 4, 5, 9, 45, 358 );
APC_TABLE_ROW ( 9, 3, 4, 7, 30, 202 );
APC_TABLE_ROW ( 10, 3, 4, 5, 21, 118 );
APC_TABLE_ROW ( 11, 2, 3, 4, 15, 71 );
APC_TABLE_ROW ( 12, 2, 3, 4, 11, 45 );
APC_TABLE_ROW ( 13, 2, 2, 3, 9, 30 );
APC_TABLE_ROW ( 14, 2, 2, 3, 7, 21 );
APC_TABLE_ROW ( 15, 1, 2, 2, 6, 15 );
APC_TABLE_ROW ( 16, 1, 2, 2, 5, 11 );
APC_TABLE_ROW ( 17, 1, 1, 2, 4, 9 );
APC_TABLE_ROW ( 18, 1, 1, 2, 4, 7 );
APC_TABLE_ROW ( 19, 1, 1, 1, 3, 6 );
APC_TABLE_ROW ( 20, 1, 1, 1, 3, 5 );
default:
return APC_NA;
}
}
/**
* Calculate cutoff value for the adaptive proportion test
*
* @v min_entropy_per_sample Min-entropy per sample
* @ret cutoff Cutoff value
*
* This is the cutoff value for the Adaptive Proportion Test defined
* in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.2.
*/
static inline __attribute__ (( always_inline )) unsigned int
entropy_adaptive_proportion_cutoff ( min_entropy_t min_entropy_per_sample ) {
unsigned int h;
unsigned int n;
unsigned int cutoff;
/* Look up cutoff value in cutoff table */
n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
h = ( min_entropy_per_sample / MIN_ENTROPY_SCALE );
cutoff = entropy_adaptive_proportion_cutoff_lookup ( n, h );
/* Fail unless cutoff value is a compile-time constant */
linker_assert ( __builtin_constant_p ( cutoff ),
adaptive_proportion_cutoff_not_constant );
/* Fail if cutoff value is N/A */
linker_assert ( ( cutoff != APC_NA ),
adaptive_proportion_cutoff_not_applicable );
return cutoff;
}
/**
* Calculate number of samples required for startup tests
*
* @v repetition_count_cutoff Repetition count test cutoff value
* @v adaptive_proportion_cutoff Adaptive proportion test cutoff value
* @ret num_samples Number of samples required
*
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
* that at least one full cycle of the continuous tests must be
* performed at start-up.
*/
static inline __attribute__ (( always_inline )) unsigned int
entropy_startup_test_count ( unsigned int repetition_count_cutoff,
unsigned int adaptive_proportion_cutoff ) {
unsigned int num_samples;
/* At least max(N,C) samples shall be generated by the noise
* source for start-up testing.
*/
num_samples = repetition_count_cutoff;
if ( num_samples < adaptive_proportion_cutoff )
num_samples = adaptive_proportion_cutoff;
linker_assert ( __builtin_constant_p ( num_samples ),
startup_test_count_not_constant );
return num_samples;
}
/**
* Initialise entropy source
*
* @v source Entropy source
* @v min_entropy_per_sample Min-entropy per sample
*
* The cutoff value calculations for the repetition count test and the
* adaptive proportion test are provided as static inline functions
* since the results will always be compile-time constants.
*/
static inline __attribute__ (( always_inline )) void
entropy_init ( struct entropy_source *source,
min_entropy_t min_entropy_per_sample ) {
unsigned int repetition_count_cutoff;
unsigned int adaptive_proportion_cutoff;
unsigned int startup_test_count;
/* Sanity check */
linker_assert ( min_entropy_per_sample > MIN_ENTROPY ( 0 ),
min_entropy_per_sample_is_zero );
linker_assert ( ( min_entropy_per_sample <=
MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ),
min_entropy_per_sample_is_impossibly_high );
/* Calculate test cutoff values */
repetition_count_cutoff =
entropy_repetition_count_cutoff ( min_entropy_per_sample );
adaptive_proportion_cutoff =
entropy_adaptive_proportion_cutoff ( min_entropy_per_sample );
startup_test_count =
entropy_startup_test_count ( repetition_count_cutoff,
adaptive_proportion_cutoff );
/* Record min-entropy per sample and test cutoff values */
source->min_entropy_per_sample = min_entropy_per_sample;
source->repetition_count_test.cutoff = repetition_count_cutoff;
source->adaptive_proportion_test.cutoff = adaptive_proportion_cutoff;
source->startup_test.count = startup_test_count;
}
extern int entropy_enable ( struct entropy_source *source );
extern void entropy_disable ( struct entropy_source *source );
extern int get_noise ( struct entropy_source *source, noise_sample_t *noise );
#endif /* _IPXE_ENTROPY_H */

View File

@ -78,7 +78,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_dma ( ERRFILE_CORE | 0x00260000 )
#define ERRFILE_cachedhcp ( ERRFILE_CORE | 0x00270000 )
#define ERRFILE_acpimac ( ERRFILE_CORE | 0x00280000 )
#define ERRFILE_efi_strings ( ERRFILE_CORE | 0x00290000 )
#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 )
#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )
@ -296,7 +295,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_ntp ( ERRFILE_NET | 0x00490000 )
#define ERRFILE_httpntlm ( ERRFILE_NET | 0x004a0000 )
#define ERRFILE_eap ( ERRFILE_NET | 0x004b0000 )
#define ERRFILE_lldp ( ERRFILE_NET | 0x004c0000 )
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
@ -404,8 +402,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_pci_cmd ( ERRFILE_OTHER | 0x00590000 )
#define ERRFILE_dhe ( ERRFILE_OTHER | 0x005a0000 )
#define ERRFILE_efi_cmdline ( ERRFILE_OTHER | 0x005b0000 )
#define ERRFILE_efi_rng ( ERRFILE_OTHER | 0x005c0000 )
#define ERRFILE_efi_shim ( ERRFILE_OTHER | 0x005d0000 )
/** @} */

View File

@ -23,7 +23,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ETH_P_SLOW 0x8809 /* Ethernet slow protocols */
#define ETH_P_EAPOL 0x888E /* 802.1X EAP over LANs */
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
#define ETH_P_LLDP 0x88CC /* Link Layer Discovery Protocol */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */

View File

@ -61,16 +61,16 @@ struct image {
};
/** Image is registered */
#define IMAGE_REGISTERED 0x0001
#define IMAGE_REGISTERED 0x00001
/** Image is selected for execution */
#define IMAGE_SELECTED 0x0002
/** Image is trusted */
#define IMAGE_TRUSTED 0x0002
#define IMAGE_TRUSTED 0x0004
/** Image will be automatically unregistered after execution */
#define IMAGE_AUTO_UNREGISTER 0x0004
/** Image will be hidden from enumeration */
#define IMAGE_HIDDEN 0x0008
#define IMAGE_AUTO_UNREGISTER 0x0008
/** An executable image type */
struct image_type {
@ -150,23 +150,8 @@ struct image_type {
/** An executable image type */
#define __image_type( probe_order ) __table_entry ( IMAGE_TYPES, probe_order )
/** An image tag */
struct image_tag {
/** Name */
const char *name;
/** Image (weak reference, nullified when image is freed) */
struct image *image;
};
/** Image tag table */
#define IMAGE_TAGS __table ( struct image_tag, "image_tags" )
/** An image tag */
#define __image_tag __table_entry ( IMAGE_TAGS, 01 )
extern struct list_head images;
extern struct image_tag current_image;
extern struct image_tag selected_image;
extern struct image *current_image;
/** Iterate over all registered images */
#define for_each_image( image ) \
@ -176,6 +161,15 @@ extern struct image_tag selected_image;
#define for_each_image_safe( image, tmp ) \
list_for_each_entry_safe ( (image), (tmp), &images, list )
/**
* Test for existence of images
*
* @ret existence Some images exist
*/
static inline int have_images ( void ) {
return ( ! list_empty ( &images ) );
}
/**
* Retrieve first image
*
@ -193,15 +187,14 @@ extern int image_set_len ( struct image *image, size_t len );
extern int image_set_data ( struct image *image, userptr_t data, size_t len );
extern int register_image ( struct image *image );
extern void unregister_image ( struct image *image );
extern struct image * find_image ( const char *name );
extern struct image * find_image_tag ( struct image_tag *tag );
struct image * find_image ( const char *name );
extern int image_exec ( struct image *image );
extern int image_replace ( struct image *replacement );
extern int image_select ( struct image *image );
extern struct image * image_find_selected ( void );
extern int image_set_trust ( int require_trusted, int permanent );
extern struct image * image_memory ( const char *name, userptr_t data,
size_t len );
extern const char * image_argument ( struct image *image, const char *key );
extern int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf );
extern int image_asn1 ( struct image *image, size_t offset,
struct asn1_cursor **cursor );
@ -256,28 +249,4 @@ static inline void image_untrust ( struct image *image ) {
image->flags &= ~IMAGE_TRUSTED;
}
/**
* Mark image as hidden
*
* @v image Image
*/
static inline void image_hide ( struct image *image ) {
image->flags |= IMAGE_HIDDEN;
}
/**
* Tag image
*
* @v image Image
* @v tag Image tag
* @ret prev Previous tagged image (if any)
*/
static inline struct image * image_tag ( struct image *image,
struct image_tag *tag ) {
struct image *prev = tag->image;
tag->image = image;
return prev;
}
#endif /* _IPXE_IMAGE_H */

View File

@ -22,15 +22,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Default iSCSI port */
#define ISCSI_PORT 3260
/** Default iSCSI first burst length */
#define ISCSI_FIRST_BURST_LEN 65536
/** Default iSCSI maximum burst length */
#define ISCSI_MAX_BURST_LEN 262144
/** Default iSCSI maximum receive data segment length */
#define ISCSI_MAX_RECV_DATA_SEG_LEN 8192
/**
* iSCSI segment lengths
*
@ -586,9 +577,6 @@ struct iscsi_session {
/** CHAP response (used for both initiator and target auth) */
struct chap_response chap;
/** Maximum burst length */
size_t max_burst_len;
/** Initiator session ID (IANA format) qualifier
*
* This is part of the ISID. It is generated randomly

View File

@ -0,0 +1,34 @@
#ifndef _IPXE_LINUX_ENTROPY_H
#define _IPXE_LINUX_ENTROPY_H
/** @file
*
* /dev/random-based entropy source
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef ENTROPY_LINUX
#define ENTROPY_PREFIX_linux
#else
#define ENTROPY_PREFIX_linux __linux_
#endif
/**
* min-entropy per sample
*
* @ret min_entropy min-entropy of each sample
*/
static inline __always_inline min_entropy_t
ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
/* linux_get_noise() reads a single byte from /dev/random,
* which is supposed to block until a sufficient amount of
* entropy is available. We therefore assume that each sample
* contains exactly 8 bits of entropy.
*/
return MIN_ENTROPY ( 8.0 );
}
#endif /* _IPXE_LINUX_ENTROPY_H */

View File

@ -1,97 +0,0 @@
#ifndef _IPXE_LLDP_H
#define _IPXE_LLDP_H
/** @file
*
* Link Layer Discovery Protocol
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
/** An LLDP TLV header */
struct lldp_tlv {
/** Type and length */
uint16_t type_len;
/** Data */
uint8_t data[0];
} __attribute__ (( packed ));
/**
* Extract LLDP TLV type
*
* @v type_len Type and length
* @ret type Type
*/
#define LLDP_TLV_TYPE( type_len ) ( (type_len) >> 9 )
/**
* Extract LLDP TLV length
*
* @v type_len Type and length
* @ret len Length
*/
#define LLDP_TLV_LEN( type_len ) ( (type_len) & 0x01ff )
/** End of LLDP data unit */
#define LLDP_TYPE_END 0x00
/** LLDP settings block name */
#define LLDP_SETTINGS_NAME "lldp"
/**
* Construct LLDP setting tag
*
* LLDP settings are encoded as
*
* ${netX.lldp/<prefix>.<type>.<index>.<offset>.<length>}
*
* where
*
* <type> is the TLV type
*
* <offset> is the starting offset within the TLV value
*
* <length> is the length (or zero to read the from <offset> to the end)
*
* <prefix>, if it has a non-zero value, is the subtype byte string
* of length <offset> to match at the start of the TLV value, up to
* a maximum matched length of 4 bytes
*
* <index> is the index of the entry matching <type> and <prefix> to
* be accessed, with zero indicating the first matching entry
*
* The <prefix> is designed to accommodate both matching of the OUI
* within an organization-specific TLV (e.g. 0x0080c2 for IEEE 802.1
* TLVs) and of a subtype byte as found within many TLVs.
*
* This encoding allows most LLDP values to be extracted easily. For
* example
*
* System name: ${netX.lldp/5.0.0.0:string}
*
* System description: ${netX.lldp/6.0.0.0:string}
*
* Port description: ${netX.lldp/4.0.0.0:string}
*
* Port interface name: ${netX.lldp/5.2.0.1.0:string}
*
* Chassis MAC address: ${netX.lldp/4.1.0.1.0:hex}
*
* Management IPv4 address: ${netX.lldp/5.1.8.0.2.4:ipv4}
*
* Port VLAN ID: ${netX.lldp/0x0080c2.1.127.0.4.2:int16}
*
* Port VLAN name: ${netX.lldp/0x0080c2.3.127.0.7.0:string}
*
* Maximum frame size: ${netX.lldp/0x00120f.4.127.0.4.2:uint16}
*
*/
#define LLDP_TAG( prefix, type, index, offset, length ) \
( ( ( ( uint64_t ) (prefix) ) << 32 ) | \
( (type) << 24 ) | ( (index) << 16 ) | \
( (offset) << 8 ) | ( (length) << 0 ) )
#endif /* _IPXE_LLDP_H */

View File

@ -1,76 +0,0 @@
#ifndef _IPXE_NONXEN_H
#define _IPXE_NONXEN_H
/** @file
*
* Stub Xen definitions for platforms with no Xen support
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name
#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)
#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
typedef type * __XEN_GUEST_HANDLE(name)
#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
___DEFINE_XEN_GUEST_HANDLE(name, type); \
___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
typedef unsigned long xen_pfn_t;
typedef unsigned long xen_ulong_t;
struct arch_vcpu_info {};
struct arch_shared_info {};
#define XEN_LEGACY_MAX_VCPUS 0
struct xen_hypervisor;
static inline __attribute__ (( always_inline )) unsigned long
xen_hypercall_1 ( struct xen_hypervisor *xen __unused,
unsigned int hypercall __unused,
unsigned long arg1 __unused ) {
return 1;
}
static inline __attribute__ (( always_inline )) unsigned long
xen_hypercall_2 ( struct xen_hypervisor *xen __unused,
unsigned int hypercall __unused,
unsigned long arg1 __unused, unsigned long arg2 __unused ) {
return 1;
}
static inline __attribute__ (( always_inline )) unsigned long
xen_hypercall_3 ( struct xen_hypervisor *xen __unused,
unsigned int hypercall __unused,
unsigned long arg1 __unused, unsigned long arg2 __unused,
unsigned long arg3 __unused ) {
return 1;
}
static inline __attribute__ (( always_inline )) unsigned long
xen_hypercall_4 ( struct xen_hypervisor *xen __unused,
unsigned int hypercall __unused,
unsigned long arg1 __unused, unsigned long arg2 __unused,
unsigned long arg3 __unused, unsigned long arg4 __unused ) {
return 1;
}
static inline __attribute__ (( always_inline )) unsigned long
xen_hypercall_5 ( struct xen_hypervisor *xen __unused,
unsigned int hypercall __unused,
unsigned long arg1 __unused, unsigned long arg2 __unused,
unsigned long arg3 __unused, unsigned long arg4 __unused,
unsigned long arg5 __unused ) {
return 1;
}
#endif /* _IPXE_NONXEN_H */

View File

@ -0,0 +1,52 @@
#ifndef _IPXE_NULL_ENTROPY_H
#define _IPXE_NULL_ENTROPY_H
/** @file
*
* Nonexistent entropy source
*
* This source provides no entropy and must NOT be used in a
* security-sensitive environment.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#ifdef ENTROPY_NULL
#define ENTROPY_PREFIX_null
#else
#define ENTROPY_PREFIX_null __null_
#endif
static inline __always_inline int
ENTROPY_INLINE ( null, entropy_enable ) ( void ) {
/* Do nothing */
return 0;
}
static inline __always_inline void
ENTROPY_INLINE ( null, entropy_disable ) ( void ) {
/* Do nothing */
}
static inline __always_inline min_entropy_t
ENTROPY_INLINE ( null, min_entropy_per_sample ) ( void ) {
/* Actual amount of min-entropy is zero. To avoid
* division-by-zero errors and to allow compilation of
* entropy-consuming code, pretend to have 1 bit of entropy in
* each sample.
*/
return MIN_ENTROPY ( 1.0 );
}
static inline __always_inline int
ENTROPY_INLINE ( null, get_noise ) ( noise_sample_t *noise ) {
/* All sample values are constant */
*noise = 0x01;
return 0;
}
#endif /* _IPXE_NULL_ENTROPY_H */

View File

@ -3,7 +3,7 @@
/** @file
*
* Request parameters
* Form parameters
*
*/
@ -12,7 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
#include <ipxe/refcnt.h>
/** A request parameter list */
/** A form parameter list */
struct parameters {
/** Reference count */
struct refcnt refcnt;
@ -24,26 +24,18 @@ struct parameters {
struct list_head entries;
};
/** A request parameter */
/** A form parameter */
struct parameter {
/** List of request parameters */
/** List of form parameters */
struct list_head list;
/** Key */
const char *key;
/** Value */
const char *value;
/** Flags */
unsigned int flags;
};
/** Request parameter is a form parameter */
#define PARAMETER_FORM 0x0001
/** Request parameter is a header parameter */
#define PARAMETER_HEADER 0x0002
/**
* Increment request parameter list reference count
* Increment form parameter list reference count
*
* @v params Parameter list, or NULL
* @ret params Parameter list as passed in
@ -55,7 +47,7 @@ params_get ( struct parameters *params ) {
}
/**
* Decrement request parameter list reference count
* Decrement form parameter list reference count
*
* @v params Parameter list, or NULL
*/
@ -65,7 +57,7 @@ params_put ( struct parameters *params ) {
}
/**
* Claim ownership of request parameter list
* Claim ownership of form parameter list
*
* @v params Parameter list
* @ret params Parameter list
@ -79,14 +71,13 @@ claim_parameters ( struct parameters *params ) {
return params;
}
/** Iterate over all request parameters in a list */
/** Iterate over all form parameters in a list */
#define for_each_param( param, params ) \
list_for_each_entry ( (param), &(params)->entries, list )
extern struct parameters * find_parameters ( const char *name );
extern struct parameters * create_parameters ( const char *name );
extern struct parameter * add_parameter ( struct parameters *params,
const char *key, const char *value,
unsigned int flags );
const char *key, const char *value );
#endif /* _IPXE_PARAMS_H */

View File

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

View File

@ -383,9 +383,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
#define for_each_table_entry( pointer, table ) \
for ( (pointer) = table_start ( table ) ; \
(pointer) < table_end ( table ) ; \
(pointer)++ )
for ( pointer = table_start ( table ) ; \
pointer < table_end ( table ) ; \
pointer++ )
/**
* Iterate through all remaining entries within a linker table
@ -412,9 +412,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
#define for_each_table_entry_continue( pointer, table ) \
for ( (pointer)++ ; \
(pointer) < table_end ( table ) ; \
(pointer)++ )
for ( pointer++ ; \
pointer < table_end ( table ) ; \
pointer++ )
/**
* Iterate through all entries within a linker table in reverse order
@ -438,9 +438,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
#define for_each_table_entry_reverse( pointer, table ) \
for ( (pointer) = ( table_end ( table ) - 1 ) ; \
(pointer) >= table_start ( table ) ; \
(pointer)-- )
for ( pointer = ( table_end ( table ) - 1 ) ; \
pointer >= table_start ( table ) ; \
pointer-- )
/**
* Iterate through all remaining entries within a linker table in reverse order
@ -467,8 +467,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
#define for_each_table_entry_continue_reverse( pointer, table ) \
for ( (pointer)-- ; \
(pointer) >= table_start ( table ) ; \
(pointer)-- )
for ( pointer-- ; \
pointer >= table_start ( table ) ; \
pointer-- )
#endif /* _IPXE_TABLES_H */

View File

@ -52,9 +52,6 @@ struct tls_header {
/** Change cipher content type */
#define TLS_TYPE_CHANGE_CIPHER 20
/** Change cipher spec magic byte */
#define TLS_CHANGE_CIPHER_SPEC 1
/** Alert content type */
#define TLS_TYPE_ALERT 21
@ -398,8 +395,6 @@ struct tls_connection {
struct io_buffer rx_header_iobuf;
/** List of received data buffers */
struct list_head rx_data;
/** Received handshake fragment */
struct io_buffer *rx_handshake;
};
/** RX I/O buffer size

View File

@ -84,7 +84,7 @@ struct uri {
const char *equery;
/** Fragment (with original URI encoding) */
const char *efragment;
/** Request parameters */
/** Form parameters */
struct parameters *params;
} __attribute__ (( packed ));

Some files were not shown because too many files have changed in this diff Show More