mirror of
https://github.com/danderson/netboot.git
synced 2025-10-16 10:01:20 +02:00
Update the vendored iPXE to the latest code.
This commit is contained in:
parent
735c025438
commit
33769d2ec3
2
third_party/ipxe/COMMIT-ID
vendored
2
third_party/ipxe/COMMIT-ID
vendored
@ -1 +1 @@
|
||||
2afd66eb55996500499eb3bcc39c66ff042679c8
|
||||
30f96c9f41f2596493c6ca18060bebaaaf44415b
|
||||
|
6
third_party/ipxe/ipxe-bin.go
vendored
6
third_party/ipxe/ipxe-bin.go
vendored
File diff suppressed because one or more lines are too long
1
third_party/ipxe/src/Makefile
vendored
1
third_party/ipxe/src/Makefile
vendored
@ -53,6 +53,7 @@ EINFO := ./util/einfo
|
||||
GENKEYMAP := ./util/genkeymap.pl
|
||||
DOXYGEN := doxygen
|
||||
LCAB := lcab
|
||||
QEMUIMG := qemu-img
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
|
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_TIMER_H
|
||||
#define _BITS_TIMER_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* ARM-specific timer API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_TIMER_H */
|
@ -120,6 +120,11 @@ NON_AUTO_MEDIA += usb
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)cat $^ > $@
|
||||
|
||||
NON_AUTO_MEDIA += vhd
|
||||
%vhd: %usb
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)$(QEMUIMG) convert -f raw -O vpc $< $@
|
||||
|
||||
# Padded floppy image (e.g. for iLO)
|
||||
NON_AUTO_MEDIA += pdsk
|
||||
%pdsk : %dsk
|
||||
|
90
third_party/ipxe/src/arch/x86/core/cpuid.c
vendored
90
third_party/ipxe/src/arch/x86/core/cpuid.c
vendored
@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
|
||||
/** @file
|
||||
@ -32,15 +33,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour 0x861d
|
||||
|
||||
/**
|
||||
* Check whether or not CPUID instruction is supported
|
||||
*
|
||||
* @ret is_supported CPUID instruction is supported
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int cpuid_is_supported ( void ) {
|
||||
static int cpuid_instruction_supported ( void ) {
|
||||
unsigned long original;
|
||||
unsigned long inverted;
|
||||
|
||||
/* Check for instruction existence via flag modifiability */
|
||||
__asm__ ( "pushf\n\t"
|
||||
"pushf\n\t"
|
||||
"pop %0\n\t"
|
||||
@ -53,7 +58,54 @@ int cpuid_is_supported ( void ) {
|
||||
"popf\n\t"
|
||||
: "=&r" ( original ), "=&r" ( inverted )
|
||||
: "ir" ( CPUID_FLAG ) );
|
||||
return ( ( original ^ inverted ) & CPUID_FLAG );
|
||||
if ( ! ( ( original ^ inverted ) & CPUID_FLAG ) ) {
|
||||
DBGC ( colour, "CPUID instruction is not supported\n" );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not CPUID function is supported
|
||||
*
|
||||
* @v function CPUID function
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int cpuid_supported ( uint32_t function ) {
|
||||
uint32_t max_function;
|
||||
uint32_t discard_b;
|
||||
uint32_t discard_c;
|
||||
uint32_t discard_d;
|
||||
int rc;
|
||||
|
||||
/* Check that CPUID instruction is available */
|
||||
if ( ( rc = cpuid_instruction_supported() ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Find highest supported function number within this family */
|
||||
cpuid ( ( function & CPUID_EXTENDED ), &max_function, &discard_b,
|
||||
&discard_c, &discard_d );
|
||||
|
||||
/* Fail if maximum function number is meaningless (e.g. if we
|
||||
* are attempting to call an extended function on a CPU which
|
||||
* does not support them).
|
||||
*/
|
||||
if ( ( max_function & CPUID_AMD_CHECK_MASK ) !=
|
||||
( function & CPUID_AMD_CHECK_MASK ) ) {
|
||||
DBGC ( colour, "CPUID invalid maximum function %#08x\n",
|
||||
max_function );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Fail if this function is not supported */
|
||||
if ( function > max_function ) {
|
||||
DBGC ( colour, "CPUID function %#08x not supported\n",
|
||||
function );
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,18 +114,13 @@ int cpuid_is_supported ( void ) {
|
||||
* @v features x86 CPU features to fill in
|
||||
*/
|
||||
static void x86_intel_features ( struct x86_features *features ) {
|
||||
uint32_t max_level;
|
||||
uint32_t discard_a;
|
||||
uint32_t discard_b;
|
||||
uint32_t discard_c;
|
||||
uint32_t discard_d;
|
||||
int rc;
|
||||
|
||||
/* Check that features are available via CPUID */
|
||||
cpuid ( CPUID_VENDOR_ID, &max_level, &discard_b, &discard_c,
|
||||
&discard_d );
|
||||
if ( max_level < CPUID_FEATURES ) {
|
||||
DBGC ( features, "CPUID has no Intel-defined features (max "
|
||||
"level %08x)\n", max_level );
|
||||
if ( ( rc = cpuid_supported ( CPUID_FEATURES ) ) != 0 ) {
|
||||
DBGC ( features, "CPUID has no Intel-defined features\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -91,22 +138,13 @@ static void x86_intel_features ( struct x86_features *features ) {
|
||||
* @v features x86 CPU features to fill in
|
||||
*/
|
||||
static void x86_amd_features ( struct x86_features *features ) {
|
||||
uint32_t max_level;
|
||||
uint32_t discard_a;
|
||||
uint32_t discard_b;
|
||||
uint32_t discard_c;
|
||||
uint32_t discard_d;
|
||||
int rc;
|
||||
|
||||
/* Check that features are available via CPUID */
|
||||
cpuid ( CPUID_AMD_MAX_FN, &max_level, &discard_b, &discard_c,
|
||||
&discard_d );
|
||||
if ( ( max_level & CPUID_AMD_CHECK_MASK ) != CPUID_AMD_CHECK ) {
|
||||
DBGC ( features, "CPUID has no extended functions\n" );
|
||||
return;
|
||||
}
|
||||
if ( max_level < CPUID_AMD_FEATURES ) {
|
||||
DBGC ( features, "CPUID has no AMD-defined features (max "
|
||||
"level %08x)\n", max_level );
|
||||
if ( ( rc = cpuid_supported ( CPUID_AMD_FEATURES ) ) != 0 ) {
|
||||
DBGC ( features, "CPUID has no AMD-defined features\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -127,12 +165,6 @@ void x86_features ( struct x86_features *features ) {
|
||||
/* Clear all features */
|
||||
memset ( features, 0, sizeof ( *features ) );
|
||||
|
||||
/* Check that CPUID instruction is available */
|
||||
if ( ! cpuid_is_supported() ) {
|
||||
DBGC ( features, "CPUID instruction is not supported\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get Intel-defined features */
|
||||
x86_intel_features ( features );
|
||||
|
||||
|
@ -149,48 +149,25 @@ static int cpuid_settings_fetch ( struct settings *settings,
|
||||
struct setting *setting,
|
||||
void *data, size_t len ) {
|
||||
uint32_t function;
|
||||
uint32_t max_function;
|
||||
uint32_t num_functions;
|
||||
uint32_t registers;
|
||||
uint32_t num_registers;
|
||||
uint32_t buf[4];
|
||||
uint32_t output;
|
||||
uint32_t discard_b;
|
||||
uint32_t discard_c;
|
||||
uint32_t discard_d;
|
||||
size_t frag_len;
|
||||
size_t result_len = 0;
|
||||
|
||||
/* Fail unless CPUID is supported */
|
||||
if ( ! cpuid_is_supported() ) {
|
||||
DBGC ( settings, "CPUID not supported\n" );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Find highest supported function number within this set */
|
||||
function = CPUID_FUNCTION ( setting->tag );
|
||||
cpuid ( function & CPUID_EXTENDED, &max_function, &discard_b,
|
||||
&discard_c, &discard_d );
|
||||
|
||||
/* Fail if maximum function number is meaningless (e.g. if we
|
||||
* are attempting to call an extended function on a CPU which
|
||||
* does not support them).
|
||||
*/
|
||||
if ( ( max_function & CPUID_AMD_CHECK_MASK ) !=
|
||||
( function & CPUID_AMD_CHECK_MASK ) ) {
|
||||
DBGC ( settings, "CPUID invalid maximum function\n" );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
int rc;
|
||||
|
||||
/* Call each function in turn */
|
||||
function = CPUID_FUNCTION ( setting->tag );
|
||||
num_functions = CPUID_NUM_FUNCTIONS ( setting->tag );
|
||||
for ( ; num_functions-- ; function++ ) {
|
||||
|
||||
/* Fail if this function is not supported */
|
||||
if ( function > max_function ) {
|
||||
DBGC ( settings, "CPUID function %#08x not supported\n",
|
||||
function );
|
||||
return -ENOTSUP;
|
||||
if ( ( rc = cpuid_supported ( function ) ) != 0 ) {
|
||||
DBGC ( settings, "CPUID function %#08x not supported: "
|
||||
"%s\n", function, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Issue CPUID */
|
||||
|
@ -108,3 +108,42 @@ void * linux_mremap ( void *old_address, __kernel_size_t old_size,
|
||||
int linux_munmap ( void *addr, __kernel_size_t length ) {
|
||||
return linux_syscall ( __NR_munmap, addr, length );
|
||||
}
|
||||
|
||||
int linux_socket ( int domain, int type_, int protocol ) {
|
||||
#ifdef __NR_socket
|
||||
return linux_syscall ( __NR_socket, domain, type_, protocol );
|
||||
#else
|
||||
#ifndef SOCKOP_socket
|
||||
# define SOCKOP_socket 1
|
||||
#endif
|
||||
unsigned long sc_args[] = { domain, type_, protocol };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_socket, sc_args );
|
||||
#endif
|
||||
}
|
||||
|
||||
int linux_bind ( int fd, const struct sockaddr *addr, socklen_t addrlen ) {
|
||||
#ifdef __NR_bind
|
||||
return linux_syscall ( __NR_bind, fd, addr, addrlen );
|
||||
#else
|
||||
#ifndef SOCKOP_bind
|
||||
# define SOCKOP_bind 2
|
||||
#endif
|
||||
unsigned long sc_args[] = { fd, (unsigned long)addr, addrlen };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_bind, sc_args );
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t linux_sendto ( int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *daddr, socklen_t addrlen ) {
|
||||
#ifdef __NR_sendto
|
||||
return linux_syscall ( __NR_sendto, fd, buf, len, flags,
|
||||
daddr, addrlen );
|
||||
#else
|
||||
#ifndef SOCKOP_sendto
|
||||
# define SOCKOP_sendto 11
|
||||
#endif
|
||||
unsigned long sc_args[] = { fd, (unsigned long)buf, len,
|
||||
flags, (unsigned long)daddr, addrlen };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_sendto, sc_args );
|
||||
#endif
|
||||
}
|
||||
|
159
third_party/ipxe/src/arch/x86/core/rdtsc_timer.c
vendored
159
third_party/ipxe/src/arch/x86/core/rdtsc_timer.c
vendored
@ -29,16 +29,70 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/timer.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
#include <ipxe/pit8254.h>
|
||||
|
||||
/**
|
||||
* Number of TSC ticks per microsecond
|
||||
/** Number of microseconds to use for TSC calibration */
|
||||
#define TSC_CALIBRATE_US 1024
|
||||
|
||||
/** TSC increment per microsecond */
|
||||
static unsigned long tsc_per_us;
|
||||
|
||||
/** Minimum resolution for scaled TSC timer */
|
||||
#define TSC_SCALED_HZ 32
|
||||
|
||||
/** TSC scale (expressed as a bit shift)
|
||||
*
|
||||
* This is calibrated on the first use of the timer.
|
||||
* We use this to avoid the need for 64-bit divsion on 32-bit systems.
|
||||
*/
|
||||
static unsigned long rdtsc_ticks_per_usec;
|
||||
static unsigned int tsc_scale;
|
||||
|
||||
/** Number of timer ticks per scaled TSC increment */
|
||||
static unsigned long ticks_per_scaled_tsc;
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &tsc_per_us
|
||||
|
||||
/**
|
||||
* Get raw TSC value
|
||||
*
|
||||
* @ret tsc Raw TSC value
|
||||
*/
|
||||
static inline __always_inline unsigned long rdtsc_raw ( void ) {
|
||||
unsigned long raw;
|
||||
|
||||
__asm__ __volatile__ ( "rdtsc\n\t" : "=a" ( raw ) : : "edx" );
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TSC value, shifted to avoid rollover within a realistic timescale
|
||||
*
|
||||
* @ret tsc Scaled TSC value
|
||||
*/
|
||||
static inline __always_inline unsigned long rdtsc_scaled ( void ) {
|
||||
unsigned long scaled;
|
||||
|
||||
__asm__ __volatile__ ( "rdtsc\n\t"
|
||||
"shrdl %b1, %%edx, %%eax\n\t"
|
||||
: "=a" ( scaled ) : "c" ( tsc_scale ) : "edx" );
|
||||
return scaled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current system time in ticks
|
||||
*
|
||||
* @ret ticks Current time, in ticks
|
||||
*/
|
||||
static unsigned long rdtsc_currticks ( void ) {
|
||||
unsigned long scaled;
|
||||
|
||||
scaled = rdtsc_scaled();
|
||||
return ( scaled * ticks_per_scaled_tsc );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay for a fixed number of microseconds
|
||||
@ -48,47 +102,76 @@ static unsigned long rdtsc_ticks_per_usec;
|
||||
static void rdtsc_udelay ( unsigned long usecs ) {
|
||||
unsigned long start;
|
||||
unsigned long elapsed;
|
||||
unsigned long threshold;
|
||||
|
||||
/* Sanity guard, since we may divide by this */
|
||||
if ( ! usecs )
|
||||
usecs = 1;
|
||||
|
||||
start = currticks();
|
||||
if ( rdtsc_ticks_per_usec ) {
|
||||
/* Already calibrated; busy-wait until done */
|
||||
do {
|
||||
elapsed = ( currticks() - start );
|
||||
} while ( elapsed < ( usecs * rdtsc_ticks_per_usec ) );
|
||||
} else {
|
||||
/* Not yet calibrated; use 8254 PIT and calibrate
|
||||
* based on result.
|
||||
*/
|
||||
pit8254_udelay ( usecs );
|
||||
elapsed = ( currticks() - start );
|
||||
rdtsc_ticks_per_usec = ( elapsed / usecs );
|
||||
DBG ( "RDTSC timer calibrated: %ld ticks in %ld usecs "
|
||||
"(%ld MHz)\n", elapsed, usecs,
|
||||
( rdtsc_ticks_per_usec << TSC_SHIFT ) );
|
||||
}
|
||||
start = rdtsc_raw();
|
||||
threshold = ( usecs * tsc_per_us );
|
||||
do {
|
||||
elapsed = ( rdtsc_raw() - start );
|
||||
} while ( elapsed < threshold );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of ticks per second
|
||||
* Probe RDTSC timer
|
||||
*
|
||||
* @ret ticks_per_sec Number of ticks per second
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static unsigned long rdtsc_ticks_per_sec ( void ) {
|
||||
static int rdtsc_probe ( void ) {
|
||||
unsigned long before;
|
||||
unsigned long after;
|
||||
unsigned long elapsed;
|
||||
uint32_t apm;
|
||||
uint32_t discard_a;
|
||||
uint32_t discard_b;
|
||||
uint32_t discard_c;
|
||||
int rc;
|
||||
|
||||
/* Calibrate timer, if not already done */
|
||||
if ( ! rdtsc_ticks_per_usec )
|
||||
udelay ( 1 );
|
||||
/* Check that TSC is invariant */
|
||||
if ( ( rc = cpuid_supported ( CPUID_APM ) ) != 0 ) {
|
||||
DBGC ( colour, "RDTSC cannot determine APM features: %s\n",
|
||||
strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
cpuid ( CPUID_APM, &discard_a, &discard_b, &discard_c, &apm );
|
||||
if ( ! ( apm & CPUID_APM_EDX_TSC_INVARIANT ) ) {
|
||||
DBGC ( colour, "RDTSC has non-invariant TSC (%#08x)\n",
|
||||
apm );
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
assert ( rdtsc_ticks_per_usec != 0 );
|
||||
/* Calibrate udelay() timer via 8254 PIT */
|
||||
before = rdtsc_raw();
|
||||
pit8254_udelay ( TSC_CALIBRATE_US );
|
||||
after = rdtsc_raw();
|
||||
elapsed = ( after - before );
|
||||
tsc_per_us = ( elapsed / TSC_CALIBRATE_US );
|
||||
if ( ! tsc_per_us ) {
|
||||
DBGC ( colour, "RDTSC has zero TSC per microsecond\n" );
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return ( rdtsc_ticks_per_usec * 1000 * 1000 );
|
||||
/* Calibrate currticks() scaling factor */
|
||||
tsc_scale = 31;
|
||||
ticks_per_scaled_tsc = ( ( 1UL << tsc_scale ) /
|
||||
( tsc_per_us * ( 1000000 / TICKS_PER_SEC ) ) );
|
||||
while ( ticks_per_scaled_tsc > ( TICKS_PER_SEC / TSC_SCALED_HZ ) ) {
|
||||
tsc_scale--;
|
||||
ticks_per_scaled_tsc >>= 1;
|
||||
}
|
||||
DBGC ( colour, "RDTSC has %ld tsc per us, %ld ticks per 2^%d tsc\n",
|
||||
tsc_per_us, ticks_per_scaled_tsc, tsc_scale );
|
||||
if ( ! ticks_per_scaled_tsc ) {
|
||||
DBGC ( colour, "RDTSC has zero ticks per TSC\n" );
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PROVIDE_TIMER ( rdtsc, udelay, rdtsc_udelay );
|
||||
PROVIDE_TIMER_INLINE ( rdtsc, currticks );
|
||||
PROVIDE_TIMER ( rdtsc, ticks_per_sec, rdtsc_ticks_per_sec );
|
||||
/** RDTSC timer */
|
||||
struct timer rdtsc_timer __timer ( TIMER_PREFERRED ) = {
|
||||
.name = "rdtsc",
|
||||
.probe = rdtsc_probe,
|
||||
.currticks = rdtsc_currticks,
|
||||
.udelay = rdtsc_udelay,
|
||||
};
|
||||
|
@ -39,6 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <pic8259.h>
|
||||
#include <ipxe/malloc.h>
|
||||
#include <ipxe/device.h>
|
||||
#include <ipxe/timer.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
#include <ipxe/msr.h>
|
||||
#include <ipxe/hyperv.h>
|
||||
@ -51,6 +52,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*/
|
||||
#define HV_MESSAGE_MAX_WAIT_MS 1000
|
||||
|
||||
/** Hyper-V timer frequency (fixed 10Mhz) */
|
||||
#define HV_TIMER_HZ 10000000
|
||||
|
||||
/** Hyper-V timer scale factor (used to avoid 64-bit division) */
|
||||
#define HV_TIMER_SHIFT 18
|
||||
|
||||
/**
|
||||
* Convert a Hyper-V status code to an iPXE status code
|
||||
*
|
||||
@ -145,22 +152,19 @@ static void hv_free_message ( struct hv_hypervisor *hv ) {
|
||||
/**
|
||||
* Check whether or not we are running in Hyper-V
|
||||
*
|
||||
* @v hv Hyper-V hypervisor
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int hv_check_hv ( struct hv_hypervisor *hv ) {
|
||||
static int hv_check_hv ( void ) {
|
||||
struct x86_features features;
|
||||
uint32_t interface_id;
|
||||
uint32_t discard_ebx;
|
||||
uint32_t discard_ecx;
|
||||
uint32_t discard_edx;
|
||||
uint32_t available;
|
||||
uint32_t permissions;
|
||||
|
||||
/* Check for presence of a hypervisor (not necessarily Hyper-V) */
|
||||
x86_features ( &features );
|
||||
if ( ! ( features.intel.ecx & CPUID_FEATURES_INTEL_ECX_HYPERVISOR ) ) {
|
||||
DBGC ( hv, "HV %p not running in a hypervisor\n", hv );
|
||||
DBGC ( HV_INTERFACE_ID, "HV not running in a hypervisor\n" );
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -168,11 +172,26 @@ static int hv_check_hv ( struct hv_hypervisor *hv ) {
|
||||
cpuid ( HV_CPUID_INTERFACE_ID, &interface_id, &discard_ebx,
|
||||
&discard_ecx, &discard_edx );
|
||||
if ( interface_id != HV_INTERFACE_ID ) {
|
||||
DBGC ( hv, "HV %p not running in Hyper-V (interface ID "
|
||||
"%#08x)\n", hv, interface_id );
|
||||
DBGC ( HV_INTERFACE_ID, "HV not running in Hyper-V (interface "
|
||||
"ID %#08x)\n", interface_id );
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check required features
|
||||
*
|
||||
* @v hv Hyper-V hypervisor
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int hv_check_features ( struct hv_hypervisor *hv ) {
|
||||
uint32_t available;
|
||||
uint32_t permissions;
|
||||
uint32_t discard_ecx;
|
||||
uint32_t discard_edx;
|
||||
|
||||
/* Check that required features and privileges are available */
|
||||
cpuid ( HV_CPUID_FEATURES, &available, &permissions, &discard_ecx,
|
||||
&discard_edx );
|
||||
@ -509,6 +528,10 @@ static int hv_probe ( struct root_device *rootdev ) {
|
||||
struct hv_hypervisor *hv;
|
||||
int rc;
|
||||
|
||||
/* Check we are running in Hyper-V */
|
||||
if ( ( rc = hv_check_hv() ) != 0 )
|
||||
goto err_check_hv;
|
||||
|
||||
/* Allocate and initialise structure */
|
||||
hv = zalloc ( sizeof ( *hv ) );
|
||||
if ( ! hv ) {
|
||||
@ -516,9 +539,9 @@ static int hv_probe ( struct root_device *rootdev ) {
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
/* Check we are running in Hyper-V */
|
||||
if ( ( rc = hv_check_hv ( hv ) ) != 0 )
|
||||
goto err_check_hv;
|
||||
/* Check features */
|
||||
if ( ( rc = hv_check_features ( hv ) ) != 0 )
|
||||
goto err_check_features;
|
||||
|
||||
/* Allocate pages */
|
||||
if ( ( rc = hv_alloc_pages ( hv, &hv->hypercall, &hv->synic.message,
|
||||
@ -555,9 +578,10 @@ static int hv_probe ( struct root_device *rootdev ) {
|
||||
hv_free_pages ( hv, hv->hypercall, hv->synic.message, hv->synic.event,
|
||||
NULL );
|
||||
err_alloc_pages:
|
||||
err_check_hv:
|
||||
err_check_features:
|
||||
free ( hv );
|
||||
err_alloc:
|
||||
err_check_hv:
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -590,6 +614,73 @@ struct root_device hv_root_device __root_device = {
|
||||
.driver = &hv_root_driver,
|
||||
};
|
||||
|
||||
/**
|
||||
* Probe timer
|
||||
*
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int hv_timer_probe ( void ) {
|
||||
uint32_t available;
|
||||
uint32_t discard_ebx;
|
||||
uint32_t discard_ecx;
|
||||
uint32_t discard_edx;
|
||||
int rc;
|
||||
|
||||
/* Check we are running in Hyper-V */
|
||||
if ( ( rc = hv_check_hv() ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Check for available reference counter */
|
||||
cpuid ( HV_CPUID_FEATURES, &available, &discard_ebx, &discard_ecx,
|
||||
&discard_edx );
|
||||
if ( ! ( available & HV_FEATURES_AVAIL_TIME_REF_COUNT_MSR ) ) {
|
||||
DBGC ( HV_INTERFACE_ID, "HV has no time reference counter\n" );
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current system time in ticks
|
||||
*
|
||||
* @ret ticks Current time, in ticks
|
||||
*/
|
||||
static unsigned long hv_currticks ( void ) {
|
||||
|
||||
/* Calculate time using a combination of bit shifts and
|
||||
* multiplication (to avoid a 64-bit division).
|
||||
*/
|
||||
return ( ( rdmsr ( HV_X64_MSR_TIME_REF_COUNT ) >> HV_TIMER_SHIFT ) *
|
||||
( TICKS_PER_SEC / ( HV_TIMER_HZ >> HV_TIMER_SHIFT ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay for a fixed number of microseconds
|
||||
*
|
||||
* @v usecs Number of microseconds for which to delay
|
||||
*/
|
||||
static void hv_udelay ( unsigned long usecs ) {
|
||||
uint32_t start;
|
||||
uint32_t elapsed;
|
||||
uint32_t threshold;
|
||||
|
||||
/* Spin until specified number of 10MHz ticks have elapsed */
|
||||
start = rdmsr ( HV_X64_MSR_TIME_REF_COUNT );
|
||||
threshold = ( usecs * ( HV_TIMER_HZ / 1000000 ) );
|
||||
do {
|
||||
elapsed = ( rdmsr ( HV_X64_MSR_TIME_REF_COUNT ) - start );
|
||||
} while ( elapsed < threshold );
|
||||
}
|
||||
|
||||
/** Hyper-V timer */
|
||||
struct timer hv_timer __timer ( TIMER_PREFERRED ) = {
|
||||
.name = "Hyper-V",
|
||||
.probe = hv_timer_probe,
|
||||
.currticks = hv_currticks,
|
||||
.udelay = hv_udelay,
|
||||
};
|
||||
|
||||
/* Drag in objects via hv_root_device */
|
||||
REQUIRING_SYMBOL ( hv_root_device );
|
||||
|
||||
|
@ -21,6 +21,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
/** Get hypervisor features */
|
||||
#define HV_CPUID_FEATURES 0x40000003UL
|
||||
|
||||
/** Time reference counter MSR is available */
|
||||
#define HV_FEATURES_AVAIL_TIME_REF_COUNT_MSR 0x00000002UL
|
||||
|
||||
/** SynIC MSRs are available */
|
||||
#define HV_FEATURES_AVAIL_SYNIC_MSR 0x00000004UL
|
||||
|
||||
@ -39,6 +42,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
/** Hypercall page MSR */
|
||||
#define HV_X64_MSR_HYPERCALL 0x40000001UL
|
||||
|
||||
/** Time reference MSR */
|
||||
#define HV_X64_MSR_TIME_REF_COUNT 0x40000020UL
|
||||
|
||||
/** SynIC control MSR */
|
||||
#define HV_X64_MSR_SCONTROL 0x40000080UL
|
||||
|
||||
|
12
third_party/ipxe/src/arch/x86/drivers/net/undi.c
vendored
12
third_party/ipxe/src/arch/x86/drivers/net/undi.c
vendored
@ -94,23 +94,14 @@ static int undipci_probe ( struct pci_device *pci ) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Add to device hierarchy */
|
||||
snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
|
||||
"UNDI-%s", pci->dev.name );
|
||||
memcpy ( &undi->dev.desc, &pci->dev.desc, sizeof ( undi->dev.desc ) );
|
||||
undi->dev.parent = &pci->dev;
|
||||
INIT_LIST_HEAD ( &undi->dev.children );
|
||||
list_add ( &undi->dev.siblings, &pci->dev.children );
|
||||
|
||||
/* Create network device */
|
||||
if ( ( rc = undinet_probe ( undi ) ) != 0 )
|
||||
if ( ( rc = undinet_probe ( undi, &pci->dev ) ) != 0 )
|
||||
goto err_undinet_probe;
|
||||
|
||||
return 0;
|
||||
|
||||
err_undinet_probe:
|
||||
undi_unload ( undi );
|
||||
list_del ( &undi->dev.siblings );
|
||||
err_find_rom:
|
||||
err_load_pci:
|
||||
free ( undi );
|
||||
@ -128,7 +119,6 @@ static void undipci_remove ( struct pci_device *pci ) {
|
||||
|
||||
undinet_remove ( undi );
|
||||
undi_unload ( undi );
|
||||
list_del ( &undi->dev.siblings );
|
||||
free ( undi );
|
||||
pci_set_drvdata ( pci, NULL );
|
||||
}
|
||||
|
@ -72,7 +72,8 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
|
||||
/* Only one UNDI instance may be loaded at any given time */
|
||||
if ( undi_loader_entry.segment ) {
|
||||
DBG ( "UNDI %p cannot load multiple instances\n", undi );
|
||||
return -EBUSY;
|
||||
rc = -EBUSY;
|
||||
goto err_multiple;
|
||||
}
|
||||
|
||||
/* Set up START_UNDI parameters */
|
||||
@ -90,10 +91,15 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
|
||||
undi_loader.UNDI_CS = fbms_seg;
|
||||
fbms_seg -= ( ( undirom->data_size + 0x0f ) >> 4 );
|
||||
undi_loader.UNDI_DS = fbms_seg;
|
||||
undi->fbms = ( fbms_seg >> 6 );
|
||||
set_fbms ( undi->fbms );
|
||||
DBGC ( undi, "UNDI %p allocated [%d,%d) kB of base memory\n",
|
||||
undi, undi->fbms, undi->restore_fbms );
|
||||
|
||||
/* Debug info */
|
||||
DBGC ( undi, "UNDI %p loading UNDI ROM %p to CS %04x DS %04x for ",
|
||||
undi, undirom, undi_loader.UNDI_CS, undi_loader.UNDI_DS );
|
||||
DBGC ( undi, "UNDI %p loading ROM %p to CS %04x:%04zx DS %04x:%04zx "
|
||||
"for ", undi, undirom, undi_loader.UNDI_CS, undirom->code_size,
|
||||
undi_loader.UNDI_DS, undirom->data_size );
|
||||
if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
|
||||
unsigned int bus = ( undi->pci_busdevfn >> 8 );
|
||||
unsigned int devfn = ( undi->pci_busdevfn & 0xff );
|
||||
@ -116,15 +122,11 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
|
||||
: "=a" ( exit )
|
||||
: "a" ( __from_data16 ( &undi_loader ) )
|
||||
: "ebx", "ecx", "edx", "esi", "edi" );
|
||||
|
||||
if ( exit != PXENV_EXIT_SUCCESS ) {
|
||||
/* Clear entry point */
|
||||
memset ( &undi_loader_entry, 0, sizeof ( undi_loader_entry ) );
|
||||
|
||||
rc = -EUNDILOAD ( undi_loader.Status );
|
||||
DBGC ( undi, "UNDI %p loader failed: %s\n",
|
||||
undi, strerror ( rc ) );
|
||||
return rc;
|
||||
goto err_loader;
|
||||
}
|
||||
|
||||
/* Populate PXE device structure */
|
||||
@ -138,13 +140,13 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
|
||||
undi->pxenv.offset, undi->ppxe.segment, undi->ppxe.offset,
|
||||
undi->entry.segment, undi->entry.offset );
|
||||
|
||||
/* Update free base memory counter */
|
||||
undi->fbms = ( fbms_seg >> 6 );
|
||||
set_fbms ( undi->fbms );
|
||||
DBGC ( undi, "UNDI %p using [%d,%d) kB of base memory\n",
|
||||
undi, undi->fbms, undi->restore_fbms );
|
||||
|
||||
return 0;
|
||||
|
||||
err_loader:
|
||||
set_fbms ( undi->restore_fbms );
|
||||
memset ( &undi_loader_entry, 0, sizeof ( undi_loader_entry ) );
|
||||
err_multiple:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -598,19 +598,19 @@ static const struct undinet_irq_broken undinet_irq_broken_list[] = {
|
||||
/**
|
||||
* Check for devices with broken support for generating interrupts
|
||||
*
|
||||
* @v undi UNDI device
|
||||
* @v desc Device description
|
||||
* @ret irq_is_broken Interrupt support is broken; no interrupts are generated
|
||||
*/
|
||||
static int undinet_irq_is_broken ( struct undi_device *undi ) {
|
||||
static int undinet_irq_is_broken ( struct device_description *desc ) {
|
||||
const struct undinet_irq_broken *broken;
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
|
||||
sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
|
||||
broken = &undinet_irq_broken_list[i];
|
||||
if ( ( undi->dev.desc.bus_type == BUS_TYPE_PCI ) &&
|
||||
( undi->dev.desc.vendor == broken->pci_vendor ) &&
|
||||
( undi->dev.desc.device == broken->pci_device ) ) {
|
||||
if ( ( desc->bus_type == BUS_TYPE_PCI ) &&
|
||||
( desc->vendor == broken->pci_vendor ) &&
|
||||
( desc->device == broken->pci_device ) ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -621,9 +621,10 @@ static int undinet_irq_is_broken ( struct undi_device *undi ) {
|
||||
* Probe UNDI device
|
||||
*
|
||||
* @v undi UNDI device
|
||||
* @v dev Underlying generic device
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int undinet_probe ( struct undi_device *undi ) {
|
||||
int undinet_probe ( struct undi_device *undi, struct device *dev ) {
|
||||
struct net_device *netdev;
|
||||
struct undi_nic *undinic;
|
||||
struct s_PXENV_START_UNDI start_undi;
|
||||
@ -644,7 +645,7 @@ int undinet_probe ( struct undi_device *undi ) {
|
||||
netdev_init ( netdev, &undinet_operations );
|
||||
undinic = netdev->priv;
|
||||
undi_set_drvdata ( undi, netdev );
|
||||
netdev->dev = &undi->dev;
|
||||
netdev->dev = dev;
|
||||
memset ( undinic, 0, sizeof ( *undinic ) );
|
||||
undinet_entry = undi->entry;
|
||||
DBGC ( undinic, "UNDINIC %p using UNDI %p\n", undinic, undi );
|
||||
@ -733,7 +734,7 @@ int undinet_probe ( struct undi_device *undi ) {
|
||||
undinic );
|
||||
undinic->hacks |= UNDI_HACK_EB54;
|
||||
}
|
||||
if ( undinet_irq_is_broken ( undi ) ) {
|
||||
if ( undinet_irq_is_broken ( &dev->desc ) ) {
|
||||
DBGC ( undinic, "UNDINIC %p forcing polling mode due to "
|
||||
"broken interrupts\n", undinic );
|
||||
undinic->irq_supported = 0;
|
||||
|
@ -50,6 +50,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
* addition to the UNDI driver, build e.g. "bin/undi.dsk".
|
||||
*/
|
||||
|
||||
/** UNDI root bus device */
|
||||
static struct device undibus_dev;
|
||||
|
||||
/**
|
||||
* Probe UNDI root bus
|
||||
*
|
||||
@ -60,6 +63,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*/
|
||||
static int undibus_probe ( struct root_device *rootdev ) {
|
||||
struct undi_device *undi = &preloaded_undi;
|
||||
struct device *dev = &undibus_dev;
|
||||
int rc;
|
||||
|
||||
/* Check for a valie preloaded UNDI device */
|
||||
@ -69,34 +73,32 @@ static int undibus_probe ( struct root_device *rootdev ) {
|
||||
}
|
||||
|
||||
/* Add to device hierarchy */
|
||||
undi->dev.driver_name = "undionly";
|
||||
dev->driver_name = "undionly";
|
||||
if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
|
||||
undi->dev.desc.bus_type = BUS_TYPE_PCI;
|
||||
undi->dev.desc.location = undi->pci_busdevfn;
|
||||
undi->dev.desc.vendor = undi->pci_vendor;
|
||||
undi->dev.desc.device = undi->pci_device;
|
||||
snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
|
||||
"UNDI-PCI%02x:%02x.%x",
|
||||
PCI_BUS ( undi->pci_busdevfn ),
|
||||
dev->desc.bus_type = BUS_TYPE_PCI;
|
||||
dev->desc.location = undi->pci_busdevfn;
|
||||
dev->desc.vendor = undi->pci_vendor;
|
||||
dev->desc.device = undi->pci_device;
|
||||
snprintf ( dev->name, sizeof ( dev->name ),
|
||||
"0000:%02x:%02x.%x", PCI_BUS ( undi->pci_busdevfn ),
|
||||
PCI_SLOT ( undi->pci_busdevfn ),
|
||||
PCI_FUNC ( undi->pci_busdevfn ) );
|
||||
} else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
|
||||
undi->dev.desc.bus_type = BUS_TYPE_ISAPNP;
|
||||
snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
|
||||
"UNDI-ISAPNP" );
|
||||
dev->desc.bus_type = BUS_TYPE_ISAPNP;
|
||||
snprintf ( dev->name, sizeof ( dev->name ), "ISAPNP" );
|
||||
}
|
||||
undi->dev.parent = &rootdev->dev;
|
||||
list_add ( &undi->dev.siblings, &rootdev->dev.children);
|
||||
INIT_LIST_HEAD ( &undi->dev.children );
|
||||
dev->parent = &rootdev->dev;
|
||||
list_add ( &dev->siblings, &rootdev->dev.children);
|
||||
INIT_LIST_HEAD ( &dev->children );
|
||||
|
||||
/* Create network device */
|
||||
if ( ( rc = undinet_probe ( undi ) ) != 0 )
|
||||
if ( ( rc = undinet_probe ( undi, dev ) ) != 0 )
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
list_del ( &undi->dev.siblings );
|
||||
list_del ( &dev->siblings );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -107,9 +109,10 @@ static int undibus_probe ( struct root_device *rootdev ) {
|
||||
*/
|
||||
static void undibus_remove ( struct root_device *rootdev __unused ) {
|
||||
struct undi_device *undi = &preloaded_undi;
|
||||
struct device *dev = &undibus_dev;
|
||||
|
||||
undinet_remove ( undi );
|
||||
list_del ( &undi->dev.siblings );
|
||||
list_del ( &dev->siblings );
|
||||
}
|
||||
|
||||
/** UNDI bus root device driver */
|
||||
|
@ -168,7 +168,7 @@ static int undirom_probe ( unsigned int rom_segment ) {
|
||||
|
||||
/* Add to UNDI ROM list and return */
|
||||
DBGC ( undirom, "UNDIROM %p registered\n", undirom );
|
||||
list_add ( &undirom->list, &undiroms );
|
||||
list_add_tail ( &undirom->list, &undiroms );
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
@ -522,10 +522,12 @@ static void bzimage_load_initrds ( struct image *image,
|
||||
|
||||
/* Find highest usable address */
|
||||
top = userptr_add ( highest->data, bzimage_align ( highest->len ) );
|
||||
if ( user_to_phys ( top, 0 ) > bzimg->mem_limit )
|
||||
top = phys_to_user ( bzimg->mem_limit );
|
||||
if ( user_to_phys ( top, -1 ) > bzimg->mem_limit ) {
|
||||
top = phys_to_user ( ( bzimg->mem_limit + 1 ) &
|
||||
~( INITRD_ALIGN - 1 ) );
|
||||
}
|
||||
DBGC ( image, "bzImage %p loading initrds from %#08lx downwards\n",
|
||||
image, user_to_phys ( top, 0 ) );
|
||||
image, user_to_phys ( top, -1 ) );
|
||||
|
||||
/* Load initrds in order */
|
||||
for_each_image ( initrd ) {
|
||||
|
2
third_party/ipxe/src/arch/x86/include/bios.h
vendored
2
third_party/ipxe/src/arch/x86/include/bios.h
vendored
@ -7,6 +7,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define BDA_EBDA 0x000e
|
||||
#define BDA_EQUIPMENT_WORD 0x0010
|
||||
#define BDA_FBMS 0x0013
|
||||
#define BDA_TICKS 0x006c
|
||||
#define BDA_MIDNIGHT 0x0070
|
||||
#define BDA_REBOOT 0x0072
|
||||
#define BDA_REBOOT_WARM 0x1234
|
||||
#define BDA_NUM_DRIVES 0x0075
|
||||
|
@ -25,6 +25,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_gdbmach ( ERRFILE_ARCH | ERRFILE_CORE | 0x000e0000 )
|
||||
#define ERRFILE_rtc_entropy ( ERRFILE_ARCH | ERRFILE_CORE | 0x000f0000 )
|
||||
#define ERRFILE_acpipwr ( ERRFILE_ARCH | ERRFILE_CORE | 0x00100000 )
|
||||
#define ERRFILE_cpuid ( ERRFILE_ARCH | ERRFILE_CORE | 0x00110000 )
|
||||
#define ERRFILE_rdtsc_timer ( ERRFILE_ARCH | ERRFILE_CORE | 0x00120000 )
|
||||
|
||||
#define ERRFILE_bootsector ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 )
|
||||
#define ERRFILE_bzimage ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 )
|
||||
|
@ -1,15 +0,0 @@
|
||||
#ifndef _BITS_TIMER_H
|
||||
#define _BITS_TIMER_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* x86-specific timer API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/bios_timer.h>
|
||||
#include <ipxe/rdtsc_timer.h>
|
||||
|
||||
#endif /* _BITS_TIMER_H */
|
@ -1,44 +0,0 @@
|
||||
#ifndef _IPXE_BIOS_TIMER_H
|
||||
#define _IPXE_BIOS_TIMER_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* BIOS timer
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifdef TIMER_PCBIOS
|
||||
#define TIMER_PREFIX_pcbios
|
||||
#else
|
||||
#define TIMER_PREFIX_pcbios __pcbios_
|
||||
#endif
|
||||
|
||||
#include <ipxe/pit8254.h>
|
||||
|
||||
/**
|
||||
* Delay for a fixed number of microseconds
|
||||
*
|
||||
* @v usecs Number of microseconds for which to delay
|
||||
*/
|
||||
static inline __always_inline void
|
||||
TIMER_INLINE ( pcbios, udelay ) ( unsigned long usecs ) {
|
||||
/* BIOS timer is not high-resolution enough for udelay(), so
|
||||
* we use the 8254 Programmable Interval Timer.
|
||||
*/
|
||||
pit8254_udelay ( usecs );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of ticks per second
|
||||
*
|
||||
* @ret ticks_per_sec Number of ticks per second
|
||||
*/
|
||||
static inline __always_inline unsigned long
|
||||
TIMER_INLINE ( pcbios, ticks_per_sec ) ( void ) {
|
||||
/* BIOS timer ticks over at 18.2 ticks per second */
|
||||
return 18;
|
||||
}
|
||||
|
||||
#endif /* _IPXE_BIOS_TIMER_H */
|
@ -57,25 +57,31 @@ struct x86_features {
|
||||
/** Get CPU model */
|
||||
#define CPUID_MODEL 0x80000002UL
|
||||
|
||||
/** Get APM information */
|
||||
#define CPUID_APM 0x80000007UL
|
||||
|
||||
/** Invariant TSC */
|
||||
#define CPUID_APM_EDX_TSC_INVARIANT 0x00000100UL
|
||||
|
||||
/**
|
||||
* Issue CPUID instruction
|
||||
*
|
||||
* @v operation CPUID operation
|
||||
* @v function CPUID function
|
||||
* @v eax Output via %eax
|
||||
* @v ebx Output via %ebx
|
||||
* @v ecx Output via %ecx
|
||||
* @v edx Output via %edx
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
cpuid ( uint32_t operation, uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
cpuid ( uint32_t function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
uint32_t *edx ) {
|
||||
|
||||
__asm__ ( "cpuid"
|
||||
: "=a" ( *eax ), "=b" ( *ebx ), "=c" ( *ecx ), "=d" ( *edx )
|
||||
: "0" ( operation ) );
|
||||
: "0" ( function ) );
|
||||
}
|
||||
|
||||
extern int cpuid_is_supported ( void );
|
||||
extern int cpuid_supported ( uint32_t function );
|
||||
extern void x86_features ( struct x86_features *features );
|
||||
|
||||
#endif /* _IPXE_CPUID_H */
|
||||
|
@ -1,39 +0,0 @@
|
||||
#ifndef _IPXE_RDTSC_TIMER_H
|
||||
#define _IPXE_RDTSC_TIMER_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* RDTSC timer
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifdef TIMER_RDTSC
|
||||
#define TIMER_PREFIX_rdtsc
|
||||
#else
|
||||
#define TIMER_PREFIX_rdtsc __rdtsc_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RDTSC values can easily overflow an unsigned long. We discard the
|
||||
* low-order bits in order to obtain sensibly-scaled values.
|
||||
*/
|
||||
#define TSC_SHIFT 8
|
||||
|
||||
/**
|
||||
* Get current system time in ticks
|
||||
*
|
||||
* @ret ticks Current time, in ticks
|
||||
*/
|
||||
static inline __always_inline unsigned long
|
||||
TIMER_INLINE ( rdtsc, currticks ) ( void ) {
|
||||
unsigned long ticks;
|
||||
|
||||
__asm__ __volatile__ ( "rdtsc\n\t"
|
||||
"shrdl %1, %%edx, %%eax\n\t"
|
||||
: "=a" ( ticks ) : "i" ( TSC_SHIFT ) : "edx" );
|
||||
return ticks;
|
||||
}
|
||||
|
||||
#endif /* _IPXE_RDTSC_TIMER_H */
|
@ -37,8 +37,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/* Register command values */
|
||||
#define OCW3_ID 0x08
|
||||
#define OCW3_READ_IRR 0x03
|
||||
#define OCW3_READ_ISR 0x02
|
||||
#define OCW3_READ_IRR 0x02
|
||||
#define OCW3_READ_ISR 0x03
|
||||
#define ICR_EOI_NON_SPECIFIC 0x20
|
||||
#define ICR_EOI_NOP 0x40
|
||||
#define ICR_EOI_SPECIFIC 0x60
|
||||
|
2
third_party/ipxe/src/arch/x86/include/undi.h
vendored
2
third_party/ipxe/src/arch/x86/include/undi.h
vendored
@ -53,8 +53,6 @@ struct undi_device {
|
||||
*/
|
||||
UINT16_t flags;
|
||||
|
||||
/** Generic device */
|
||||
struct device dev;
|
||||
/** Driver-private data
|
||||
*
|
||||
* Use undi_set_drvdata() and undi_get_drvdata() to access this
|
||||
|
@ -10,8 +10,9 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
struct undi_device;
|
||||
struct device;
|
||||
|
||||
extern int undinet_probe ( struct undi_device *undi );
|
||||
extern int undinet_probe ( struct undi_device *undi, struct device *dev );
|
||||
extern void undinet_remove ( struct undi_device *undi );
|
||||
|
||||
#endif /* _UNDINET_H */
|
||||
|
@ -32,6 +32,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/timer.h>
|
||||
#include <realmode.h>
|
||||
#include <bios.h>
|
||||
#include <ipxe/pit8254.h>
|
||||
|
||||
/** Number of ticks per day
|
||||
*
|
||||
* This seems to be the normative value, as used by e.g. SeaBIOS to
|
||||
* decide when to set the midnight rollover flag.
|
||||
*/
|
||||
#define BIOS_TICKS_PER_DAY 0x1800b0
|
||||
|
||||
/** Number of ticks per BIOS tick */
|
||||
#define TICKS_PER_BIOS_TICK \
|
||||
( ( TICKS_PER_SEC * 60 * 60 * 24 ) / BIOS_TICKS_PER_DAY )
|
||||
|
||||
/**
|
||||
* Get current system time in ticks
|
||||
@ -43,7 +55,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
* of calling timeofday BIOS interrupt.
|
||||
*/
|
||||
static unsigned long bios_currticks ( void ) {
|
||||
static int days = 0;
|
||||
static uint32_t offset;
|
||||
uint32_t ticks;
|
||||
uint8_t midnight;
|
||||
|
||||
@ -53,18 +65,25 @@ static unsigned long bios_currticks ( void ) {
|
||||
"nop\n\t"
|
||||
"cli\n\t" );
|
||||
|
||||
get_real ( ticks, BDA_SEG, 0x006c );
|
||||
get_real ( midnight, BDA_SEG, 0x0070 );
|
||||
/* Read current BIOS time of day */
|
||||
get_real ( ticks, BDA_SEG, BDA_TICKS );
|
||||
get_real ( midnight, BDA_SEG, BDA_MIDNIGHT );
|
||||
|
||||
/* Handle midnight rollover */
|
||||
if ( midnight ) {
|
||||
midnight = 0;
|
||||
put_real ( midnight, BDA_SEG, 0x0070 );
|
||||
days += 0x1800b0;
|
||||
put_real ( midnight, BDA_SEG, BDA_MIDNIGHT );
|
||||
offset += BIOS_TICKS_PER_DAY;
|
||||
}
|
||||
ticks += offset;
|
||||
|
||||
return ( days + ticks );
|
||||
/* Convert to timer ticks */
|
||||
return ( ticks * TICKS_PER_BIOS_TICK );
|
||||
}
|
||||
|
||||
PROVIDE_TIMER_INLINE ( pcbios, udelay );
|
||||
PROVIDE_TIMER ( pcbios, currticks, bios_currticks );
|
||||
PROVIDE_TIMER_INLINE ( pcbios, ticks_per_sec );
|
||||
/** BIOS timer */
|
||||
struct timer bios_timer __timer ( TIMER_NORMAL ) = {
|
||||
.name = "bios",
|
||||
.currticks = bios_currticks,
|
||||
.udelay = pit8254_udelay,
|
||||
};
|
||||
|
@ -561,6 +561,8 @@ static int int13_guess_geometry_hdd ( struct int13_drive *int13, void *scratch,
|
||||
struct master_boot_record *mbr = scratch;
|
||||
struct partition_table_entry *partition;
|
||||
unsigned int i;
|
||||
unsigned int end_head;
|
||||
unsigned int end_sector;
|
||||
int rc;
|
||||
|
||||
/* Default guess is xx/255/63 */
|
||||
@ -586,10 +588,12 @@ static int int13_guess_geometry_hdd ( struct int13_drive *int13, void *scratch,
|
||||
*/
|
||||
for ( i = 0 ; i < 4 ; i++ ) {
|
||||
partition = &mbr->partitions[i];
|
||||
if ( ! partition->type )
|
||||
end_head = PART_HEAD ( partition->chs_end );
|
||||
end_sector = PART_SECTOR ( partition->chs_end );
|
||||
if ( ! ( partition->type && end_head && end_sector ) )
|
||||
continue;
|
||||
*heads = ( PART_HEAD ( partition->chs_end ) + 1 );
|
||||
*sectors = PART_SECTOR ( partition->chs_end );
|
||||
*heads = ( end_head + 1 );
|
||||
*sectors = end_sector;
|
||||
DBGC ( int13, "INT13 drive %02x guessing C/H/S xx/%d/%d based "
|
||||
"on partition %d\n",
|
||||
int13->drive, *heads, *sectors, ( i + 1 ) );
|
||||
@ -1747,7 +1751,7 @@ static void int13_unhook ( unsigned int drive ) {
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int int13_load_mbr ( unsigned int drive, struct segoff *address ) {
|
||||
uint8_t status;
|
||||
uint16_t status;
|
||||
int discard_b, discard_c, discard_d;
|
||||
uint16_t magic;
|
||||
|
||||
@ -1771,7 +1775,7 @@ static int int13_load_mbr ( unsigned int drive, struct segoff *address ) {
|
||||
: "a" ( 0x0201 ), "b" ( *address ),
|
||||
"c" ( 1 ), "d" ( drive ) );
|
||||
if ( status ) {
|
||||
DBG ( "INT13 drive %02x could not read MBR (status %02x)\n",
|
||||
DBG ( "INT13 drive %02x could not read MBR (status %04x)\n",
|
||||
drive, status );
|
||||
return -EIO;
|
||||
}
|
||||
@ -1814,7 +1818,7 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
|
||||
struct eltorito_validation_entry valid;
|
||||
struct eltorito_boot_entry boot;
|
||||
} __attribute__ (( packed )) catalog;
|
||||
uint8_t status;
|
||||
uint16_t status;
|
||||
|
||||
/* Use INT 13, 4d to read the boot catalog */
|
||||
__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
|
||||
@ -1829,7 +1833,7 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
|
||||
"S" ( __from_data16 ( &eltorito_cmd ) ) );
|
||||
if ( status ) {
|
||||
DBG ( "INT13 drive %02x could not read El Torito boot catalog "
|
||||
"(status %02x)\n", drive, status );
|
||||
"(status %04x)\n", drive, status );
|
||||
return -EIO;
|
||||
}
|
||||
copy_from_user ( &catalog, phys_to_user ( eltorito_cmd.buffer ), 0,
|
||||
@ -1876,7 +1880,7 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
|
||||
"S" ( __from_data16 ( &eltorito_address ) ) );
|
||||
if ( status ) {
|
||||
DBG ( "INT13 drive %02x could not read El Torito boot image "
|
||||
"(status %02x)\n", drive, status );
|
||||
"(status %04x)\n", drive, status );
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
53
third_party/ipxe/src/arch/x86/prefix/libprefix.S
vendored
53
third_party/ipxe/src/arch/x86/prefix/libprefix.S
vendored
@ -36,10 +36,24 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
/* Allow for DBG()-style messages within libprefix */
|
||||
#ifdef NDEBUG
|
||||
.macro progress message
|
||||
.macro progress message, regs:vararg
|
||||
.endm
|
||||
#else
|
||||
.macro progress message
|
||||
.macro dumpreg reg, others:vararg
|
||||
pushl %eax
|
||||
movl \reg, %eax
|
||||
pushw %di
|
||||
xorw %di, %di
|
||||
call print_space
|
||||
call print_hex_dword
|
||||
popw %di
|
||||
popl %eax
|
||||
.ifnb \others
|
||||
dumpreg \others
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro progress message, regs:vararg
|
||||
pushfl
|
||||
pushw %ds
|
||||
pushw %si
|
||||
@ -51,6 +65,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
call print_message
|
||||
popw %di
|
||||
popw %si
|
||||
.ifnb \regs
|
||||
dumpreg \regs
|
||||
.endif
|
||||
pushw %di
|
||||
pushw %ax
|
||||
xorw %di, %di
|
||||
movb $( '\n' ), %al
|
||||
call print_character
|
||||
popw %ax
|
||||
popw %di
|
||||
popw %ds
|
||||
popfl
|
||||
.section ".prefix.data", "aw", @progbits
|
||||
@ -659,7 +683,7 @@ hooked_bios_interrupts:
|
||||
.code16
|
||||
.globl install
|
||||
install:
|
||||
progress "install:\n"
|
||||
progress "\ninstall:"
|
||||
/* Preserve registers */
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
@ -702,7 +726,7 @@ install:
|
||||
.code16
|
||||
.globl install_prealloc
|
||||
install_prealloc:
|
||||
progress "install_prealloc:\n"
|
||||
progress "\ninstall_prealloc:", %eax, %ebx, %esi, %edi, %ebp
|
||||
/* Save registers on external stack */
|
||||
pushal
|
||||
pushw %ds
|
||||
@ -726,7 +750,6 @@ install_prealloc:
|
||||
pushl %edi
|
||||
|
||||
/* Install .text16.early and calculate %ecx as offset to next block */
|
||||
progress " .text16.early\n"
|
||||
pushl %esi
|
||||
xorl %esi, %esi
|
||||
movw %cs, %si
|
||||
@ -737,6 +760,7 @@ install_prealloc:
|
||||
shll $4, %edi
|
||||
movl $_text16_early_filesz, %ecx
|
||||
movl $_text16_early_memsz, %edx
|
||||
progress " .text16.early ", %esi, %edi, %ecx, %edx
|
||||
call install_block /* .text16.early */
|
||||
jc install_block_death
|
||||
popl %ecx /* Calculate offset to next block */
|
||||
@ -750,7 +774,7 @@ install_prealloc:
|
||||
* already have 4GB segment limits as a result of calling
|
||||
* install_block.)
|
||||
*/
|
||||
progress " access_highmem\n"
|
||||
progress " access_highmem"
|
||||
pushw %cs
|
||||
pushw $1f
|
||||
pushw %ax
|
||||
@ -762,7 +786,7 @@ install_prealloc:
|
||||
#endif
|
||||
|
||||
/* Open payload (which may not yet be in memory) */
|
||||
progress " open_payload\n"
|
||||
progress " open_payload ", %esi, %ecx
|
||||
pushw %cs
|
||||
pushw $1f
|
||||
pushw %ax
|
||||
@ -779,16 +803,16 @@ install_prealloc:
|
||||
1: addl %ecx, %esi
|
||||
|
||||
/* Install .text16.late and .data16 */
|
||||
progress " .text16.late\n"
|
||||
movl $_text16_late_filesz, %ecx
|
||||
movl $_text16_late_memsz, %edx
|
||||
progress " .text16.late ", %esi, %edi, %ecx, %edx
|
||||
call install_block /* .text16.late */
|
||||
jc install_block_death
|
||||
progress " .data16\n"
|
||||
movzwl %bx, %edi
|
||||
shll $4, %edi
|
||||
movl $_data16_filesz, %ecx
|
||||
movl $_data16_filesz, %edx /* do not zero our temporary stack */
|
||||
progress " .data16 ", %esi, %edi, %ecx, %edx
|
||||
call install_block /* .data16 */
|
||||
jc install_block_death
|
||||
|
||||
@ -825,10 +849,10 @@ install_prealloc:
|
||||
* prior to reading the E820 memory map and relocating
|
||||
* properly.
|
||||
*/
|
||||
progress " .textdata\n"
|
||||
pushl %edi
|
||||
movl $_textdata_filesz, %ecx
|
||||
movl $_textdata_memsz, %edx
|
||||
progress " .textdata ", %esi, %edi, %ecx, %edx
|
||||
call install_block
|
||||
jc install_block_death
|
||||
popl %edi
|
||||
@ -850,7 +874,7 @@ install_prealloc:
|
||||
#ifndef KEEP_IT_REAL
|
||||
|
||||
/* Initialise librm at current location */
|
||||
progress " init_librm\n"
|
||||
progress " init_librm ", %eax, %ebx, %edi
|
||||
movw %ax, (init_librm_vector+2)
|
||||
lcall *init_librm_vector
|
||||
|
||||
@ -873,7 +897,6 @@ install_prealloc:
|
||||
* relocate() will return with %esi, %edi and %ecx set up
|
||||
* ready for the copy to the new location.
|
||||
*/
|
||||
progress " relocate\n"
|
||||
virtcall relocate
|
||||
|
||||
/* Jump back to .prefix segment */
|
||||
@ -882,7 +905,7 @@ install_prealloc:
|
||||
.section ".prefix.install_prealloc", "awx", @progbits
|
||||
1:
|
||||
/* Copy code to new location */
|
||||
progress " copy\n"
|
||||
progress " copy ", %esi, %edi, %ecx
|
||||
pushl %edi
|
||||
pushw %bx
|
||||
movw $copy_bytes, %bx
|
||||
@ -891,7 +914,7 @@ install_prealloc:
|
||||
popl %edi
|
||||
|
||||
/* Initialise librm at new location */
|
||||
progress " init_librm\n"
|
||||
progress " init_librm ", %eax, %ebx, %edi
|
||||
lcall *init_librm_vector
|
||||
|
||||
#else /* KEEP_IT_REAL */
|
||||
@ -903,7 +926,7 @@ install_prealloc:
|
||||
#endif /* KEEP_IT_REAL */
|
||||
|
||||
/* Close access to payload */
|
||||
progress " close_payload\n"
|
||||
progress " close_payload"
|
||||
movw %ax, (close_payload_vector+2)
|
||||
lcall *close_payload_vector
|
||||
|
||||
|
@ -456,6 +456,24 @@ pci_set_mem_access:
|
||||
ret
|
||||
.size pci_set_mem_access, . - pci_set_mem_access
|
||||
|
||||
/* Update image source address for UNDI loader
|
||||
*
|
||||
* Parameters:
|
||||
* %esi : Image source address
|
||||
* Returns:
|
||||
* %esi : Image source address
|
||||
*/
|
||||
.section ".prefix", "ax", @progbits
|
||||
.globl undiloader_source
|
||||
undiloader_source:
|
||||
/* Always use expansion ROM BAR directly when installing via
|
||||
* the UNDI loader entry point, since the PMM-allocated block
|
||||
* may collide with whatever is calling the UNDI loader entry
|
||||
* point.
|
||||
*/
|
||||
xorl %esi, %esi
|
||||
ret
|
||||
|
||||
/* Payload prefix
|
||||
*
|
||||
* We include a dummy ROM header to cover the "hidden" portion of the
|
||||
|
@ -35,7 +35,8 @@ undiloader:
|
||||
movw %es:12(%di), %bx
|
||||
movw %es:14(%di), %ax
|
||||
movl image_source, %esi
|
||||
movl decompress_to, %edi
|
||||
call undiloader_source
|
||||
xorl %edi, %edi
|
||||
orl $0xffffffff, %ebp /* Allow arbitrary relocation */
|
||||
call install_prealloc
|
||||
popw %di
|
||||
@ -57,3 +58,16 @@ undiloader:
|
||||
popl %edi
|
||||
popl %esi
|
||||
lret
|
||||
|
||||
/* Update image source address for UNDI loader
|
||||
*
|
||||
* Parameters:
|
||||
* %esi : Image source address
|
||||
* Returns:
|
||||
* %esi : Image source address
|
||||
*/
|
||||
.section ".prefix", "ax", @progbits
|
||||
.globl undiloader_source
|
||||
.weak undiloader_source
|
||||
undiloader_source:
|
||||
ret
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
/* Drag in general configuration */
|
||||
#include <config/general.h>
|
||||
|
||||
/* Drag in local definitions */
|
||||
#include "librm.h"
|
||||
|
||||
@ -207,7 +210,9 @@ VC_TMP_CR3: .space 4
|
||||
VC_TMP_CR4: .space 4
|
||||
VC_TMP_EMER: .space 8
|
||||
.endif
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
VC_TMP_FXSAVE: .space 512
|
||||
#endif
|
||||
VC_TMP_END:
|
||||
.previous
|
||||
|
||||
@ -1000,11 +1005,12 @@ virt_call:
|
||||
|
||||
/* Claim ownership of temporary static buffer */
|
||||
cli
|
||||
|
||||
/* Preserve FPU, MMX and SSE state in temporary static buffer */
|
||||
movw %cs:rm_ds, %ds
|
||||
fxsave ( rm_tmpbuf + VC_TMP_FXSAVE )
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Preserve FPU, MMX and SSE state in temporary static buffer */
|
||||
fxsave ( rm_tmpbuf + VC_TMP_FXSAVE )
|
||||
#endif
|
||||
/* Preserve GDT and IDT in temporary static buffer */
|
||||
sidt ( rm_tmpbuf + VC_TMP_IDT )
|
||||
sgdt ( rm_tmpbuf + VC_TMP_GDT )
|
||||
@ -1070,9 +1076,11 @@ vc_rmode:
|
||||
movl $MSR_EFER, %ecx
|
||||
wrmsr
|
||||
.endif
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Restore FPU, MMX and SSE state from temporary static buffer */
|
||||
fxrstor ( rm_tmpbuf + VC_TMP_FXSAVE )
|
||||
|
||||
#endif
|
||||
/* Restore registers and flags and return */
|
||||
popl %eax /* skip %cs and %ss */
|
||||
popw %ds
|
||||
|
1
third_party/ipxe/src/config/cloud/aws.ipxe
vendored
1
third_party/ipxe/src/config/cloud/aws.ipxe
vendored
@ -1,6 +1,7 @@
|
||||
#!ipxe
|
||||
|
||||
echo Amazon EC2 - iPXE boot via user-data
|
||||
echo CPU: ${cpuvendor} ${cpumodel}
|
||||
ifstat ||
|
||||
dhcp ||
|
||||
route ||
|
||||
|
8
third_party/ipxe/src/config/cloud/gce.ipxe
vendored
Normal file
8
third_party/ipxe/src/config/cloud/gce.ipxe
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
#!ipxe
|
||||
|
||||
echo Google Compute Engine - iPXE boot via metadata
|
||||
echo CPU: ${cpuvendor} ${cpumodel}
|
||||
ifstat ||
|
||||
dhcp ||
|
||||
route ||
|
||||
chain -ar http://metadata.google.internal/computeMetadata/v1/instance/attributes/ipxeboot
|
4
third_party/ipxe/src/config/cloud/general.h
vendored
4
third_party/ipxe/src/config/cloud/general.h
vendored
@ -0,0 +1,4 @@
|
||||
/* Allow retrieval of metadata (such as an iPXE boot script) from
|
||||
* Google Compute Engine metadata server.
|
||||
*/
|
||||
#define HTTP_HACK_GCE
|
4
third_party/ipxe/src/config/cloud/settings.h
vendored
4
third_party/ipxe/src/config/cloud/settings.h
vendored
@ -0,0 +1,4 @@
|
||||
/* It can often be useful to know the CPU on which a cloud instance is
|
||||
* running (e.g. to isolate problems with Azure AMD instances).
|
||||
*/
|
||||
#define CPUID_SETTINGS
|
3
third_party/ipxe/src/config/config.c
vendored
3
third_party/ipxe/src/config/config.c
vendored
@ -275,6 +275,9 @@ REQUIRE_OBJECT ( profstat_cmd );
|
||||
#ifdef NTP_CMD
|
||||
REQUIRE_OBJECT ( ntp_cmd );
|
||||
#endif
|
||||
#ifdef CERT_CMD
|
||||
REQUIRE_OBJECT ( cert_cmd );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Drag in miscellaneous objects
|
||||
|
3
third_party/ipxe/src/config/config_http.c
vendored
3
third_party/ipxe/src/config/config_http.c
vendored
@ -43,3 +43,6 @@ REQUIRE_OBJECT ( httpdigest );
|
||||
#ifdef HTTP_ENC_PEERDIST
|
||||
REQUIRE_OBJECT ( peerdist );
|
||||
#endif
|
||||
#ifdef HTTP_HACK_GCE
|
||||
REQUIRE_OBJECT ( httpgce );
|
||||
#endif
|
||||
|
48
third_party/ipxe/src/config/config_timer.c
vendored
Normal file
48
third_party/ipxe/src/config/config_timer.c
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <config/timer.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Timer configuration options
|
||||
*
|
||||
*/
|
||||
|
||||
PROVIDE_REQUIRING_SYMBOL();
|
||||
|
||||
/*
|
||||
* Drag in timers
|
||||
*/
|
||||
#ifdef TIMER_PCBIOS
|
||||
REQUIRE_OBJECT ( bios_timer );
|
||||
#endif
|
||||
#ifdef TIMER_RDTSC
|
||||
REQUIRE_OBJECT ( rdtsc_timer );
|
||||
#endif
|
||||
#ifdef TIMER_EFI
|
||||
REQUIRE_OBJECT ( efi_timer );
|
||||
#endif
|
||||
#ifdef TIMER_LINUX
|
||||
REQUIRE_OBJECT ( linux_timer );
|
||||
#endif
|
7
third_party/ipxe/src/config/defaults/efi.h
vendored
7
third_party/ipxe/src/config/defaults/efi.h
vendored
@ -16,7 +16,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define TIMER_EFI
|
||||
#define UMALLOC_EFI
|
||||
#define SMBIOS_EFI
|
||||
#define SANBOOT_NULL
|
||||
#define SANBOOT_EFI
|
||||
#define BOFM_EFI
|
||||
#define ENTROPY_EFI
|
||||
#define TIME_EFI
|
||||
@ -27,6 +27,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define IMAGE_EFI /* EFI image support */
|
||||
#define IMAGE_SCRIPT /* iPXE script image support */
|
||||
|
||||
#define SANBOOT_PROTO_ISCSI /* iSCSI protocol */
|
||||
#define SANBOOT_PROTO_AOE /* AoE protocol */
|
||||
#define SANBOOT_PROTO_IB_SRP /* Infiniband SCSI RDMA protocol */
|
||||
#define SANBOOT_PROTO_FCP /* Fibre Channel protocol */
|
||||
|
||||
#define USB_HCD_XHCI /* xHCI USB host controller */
|
||||
#define USB_HCD_EHCI /* EHCI USB host controller */
|
||||
#define USB_HCD_UHCI /* UHCI USB host controller */
|
||||
|
5
third_party/ipxe/src/config/general.h
vendored
5
third_party/ipxe/src/config/general.h
vendored
@ -78,6 +78,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define HTTP_AUTH_BASIC /* Basic authentication */
|
||||
#define HTTP_AUTH_DIGEST /* Digest authentication */
|
||||
//#define HTTP_ENC_PEERDIST /* PeerDist content encoding */
|
||||
//#define HTTP_HACK_GCE /* Google Compute Engine hacks */
|
||||
|
||||
/*
|
||||
* 802.11 cryptosystems and handshaking protocols
|
||||
@ -150,6 +151,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
//#define IPSTAT_CMD /* IP statistics commands */
|
||||
//#define PROFSTAT_CMD /* Profiling commands */
|
||||
//#define NTP_CMD /* NTP commands */
|
||||
//#define CERT_CMD /* Certificate management commands */
|
||||
|
||||
/*
|
||||
* ROM-specific options
|
||||
@ -189,6 +191,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#undef GDBUDP /* Remote GDB debugging over UDP
|
||||
* (both may be set) */
|
||||
//#define EFI_DOWNGRADE_UX /* Downgrade UEFI user experience */
|
||||
#define TIVOLI_VMM_WORKAROUND /* Work around the Tivoli VMM's garbling of SSE
|
||||
* registers when iPXE traps to it due to
|
||||
* privileged instructions */
|
||||
|
||||
#include <config/named.h>
|
||||
#include NAMED_CONFIG(general.h)
|
||||
|
5
third_party/ipxe/src/config/qemu/general.h
vendored
5
third_party/ipxe/src/config/qemu/general.h
vendored
@ -8,3 +8,8 @@
|
||||
|
||||
/* Work around missing EFI_PXE_BASE_CODE_PROTOCOL */
|
||||
#define EFI_DOWNGRADE_UX
|
||||
|
||||
/* The Tivoli VMM workaround causes a KVM emulation failure on hosts
|
||||
* without unrestricted_guest support
|
||||
*/
|
||||
#undef TIVOLI_VMM_WORKAROUND
|
||||
|
93
third_party/ipxe/src/core/interface.c
vendored
93
third_party/ipxe/src/core/interface.c
vendored
@ -79,9 +79,6 @@ struct interface null_intf = INTF_INIT ( null_intf_desc );
|
||||
* The reference to the existing destination interface is dropped, a
|
||||
* reference to the new destination interface is obtained, and the
|
||||
* interface is updated to point to the new destination interface.
|
||||
*
|
||||
* Note that there is no "unplug" call; instead you must plug the
|
||||
* interface into a null interface.
|
||||
*/
|
||||
void intf_plug ( struct interface *intf, struct interface *dest ) {
|
||||
DBGC ( INTF_COL ( intf ),
|
||||
@ -113,7 +110,10 @@ void intf_plug_plug ( struct interface *a, struct interface *b ) {
|
||||
* @v intf Object interface
|
||||
*/
|
||||
void intf_unplug ( struct interface *intf ) {
|
||||
intf_plug ( intf, &null_intf );
|
||||
DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " unplug\n",
|
||||
INTF_INTF_DBG ( intf, intf->dest ) );
|
||||
intf_put ( intf->dest );
|
||||
intf->dest = &null_intf;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,6 +271,7 @@ void intf_close ( struct interface *intf, int rc ) {
|
||||
* unplugs the interface.
|
||||
*/
|
||||
void intf_shutdown ( struct interface *intf, int rc ) {
|
||||
struct interface tmp;
|
||||
|
||||
DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
|
||||
INTF_DBG ( intf ), strerror ( rc ) );
|
||||
@ -278,11 +279,50 @@ void intf_shutdown ( struct interface *intf, int rc ) {
|
||||
/* Block further operations */
|
||||
intf_nullify ( intf );
|
||||
|
||||
/* Notify destination of close */
|
||||
intf_close ( intf, rc );
|
||||
/* Transfer destination to temporary interface */
|
||||
tmp.dest = intf->dest;
|
||||
intf->dest = &null_intf;
|
||||
|
||||
/* Unplug interface */
|
||||
intf_unplug ( intf );
|
||||
/* Notify destination of close via temporary interface */
|
||||
intf_close ( &tmp, rc );
|
||||
|
||||
/* Unplug temporary interface */
|
||||
intf_unplug ( &tmp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down multiple object interfaces
|
||||
*
|
||||
* @v intfs Object interfaces
|
||||
* @v rc Reason for close
|
||||
*/
|
||||
void intfs_vshutdown ( va_list intfs, int rc ) {
|
||||
struct interface *intf;
|
||||
va_list tmp;
|
||||
|
||||
/* Nullify all interfaces to avoid potential loops */
|
||||
va_copy ( tmp, intfs );
|
||||
while ( ( intf = va_arg ( tmp, struct interface * ) ) )
|
||||
intf_nullify ( intf );
|
||||
va_end ( tmp );
|
||||
|
||||
/* Shut down all interfaces */
|
||||
while ( ( intf = va_arg ( intfs, struct interface * ) ) )
|
||||
intf_shutdown ( intf, rc );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down multiple object interfaces
|
||||
*
|
||||
* @v rc Reason for close
|
||||
* @v ... Object interfaces
|
||||
*/
|
||||
void intfs_shutdown ( int rc, ... ) {
|
||||
va_list intfs;
|
||||
|
||||
va_start ( intfs, rc );
|
||||
intfs_vshutdown ( intfs, rc );
|
||||
va_end ( intfs );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -295,7 +335,6 @@ void intf_shutdown ( struct interface *intf, int rc ) {
|
||||
* blocked during shutdown.
|
||||
*/
|
||||
void intf_restart ( struct interface *intf, int rc ) {
|
||||
struct interface_descriptor *desc = intf->desc;
|
||||
|
||||
/* Shut down the interface */
|
||||
intf_shutdown ( intf, rc );
|
||||
@ -309,7 +348,41 @@ void intf_restart ( struct interface *intf, int rc ) {
|
||||
* infinite loop as the intf_close() operations on each side
|
||||
* of the link call each other recursively.
|
||||
*/
|
||||
intf->desc = desc;
|
||||
intf_reinit ( intf );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down and restart multiple object interfaces
|
||||
*
|
||||
* @v intfs Object interfaces
|
||||
* @v rc Reason for close
|
||||
*/
|
||||
void intfs_vrestart ( va_list intfs, int rc ) {
|
||||
struct interface *intf;
|
||||
va_list tmp;
|
||||
|
||||
/* Shut down all interfaces */
|
||||
va_copy ( tmp, intfs );
|
||||
intfs_vshutdown ( tmp, rc );
|
||||
va_end ( tmp );
|
||||
|
||||
/* Reinitialise all interfaces */
|
||||
while ( ( intf = va_arg ( intfs, struct interface * ) ) )
|
||||
intf_reinit ( intf );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down and restart multiple object interfaces
|
||||
*
|
||||
* @v rc Reason for close
|
||||
* @v ... Object interfaces
|
||||
*/
|
||||
void intfs_restart ( int rc, ... ) {
|
||||
va_list intfs;
|
||||
|
||||
va_start ( intfs, rc );
|
||||
intfs_vrestart ( intfs, rc );
|
||||
va_end ( intfs );
|
||||
}
|
||||
|
||||
/**
|
||||
|
2
third_party/ipxe/src/core/parseopt.c
vendored
2
third_party/ipxe/src/core/parseopt.c
vendored
@ -117,7 +117,7 @@ int parse_timeout ( char *text, unsigned long *value ) {
|
||||
return rc;
|
||||
|
||||
/* Convert to a number of timer ticks */
|
||||
*value = ( ( value_ms * TICKS_PER_SEC ) / 1000 );
|
||||
*value = ( value_ms * TICKS_PER_MS );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
33
third_party/ipxe/src/core/settings.c
vendored
33
third_party/ipxe/src/core/settings.c
vendored
@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <byteswap.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <ipxe/in.h>
|
||||
#include <ipxe/ip.h>
|
||||
#include <ipxe/ipv6.h>
|
||||
@ -2552,6 +2553,38 @@ struct builtin_setting version_builtin_setting __builtin_setting = {
|
||||
.fetch = version_fetch,
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch current time setting
|
||||
*
|
||||
* @v data Buffer to fill with setting data
|
||||
* @v len Length of buffer
|
||||
* @ret len Length of setting data, or negative error
|
||||
*/
|
||||
static int unixtime_fetch ( void *data, size_t len ) {
|
||||
uint32_t content;
|
||||
|
||||
/* Return current time */
|
||||
content = htonl ( time(NULL) );
|
||||
if ( len > sizeof ( content ) )
|
||||
len = sizeof ( content );
|
||||
memcpy ( data, &content, len );
|
||||
return sizeof ( content );
|
||||
}
|
||||
|
||||
/** Current time setting */
|
||||
const struct setting unixtime_setting __setting ( SETTING_MISC, unixtime ) = {
|
||||
.name = "unixtime",
|
||||
.description = "Seconds since the Epoch",
|
||||
.type = &setting_type_uint32,
|
||||
.scope = &builtin_scope,
|
||||
};
|
||||
|
||||
/** Current time built-in setting */
|
||||
struct builtin_setting unixtime_builtin_setting __builtin_setting = {
|
||||
.setting = &unixtime_setting,
|
||||
.fetch = unixtime_fetch,
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch built-in setting
|
||||
*
|
||||
|
84
third_party/ipxe/src/core/timer.c
vendored
84
third_party/ipxe/src/core/timer.c
vendored
@ -23,11 +23,52 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ipxe/process.h>
|
||||
#include <ipxe/console.h>
|
||||
#include <ipxe/keys.h>
|
||||
#include <ipxe/nap.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/timer.h>
|
||||
|
||||
/** Current timer */
|
||||
static struct timer *timer;
|
||||
|
||||
/**
|
||||
* Get current system time in ticks
|
||||
*
|
||||
* @ret ticks Current time, in ticks
|
||||
*/
|
||||
unsigned long currticks ( void ) {
|
||||
|
||||
/* Guard against use during early initialisation */
|
||||
if ( ! timer ) {
|
||||
DBGC ( &timer, "TIMER currticks() called before initialisation "
|
||||
"from %p\n", __builtin_return_address ( 0 ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use selected timer */
|
||||
return timer->currticks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay for a fixed number of microseconds
|
||||
*
|
||||
* @v usecs Number of microseconds for which to delay
|
||||
*/
|
||||
void udelay ( unsigned long usecs ) {
|
||||
|
||||
/* Guard against use during early initialisation */
|
||||
if ( ! timer ) {
|
||||
DBGC ( &timer, "TIMER udelay() called before initialisation "
|
||||
"from %p\n", __builtin_return_address ( 0 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use selected timer */
|
||||
timer->udelay ( usecs );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay for a fixed number of milliseconds
|
||||
@ -35,6 +76,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
* @v msecs Number of milliseconds for which to delay
|
||||
*/
|
||||
void mdelay ( unsigned long msecs ) {
|
||||
|
||||
/* Guard against use during early initialisation */
|
||||
if ( ! timer ) {
|
||||
DBGC ( &timer, "TIMER mdelay() called before initialisation "
|
||||
"from %p\n", __builtin_return_address ( 0 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Delay for specified number of milliseconds */
|
||||
while ( msecs-- )
|
||||
udelay ( 1000 );
|
||||
}
|
||||
@ -61,3 +111,35 @@ unsigned int sleep ( unsigned int secs ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a working timer
|
||||
*
|
||||
*/
|
||||
static void timer_probe ( void ) {
|
||||
int rc;
|
||||
|
||||
/* Use first working timer */
|
||||
for_each_table_entry ( timer, TIMERS ) {
|
||||
if ( ( timer->probe == NULL ) ||
|
||||
( ( rc = timer->probe() ) == 0 ) ) {
|
||||
DBGC ( &timer, "TIMER using %s\n", timer->name );
|
||||
return;
|
||||
}
|
||||
DBGC ( &timer, "TIMER could not initialise %s: %s\n",
|
||||
timer->name, strerror ( rc ) );
|
||||
}
|
||||
|
||||
/* This is a fatal error */
|
||||
DBGC ( &timer, "TIMER found no working timers!\n" );
|
||||
while ( 1 ) {}
|
||||
}
|
||||
|
||||
/** Timer initialisation function */
|
||||
struct init_fn timer_init_fn __init_fn ( INIT_EARLY ) = {
|
||||
.initialise = timer_probe,
|
||||
};
|
||||
|
||||
/* Drag in timer configuration */
|
||||
REQUIRING_SYMBOL ( timer_init_fn );
|
||||
REQUIRE_OBJECT ( config_timer );
|
||||
|
2
third_party/ipxe/src/core/uuid.c
vendored
2
third_party/ipxe/src/core/uuid.c
vendored
@ -40,7 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
* @v uuid UUID
|
||||
* @ret string UUID in canonical form
|
||||
*/
|
||||
char * uuid_ntoa ( const union uuid *uuid ) {
|
||||
const char * uuid_ntoa ( const union uuid *uuid ) {
|
||||
static char buf[37]; /* "00000000-0000-0000-0000-000000000000" */
|
||||
|
||||
sprintf ( buf, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
|
||||
|
41
third_party/ipxe/src/crypto/certstore.c
vendored
41
third_party/ipxe/src/crypto/certstore.c
vendored
@ -145,6 +145,24 @@ void certstore_add ( struct x509_certificate *cert ) {
|
||||
x509_name ( cert ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove certificate from store
|
||||
*
|
||||
* @v cert X.509 certificate
|
||||
*/
|
||||
void certstore_del ( struct x509_certificate *cert ) {
|
||||
|
||||
/* Ignore attempts to remove permanent certificates */
|
||||
if ( cert->flags & X509_FL_PERMANENT )
|
||||
return;
|
||||
|
||||
/* Remove certificate from store */
|
||||
DBGC ( &certstore, "CERTSTORE removed certificate %s\n",
|
||||
x509_name ( cert ) );
|
||||
list_del ( &cert->store.list );
|
||||
x509_put ( cert );
|
||||
}
|
||||
|
||||
/**
|
||||
* Discard a stored certificate
|
||||
*
|
||||
@ -157,14 +175,22 @@ static unsigned int certstore_discard ( void ) {
|
||||
* only reference is held by the store itself.
|
||||
*/
|
||||
list_for_each_entry_reverse ( cert, &certstore.links, store.list ) {
|
||||
if ( cert->refcnt.count == 0 ) {
|
||||
DBGC ( &certstore, "CERTSTORE discarded certificate "
|
||||
"%s\n", x509_name ( cert ) );
|
||||
list_del ( &cert->store.list );
|
||||
x509_put ( cert );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Skip certificates for which another reference is held */
|
||||
if ( cert->refcnt.count > 0 )
|
||||
continue;
|
||||
|
||||
/* Skip certificates that were added at build time or
|
||||
* added explicitly at run time.
|
||||
*/
|
||||
if ( cert->flags & ( X509_FL_PERMANENT | X509_FL_EXPLICIT ) )
|
||||
continue;
|
||||
|
||||
/* Discard certificate */
|
||||
certstore_del ( cert );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -214,6 +240,7 @@ static void certstore_init ( void ) {
|
||||
* permanent reference to it.
|
||||
*/
|
||||
certstore_add ( cert );
|
||||
cert->flags |= X509_FL_PERMANENT;
|
||||
DBGC ( &certstore, "CERTSTORE permanent certificate %d is %s\n",
|
||||
i, x509_name ( cert ) );
|
||||
}
|
||||
|
2
third_party/ipxe/src/crypto/ocsp.c
vendored
2
third_party/ipxe/src/crypto/ocsp.c
vendored
@ -282,7 +282,7 @@ int ocsp_check ( struct x509_certificate *cert,
|
||||
/* Sanity checks */
|
||||
assert ( cert != NULL );
|
||||
assert ( issuer != NULL );
|
||||
assert ( issuer->valid );
|
||||
assert ( x509_is_valid ( issuer ) );
|
||||
|
||||
/* Allocate and initialise check */
|
||||
*ocsp = zalloc ( sizeof ( **ocsp ) );
|
||||
|
54
third_party/ipxe/src/crypto/x509.c
vendored
54
third_party/ipxe/src/crypto/x509.c
vendored
@ -39,6 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/certstore.h>
|
||||
#include <ipxe/socket.h>
|
||||
#include <ipxe/in.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/x509.h>
|
||||
#include <config/crypto.h>
|
||||
|
||||
@ -121,10 +122,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
__einfo_uniqify ( EINFO_EACCES, 0x0b, "No usable certificates" )
|
||||
|
||||
/**
|
||||
* Get X.509 certificate name (for debugging)
|
||||
* Get X.509 certificate display name
|
||||
*
|
||||
* @v cert X.509 certificate
|
||||
* @ret name Name (for debugging)
|
||||
* @ret name Display name
|
||||
*/
|
||||
const char * x509_name ( struct x509_certificate *cert ) {
|
||||
struct asn1_cursor *common_name = &cert->subject.common_name;
|
||||
@ -1319,7 +1320,7 @@ int x509_validate ( struct x509_certificate *cert,
|
||||
root = &root_certificates;
|
||||
|
||||
/* Return success if certificate has already been validated */
|
||||
if ( cert->valid )
|
||||
if ( x509_is_valid ( cert ) )
|
||||
return 0;
|
||||
|
||||
/* Fail if certificate is invalid at specified time */
|
||||
@ -1328,7 +1329,7 @@ int x509_validate ( struct x509_certificate *cert,
|
||||
|
||||
/* Succeed if certificate is a trusted root certificate */
|
||||
if ( x509_check_root ( cert, root ) == 0 ) {
|
||||
cert->valid = 1;
|
||||
cert->flags |= X509_FL_VALIDATED;
|
||||
cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
|
||||
return 0;
|
||||
}
|
||||
@ -1341,7 +1342,7 @@ int x509_validate ( struct x509_certificate *cert,
|
||||
}
|
||||
|
||||
/* Fail unless issuer has already been validated */
|
||||
if ( ! issuer->valid ) {
|
||||
if ( ! x509_is_valid ( issuer ) ) {
|
||||
DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
|
||||
DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
|
||||
issuer, x509_name ( issuer ) );
|
||||
@ -1375,7 +1376,7 @@ int x509_validate ( struct x509_certificate *cert,
|
||||
cert->path_remaining = max_path_remaining;
|
||||
|
||||
/* Mark certificate as valid */
|
||||
cert->valid = 1;
|
||||
cert->flags |= X509_FL_VALIDATED;
|
||||
|
||||
DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
|
||||
cert, x509_name ( cert ) );
|
||||
@ -1766,6 +1767,47 @@ int x509_validate_chain ( struct x509_chain *chain, time_t time,
|
||||
return -EACCES_USELESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract X.509 certificate object from image
|
||||
*
|
||||
* @v image Image
|
||||
* @v offset Offset within image
|
||||
* @ret cert X.509 certificate
|
||||
* @ret next Offset to next image, or negative error
|
||||
*
|
||||
* On success, the caller holds a reference to the X.509 certificate,
|
||||
* and is responsible for ultimately calling x509_put().
|
||||
*/
|
||||
int image_x509 ( struct image *image, size_t offset,
|
||||
struct x509_certificate **cert ) {
|
||||
struct asn1_cursor *cursor;
|
||||
int next;
|
||||
int rc;
|
||||
|
||||
/* Get ASN.1 object */
|
||||
next = image_asn1 ( image, offset, &cursor );
|
||||
if ( next < 0 ) {
|
||||
rc = next;
|
||||
goto err_asn1;
|
||||
}
|
||||
|
||||
/* Parse certificate */
|
||||
if ( ( rc = x509_certificate ( cursor->data, cursor->len,
|
||||
cert ) ) != 0 )
|
||||
goto err_certificate;
|
||||
|
||||
/* Free ASN.1 object */
|
||||
free ( cursor );
|
||||
|
||||
return next;
|
||||
|
||||
x509_put ( *cert );
|
||||
err_certificate:
|
||||
free ( cursor );
|
||||
err_asn1:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Drag in objects via x509_validate() */
|
||||
REQUIRING_SYMBOL ( x509_validate );
|
||||
|
||||
|
65
third_party/ipxe/src/drivers/bus/virtio-pci.c
vendored
65
third_party/ipxe/src/drivers/bus/virtio-pci.c
vendored
@ -21,11 +21,37 @@
|
||||
#include "ipxe/virtio-pci.h"
|
||||
#include "ipxe/virtio-ring.h"
|
||||
|
||||
static int vp_alloc_vq(struct vring_virtqueue *vq, u16 num)
|
||||
{
|
||||
size_t queue_size = PAGE_MASK + vring_size(num);
|
||||
size_t vdata_size = num * sizeof(void *);
|
||||
|
||||
vq->queue = zalloc(queue_size + vdata_size);
|
||||
if (!vq->queue) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* vdata immediately follows the ring */
|
||||
vq->vdata = (void **)(vq->queue + queue_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vp_free_vq(struct vring_virtqueue *vq)
|
||||
{
|
||||
if (vq->queue) {
|
||||
free(vq->queue);
|
||||
vq->queue = NULL;
|
||||
vq->vdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int vp_find_vq(unsigned int ioaddr, int queue_index,
|
||||
struct vring_virtqueue *vq)
|
||||
{
|
||||
struct vring * vr = &vq->vring;
|
||||
u16 num;
|
||||
int rc;
|
||||
|
||||
/* select the queue */
|
||||
|
||||
@ -39,11 +65,6 @@ int vp_find_vq(unsigned int ioaddr, int queue_index,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (num > MAX_QUEUE_NUM) {
|
||||
DBG("VIRTIO-PCI ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check if the queue is already active */
|
||||
|
||||
if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
|
||||
@ -54,8 +75,12 @@ int vp_find_vq(unsigned int ioaddr, int queue_index,
|
||||
vq->queue_index = queue_index;
|
||||
|
||||
/* initialize the queue */
|
||||
|
||||
vring_init(vr, num, (unsigned char*)&vq->queue);
|
||||
rc = vp_alloc_vq(vq, num);
|
||||
if (rc) {
|
||||
DBG("VIRTIO-PCI ERROR: failed to allocate queue memory\n");
|
||||
return rc;
|
||||
}
|
||||
vring_init(vr, num, vq->queue);
|
||||
|
||||
/* activate the queue
|
||||
*
|
||||
@ -354,18 +379,29 @@ int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
|
||||
return -ENOENT;
|
||||
|
||||
if (size & (size - 1)) {
|
||||
DBG("VIRTIO-PCI %p: bad queue size %d", vdev, size);
|
||||
DBG("VIRTIO-PCI %p: bad queue size %d\n", vdev, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (size > MAX_QUEUE_NUM) {
|
||||
/* iPXE networking tends to be not perf critical so there's no
|
||||
* need to accept large queue sizes.
|
||||
*/
|
||||
size = MAX_QUEUE_NUM;
|
||||
}
|
||||
|
||||
vq = &vqs[i];
|
||||
vq->queue_index = i;
|
||||
|
||||
/* get offset of notification word for this vq */
|
||||
off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));
|
||||
vq->vring.num = size;
|
||||
|
||||
vring_init(&vq->vring, size, (unsigned char *)vq->queue);
|
||||
err = vp_alloc_vq(vq, size);
|
||||
if (err) {
|
||||
DBG("VIRTIO-PCI %p: failed to allocate queue memory\n", vdev);
|
||||
return err;
|
||||
}
|
||||
vring_init(&vq->vring, size, vq->queue);
|
||||
|
||||
/* activate the queue */
|
||||
vpm_iowrite16(vdev, &vdev->common, size, COMMON_OFFSET(queue_size));
|
||||
@ -385,7 +421,7 @@ int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
|
||||
off * notify_offset_multiplier, 2,
|
||||
&vq->notification);
|
||||
if (err) {
|
||||
goto err_map_notify;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,11 +435,4 @@ int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
|
||||
vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_map_notify:
|
||||
/* Undo the virtio_pci_map_capability calls. */
|
||||
while (i-- > 0) {
|
||||
virtio_pci_unmap_capability(&vqs[i].notification);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/pci.h>
|
||||
#include <ipxe/malloc.h>
|
||||
#include <ipxe/umalloc.h>
|
||||
@ -31,10 +30,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#include <ipxe/vlan.h>
|
||||
#include <ipxe/io.h>
|
||||
#include "flexboot_nodnic.h"
|
||||
#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
|
||||
#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h"
|
||||
#include "mlx_utils/include/public/mlx_pci_gw.h"
|
||||
#include "mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h"
|
||||
#include "mlx_utils/include/public/mlx_types.h"
|
||||
#include "mlx_utils/include/public/mlx_utils.h"
|
||||
#include "mlx_utils/include/public/mlx_bail.h"
|
||||
@ -43,6 +38,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#include "mlx_utils/include/public/mlx_pci.h"
|
||||
#include "mlx_nodnic/include/mlx_device.h"
|
||||
#include "mlx_nodnic/include/mlx_port.h"
|
||||
#include <byteswap.h>
|
||||
#include <usr/ifmgmt.h>
|
||||
#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
|
||||
#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h"
|
||||
#include "mlx_utils/include/public/mlx_pci_gw.h"
|
||||
#include "mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h"
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
@ -52,10 +53,27 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
*/
|
||||
static int flexboot_nodnic_arm_cq ( struct flexboot_nodnic_port *port ) {
|
||||
#ifndef DEVICE_CX3
|
||||
mlx_uint32 val = ( port->eth_cq->next_idx & 0xffff );
|
||||
if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val ) ) {
|
||||
MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
|
||||
return MLX_FAILED;
|
||||
mlx_uint32 val32 = 0;
|
||||
union arm_cq_uar cq_uar;
|
||||
|
||||
#define ARM_CQ_UAR_CQ_CI_MASK 0xffffff
|
||||
#define ARM_CQ_UAR_CMDSN_MASK 3
|
||||
#define ARM_CQ_UAR_CMDSN_OFFSET 28
|
||||
#define ARM_CQ_UAR_CQ_CI_OFFSET 0x20
|
||||
if ( port->port_priv.device->device_cap.support_bar_cq_ctrl ) {
|
||||
cq_uar.dword[0] = cpu_to_be32((port->eth_cq->next_idx & ARM_CQ_UAR_CQ_CI_MASK) |
|
||||
((port->cmdsn++ & ARM_CQ_UAR_CMDSN_MASK) << ARM_CQ_UAR_CMDSN_OFFSET));
|
||||
cq_uar.dword[1] = cpu_to_be32(port->eth_cq->cqn);
|
||||
wmb();
|
||||
writeq(cq_uar.qword, port->port_priv.device->uar.virt + ARM_CQ_UAR_CQ_CI_OFFSET);
|
||||
port->port_priv.arm_cq_doorbell_record->dword[0] = cq_uar.dword[1];
|
||||
port->port_priv.arm_cq_doorbell_record->dword[1] = cq_uar.dword[0];
|
||||
} else {
|
||||
val32 = ( port->eth_cq->next_idx & 0xffffff );
|
||||
if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val32 ) ) {
|
||||
MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
|
||||
return MLX_FAILED;
|
||||
}
|
||||
}
|
||||
#else
|
||||
mlx_utils *utils = port->port_priv.device->utils;
|
||||
@ -77,7 +95,7 @@ static int flexboot_nodnic_arm_cq ( struct flexboot_nodnic_port *port ) {
|
||||
data = ( ( ( port->eth_cq->next_idx & 0xffff ) << 16 ) | 0x0080 );
|
||||
/* Write the new index and update FW that new data was submitted */
|
||||
mlx_pci_mem_write ( utils, MlxPciWidthUint32, 0,
|
||||
( mlx_uint64 ) & ( ptr->armcq_cq_ci_dword ), 1, &data );
|
||||
( mlx_uintn ) & ( ptr->armcq_cq_ci_dword ), 1, &data );
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
@ -96,6 +114,7 @@ static int flexboot_nodnic_create_cq ( struct ib_device *ibdev ,
|
||||
struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
|
||||
struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq;
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
mlx_uint32 cqn;
|
||||
|
||||
flexboot_nodnic_cq = (struct flexboot_nodnic_completion_queue *)
|
||||
zalloc(sizeof(*flexboot_nodnic_cq));
|
||||
@ -114,10 +133,18 @@ static int flexboot_nodnic_create_cq ( struct ib_device *ibdev ,
|
||||
flexboot_nodnic->callbacks->cqe_set_owner(
|
||||
flexboot_nodnic_cq->nodnic_completion_queue->cq_virt,
|
||||
cq->num_cqes);
|
||||
|
||||
if ( flexboot_nodnic->device_priv.device_cap.support_bar_cq_ctrl ) {
|
||||
status = nodnic_port_query(&port->port_priv,
|
||||
nodnic_port_option_cq_n_index,
|
||||
(mlx_uint32 *)&cqn );
|
||||
MLX_FATAL_CHECK_STATUS(status, read_cqn_err,
|
||||
"failed to query cqn");
|
||||
cq->cqn = cqn;
|
||||
}
|
||||
|
||||
ib_cq_set_drvdata ( cq, flexboot_nodnic_cq );
|
||||
return status;
|
||||
read_cqn_err:
|
||||
create_err:
|
||||
free(flexboot_nodnic_cq);
|
||||
qp_alloc_err:
|
||||
@ -450,6 +477,9 @@ static int flexboot_nodnic_post_send ( struct ib_device *ibdev,
|
||||
|
||||
status = port->port_priv.send_doorbell ( &port->port_priv,
|
||||
&send_ring->nodnic_ring, ( mlx_uint16 ) wq->next_idx );
|
||||
if ( flexboot_nodnic->callbacks->tx_uar_send_doorbell_fn ) {
|
||||
flexboot_nodnic->callbacks->tx_uar_send_doorbell_fn ( ibdev, wqbb );
|
||||
}
|
||||
if ( status != 0 ) {
|
||||
DBGC ( flexboot_nodnic, "flexboot_nodnic %p ring send doorbell failed\n", flexboot_nodnic );
|
||||
}
|
||||
@ -1293,12 +1323,14 @@ int flexboot_nodnic_is_supported ( struct pci_device *pci ) {
|
||||
mlx_pci_gw_teardown( &utils );
|
||||
|
||||
pci_gw_init_err:
|
||||
mlx_utils_teardown(&utils);
|
||||
utils_init_err:
|
||||
DBG ( "%s: NODNIC is %s supported (status = %d)\n",
|
||||
__FUNCTION__, ( is_supported ? "": "not" ), status );
|
||||
return is_supported;
|
||||
}
|
||||
|
||||
|
||||
void flexboot_nodnic_copy_mac ( uint8_t mac_addr[], uint32_t low_byte,
|
||||
uint16_t high_byte ) {
|
||||
union mac_addr {
|
||||
@ -1329,13 +1361,14 @@ static mlx_status flexboot_nodnic_get_factory_mac (
|
||||
status = mlx_vmac_query_virt_mac ( flexboot_nodnic_priv->device_priv.utils,
|
||||
&virt_mac );
|
||||
if ( ! status ) {
|
||||
DBGC ( flexboot_nodnic_priv, "NODNIC %p Failed to set the virtual MAC\n",
|
||||
flexboot_nodnic_priv );
|
||||
DBGC ( flexboot_nodnic_priv, "NODNIC %p Failed to set the virtual MAC\n"
|
||||
,flexboot_nodnic_priv );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set port masking
|
||||
*
|
||||
@ -1361,6 +1394,79 @@ static int flexboot_nodnic_set_port_masking ( struct flexboot_nodnic *flexboot_n
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_mlx_utils ( mlx_utils **utils, struct pci_device *pci ) {
|
||||
int rc = 0;
|
||||
|
||||
*utils = ( mlx_utils * ) zalloc ( sizeof ( mlx_utils ) );
|
||||
if ( *utils == NULL ) {
|
||||
DBGC ( utils, "%s: Failed to allocate utils\n", __FUNCTION__ );
|
||||
rc = -1;
|
||||
goto err_utils_alloc;
|
||||
}
|
||||
if ( mlx_utils_init ( *utils, pci ) ) {
|
||||
DBGC ( utils, "%s: mlx_utils_init failed\n", __FUNCTION__ );
|
||||
rc = -1;
|
||||
goto err_utils_init;
|
||||
}
|
||||
if ( mlx_pci_gw_init ( *utils ) ){
|
||||
DBGC ( utils, "%s: mlx_pci_gw_init failed\n", __FUNCTION__ );
|
||||
rc = -1;
|
||||
goto err_cmd_init;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
mlx_pci_gw_teardown ( *utils );
|
||||
err_cmd_init:
|
||||
mlx_utils_teardown ( *utils );
|
||||
err_utils_init:
|
||||
free ( *utils );
|
||||
err_utils_alloc:
|
||||
*utils = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void free_mlx_utils ( mlx_utils **utils ) {
|
||||
|
||||
mlx_pci_gw_teardown ( *utils );
|
||||
mlx_utils_teardown ( *utils );
|
||||
free ( *utils );
|
||||
*utils = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise Nodnic PCI parameters
|
||||
*
|
||||
* @v hermon Nodnic device
|
||||
*/
|
||||
static int flexboot_nodnic_alloc_uar ( struct flexboot_nodnic *flexboot_nodnic ) {
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
struct pci_device *pci = flexboot_nodnic->pci;
|
||||
nodnic_uar *uar = &flexboot_nodnic->port[0].port_priv.device->uar;
|
||||
|
||||
if ( ! flexboot_nodnic->device_priv.utils ) {
|
||||
uar->virt = NULL;
|
||||
DBGC ( flexboot_nodnic, "%s: mlx_utils is not initialized \n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( ! flexboot_nodnic->device_priv.device_cap.support_uar_tx_db ) {
|
||||
DBGC ( flexboot_nodnic, "%s: tx db using uar is not supported \n", __FUNCTION__ );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
/* read uar offset then allocate */
|
||||
if ( ( status = nodnic_port_set_send_uar_offset ( &flexboot_nodnic->port[0].port_priv ) ) ) {
|
||||
DBGC ( flexboot_nodnic, "%s: nodnic_port_set_send_uar_offset failed,"
|
||||
"status = %d\n", __FUNCTION__, status );
|
||||
return -EINVAL;
|
||||
}
|
||||
uar->phys = ( pci_bar_start ( pci, FLEXBOOT_NODNIC_HCA_BAR ) + (mlx_uint32)uar->offset );
|
||||
uar->virt = ( void * )( ioremap ( uar->phys, FLEXBOOT_NODNIC_PAGE_SIZE ) );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int flexboot_nodnic_probe ( struct pci_device *pci,
|
||||
struct flexboot_nodnic_callbacks *callbacks,
|
||||
void *drv_priv __unused ) {
|
||||
@ -1388,21 +1494,10 @@ int flexboot_nodnic_probe ( struct pci_device *pci,
|
||||
pci_set_drvdata ( pci, flexboot_nodnic_priv );
|
||||
|
||||
device_priv = &flexboot_nodnic_priv->device_priv;
|
||||
device_priv->utils = (mlx_utils *)zalloc( sizeof ( mlx_utils ) );
|
||||
if ( device_priv->utils == NULL ) {
|
||||
DBGC ( flexboot_nodnic_priv, "%s: Failed to allocate utils\n", __FUNCTION__ );
|
||||
status = MLX_OUT_OF_RESOURCES;
|
||||
goto utils_err_alloc;
|
||||
}
|
||||
|
||||
status = mlx_utils_init( device_priv->utils, pci );
|
||||
MLX_FATAL_CHECK_STATUS(status, utils_init_err,
|
||||
"mlx_utils_init failed");
|
||||
|
||||
/* nodnic init*/
|
||||
status = mlx_pci_gw_init( device_priv->utils );
|
||||
MLX_FATAL_CHECK_STATUS(status, cmd_init_err,
|
||||
"mlx_pci_gw_init failed");
|
||||
/* init mlx utils */
|
||||
status = init_mlx_utils ( & device_priv->utils, pci );
|
||||
MLX_FATAL_CHECK_STATUS(status, err_utils_init,
|
||||
"init_mlx_utils failed");
|
||||
|
||||
/* init device */
|
||||
status = nodnic_device_init( device_priv );
|
||||
@ -1426,6 +1521,11 @@ int flexboot_nodnic_probe ( struct pci_device *pci,
|
||||
MLX_FATAL_CHECK_STATUS(status, err_thin_init_ports,
|
||||
"flexboot_nodnic_thin_init_ports failed");
|
||||
|
||||
if ( ( status = flexboot_nodnic_alloc_uar ( flexboot_nodnic_priv ) ) ) {
|
||||
DBGC(flexboot_nodnic_priv, "%s: flexboot_nodnic_pci_init failed"
|
||||
" ( status = %d )\n",__FUNCTION__, status );
|
||||
}
|
||||
|
||||
/* device reg */
|
||||
status = flexboot_nodnic_set_ports_type( flexboot_nodnic_priv );
|
||||
MLX_CHECK_STATUS( flexboot_nodnic_priv, status, err_set_ports_types,
|
||||
@ -1456,11 +1556,8 @@ err_set_masking:
|
||||
get_cap_err:
|
||||
nodnic_device_teardown ( device_priv );
|
||||
device_init_err:
|
||||
mlx_pci_gw_teardown ( device_priv->utils );
|
||||
cmd_init_err:
|
||||
utils_init_err:
|
||||
free ( device_priv->utils );
|
||||
utils_err_alloc:
|
||||
free_mlx_utils ( & device_priv->utils );
|
||||
err_utils_init:
|
||||
free ( flexboot_nodnic_priv );
|
||||
device_err_alloc:
|
||||
return status;
|
||||
@ -1473,7 +1570,6 @@ void flexboot_nodnic_remove ( struct pci_device *pci )
|
||||
|
||||
flexboot_nodnic_ports_unregister_dev ( flexboot_nodnic_priv );
|
||||
nodnic_device_teardown( device_priv );
|
||||
mlx_pci_gw_teardown( device_priv->utils );
|
||||
free( device_priv->utils );
|
||||
free_mlx_utils ( & device_priv->utils );
|
||||
free( flexboot_nodnic_priv );
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#include <ipxe/io.h>
|
||||
#include <ipxe/infiniband.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
|
||||
|
||||
/*
|
||||
* If defined, use interrupts in NODNIC driver
|
||||
@ -37,6 +38,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#define FLEXBOOT_NODNIC_PORT_BASE 1
|
||||
|
||||
#define FLEXBOOT_NODNIC_OPCODE_SEND 0xa
|
||||
#define FLEXBOOT_NODNIC_HCA_BAR PCI_BASE_ADDRESS_0 //BAR 0
|
||||
#define FLEXBOOT_NODNIC_PAGE_SHIFT 12
|
||||
#define FLEXBOOT_NODNIC_PAGE_SIZE (1 << FLEXBOOT_NODNIC_PAGE_SHIFT)
|
||||
#define FLEXBOOT_NODNIC_PAGE_MASK (FLEXBOOT_NODNIC_PAGE_SIZE - 1)
|
||||
|
||||
/* Port protocol */
|
||||
enum flexboot_nodnic_protocol {
|
||||
@ -60,6 +65,7 @@ struct flexboot_nodnic_port {
|
||||
struct ib_completion_queue *eth_cq;
|
||||
/** Ethernet queue pair */
|
||||
struct ib_queue_pair *eth_qp;
|
||||
mlx_uint8 cmdsn;
|
||||
};
|
||||
|
||||
|
||||
@ -136,6 +142,21 @@ struct cqe_data{
|
||||
mlx_uint32 byte_cnt;
|
||||
};
|
||||
|
||||
union arm_cq_uar {
|
||||
struct {
|
||||
//big endian
|
||||
mlx_uint32 reserved0 :2;
|
||||
mlx_uint32 cmdn :2;
|
||||
mlx_uint32 reserved1 :3;
|
||||
mlx_uint32 cmd :1;
|
||||
mlx_uint32 cq_ci :24;
|
||||
mlx_uint32 reserved2 :8;
|
||||
mlx_uint32 cq_n :24;
|
||||
};
|
||||
mlx_uint32 dword[2];
|
||||
mlx_uint64 qword;
|
||||
};
|
||||
|
||||
struct flexboot_nodnic_callbacks {
|
||||
mlx_status ( * fill_completion ) ( void *cqe, struct cqe_data *cqe_data );
|
||||
mlx_status ( * cqe_set_owner ) ( void *cq, unsigned int num_cqes );
|
||||
@ -149,6 +170,10 @@ struct flexboot_nodnic_callbacks {
|
||||
unsigned long wqe_idx
|
||||
);
|
||||
void ( * irq ) ( struct net_device *netdev, int enable );
|
||||
mlx_status ( * tx_uar_send_doorbell_fn ) (
|
||||
struct ib_device *ibdev,
|
||||
struct nodnic_send_wqbb *wqbb
|
||||
);
|
||||
};
|
||||
|
||||
int flexboot_nodnic_probe ( struct pci_device *pci,
|
||||
@ -159,5 +184,6 @@ void flexboot_nodnic_eth_irq ( struct net_device *netdev, int enable );
|
||||
int flexboot_nodnic_is_supported ( struct pci_device *pci );
|
||||
void flexboot_nodnic_copy_mac ( uint8_t mac_addr[], uint32_t low_byte,
|
||||
uint16_t high_byte );
|
||||
|
||||
int init_mlx_utils ( mlx_utils **utils, struct pci_device *pci );
|
||||
void free_mlx_utils ( mlx_utils **utils );
|
||||
#endif /* SRC_DRIVERS_INFINIBAND_FLEXBOOT_NODNIC_FLEXBOOT_NODNIC_H_ */
|
||||
|
206
third_party/ipxe/src/drivers/infiniband/golan.c
vendored
206
third_party/ipxe/src/drivers/infiniband/golan.c
vendored
@ -21,31 +21,32 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/malloc.h>
|
||||
#include <ipxe/umalloc.h>
|
||||
#include <ipxe/infiniband.h>
|
||||
#include <ipxe/ib_smc.h>
|
||||
#include <ipxe/iobuf.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
#include "flexboot_nodnic.h"
|
||||
#include <ipxe/ethernet.h>
|
||||
#include <ipxe/if_ether.h>
|
||||
#include <usr/ifmgmt.h>
|
||||
#include <ipxe/in.h>
|
||||
#include <byteswap.h>
|
||||
#include "mlx_utils/include/public/mlx_pci_gw.h"
|
||||
#include <config/general.h>
|
||||
#include <ipxe/ipoib.h>
|
||||
#include "flexboot_nodnic.h"
|
||||
#include "mlx_nodnic/include/mlx_port.h"
|
||||
#include "nodnic_shomron_prm.h"
|
||||
#include "golan.h"
|
||||
#include "mlx_utils/include/public/mlx_bail.h"
|
||||
#include "mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h"
|
||||
#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
|
||||
#include "mlx_utils/include/public/mlx_pci_gw.h"
|
||||
#include "mlx_nodnic/include/mlx_port.h"
|
||||
|
||||
#define DEVICE_IS_CIB( device ) ( device == 0x1011 )
|
||||
/******************************************************************************/
|
||||
/************* Very simple memory management for umalloced pages **************/
|
||||
/******* Temporary solution until full memory management is implemented *******/
|
||||
/******************************************************************************/
|
||||
#define GOLAN_PAGES 20
|
||||
struct golan_page {
|
||||
struct list_head list;
|
||||
userptr_t addr;
|
||||
@ -61,8 +62,7 @@ static void golan_free_pages ( struct list_head *head ) {
|
||||
}
|
||||
|
||||
static int golan_init_pages ( struct list_head *head ) {
|
||||
struct golan_page *new_entry;
|
||||
int rc, i;
|
||||
int rc = 0;
|
||||
|
||||
if ( !head ) {
|
||||
rc = -EINVAL;
|
||||
@ -70,26 +70,8 @@ static int golan_init_pages ( struct list_head *head ) {
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD ( head );
|
||||
return rc;
|
||||
|
||||
for ( i = 0; i < GOLAN_PAGES; i++ ) {
|
||||
new_entry = zalloc ( sizeof ( *new_entry ) );
|
||||
if ( new_entry == NULL ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_golan_init_pages_alloc_page;
|
||||
}
|
||||
new_entry->addr = umalloc ( GOLAN_PAGE_SIZE );
|
||||
if ( new_entry->addr == UNULL ) {
|
||||
free ( new_entry );
|
||||
rc = -ENOMEM;
|
||||
goto err_golan_init_pages_alloc_page;
|
||||
}
|
||||
list_add ( &new_entry->list, head );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_golan_init_pages_alloc_page:
|
||||
golan_free_pages ( head );
|
||||
err_golan_init_pages_bad_param:
|
||||
return rc;
|
||||
}
|
||||
@ -98,16 +80,42 @@ static userptr_t golan_get_page ( struct list_head *head ) {
|
||||
struct golan_page *page;
|
||||
userptr_t addr;
|
||||
|
||||
if ( list_empty ( head ) )
|
||||
return UNULL;
|
||||
|
||||
page = list_first_entry ( head, struct golan_page, list );
|
||||
list_del ( &page->list );
|
||||
addr = page->addr;
|
||||
free ( page );
|
||||
if ( list_empty ( head ) ) {
|
||||
addr = umalloc ( GOLAN_PAGE_SIZE );
|
||||
if ( addr == UNULL ) {
|
||||
goto err_golan_iget_page_alloc_page;
|
||||
}
|
||||
} else {
|
||||
page = list_first_entry ( head, struct golan_page, list );
|
||||
list_del ( &page->list );
|
||||
addr = page->addr;
|
||||
free ( page );
|
||||
}
|
||||
err_golan_iget_page_alloc_page:
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int golan_return_page ( struct list_head *head,
|
||||
userptr_t addr ) {
|
||||
struct golan_page *new_entry;
|
||||
int rc = 0;
|
||||
|
||||
if ( ! head ) {
|
||||
rc = -EINVAL;
|
||||
goto err_golan_return_page_bad_param;
|
||||
}
|
||||
new_entry = zalloc ( sizeof ( *new_entry ) );
|
||||
if ( new_entry == NULL ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_golan_return_page_alloc_page;
|
||||
}
|
||||
new_entry->addr = addr;
|
||||
list_add_tail( &new_entry->list, head );
|
||||
|
||||
err_golan_return_page_alloc_page:
|
||||
err_golan_return_page_bad_param:
|
||||
return rc;
|
||||
}
|
||||
/******************************************************************************/
|
||||
|
||||
const char *golan_qp_state_as_string[] = {
|
||||
@ -450,8 +458,8 @@ err_query_hca_cap:
|
||||
|
||||
static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16 func_id ) {
|
||||
uint32_t out_num_entries = 0;
|
||||
int size_ibox = sizeof(struct golan_manage_pages_inbox);
|
||||
int size_obox = sizeof(struct golan_manage_pages_outbox);
|
||||
int size_ibox = 0;
|
||||
int size_obox = 0;
|
||||
int rc = 0;
|
||||
|
||||
DBGC(golan, "%s\n", __FUNCTION__);
|
||||
@ -463,8 +471,8 @@ static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16
|
||||
struct golan_manage_pages_inbox *in;
|
||||
struct golan_manage_pages_outbox_data *out;
|
||||
|
||||
size_ibox += (pas_num * GOLAN_PAS_SIZE);
|
||||
size_obox += (pas_num * GOLAN_PAS_SIZE);
|
||||
size_ibox = sizeof(struct golan_manage_pages_inbox) + (pas_num * GOLAN_PAS_SIZE);
|
||||
size_obox = sizeof(struct golan_manage_pages_outbox) + (pas_num * GOLAN_PAS_SIZE);
|
||||
|
||||
cmd = write_cmd(golan, MEM_CMD_IDX, GOLAN_CMD_OP_MANAGE_PAGES, GOLAN_PAGES_TAKE,
|
||||
MEM_MBOX, MEM_MBOX,
|
||||
@ -480,7 +488,7 @@ static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16
|
||||
out = (struct golan_manage_pages_outbox_data *)GET_OUTBOX(golan, MEM_MBOX);
|
||||
out_num_entries = be32_to_cpu(((struct golan_manage_pages_outbox *)(cmd->out))->num_entries);
|
||||
for (i = 0; i < out_num_entries; ++i) {
|
||||
ufree(BE64_BUS_2_USR(out->pas[i]));
|
||||
golan_return_page ( &golan->pages, ( BE64_BUS_2_USR( out->pas[i] ) ) );
|
||||
}
|
||||
} else {
|
||||
if ( rc == -EBUSY ) {
|
||||
@ -503,8 +511,8 @@ static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16
|
||||
|
||||
static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __be16 func_id ) {
|
||||
struct mbox *mailbox;
|
||||
int size_ibox = sizeof(struct golan_manage_pages_inbox);
|
||||
int size_obox = sizeof(struct golan_manage_pages_outbox);
|
||||
int size_ibox = 0;
|
||||
int size_obox = 0;
|
||||
int rc = 0;
|
||||
|
||||
DBGC(golan, "%s\n", __FUNCTION__);
|
||||
@ -517,8 +525,8 @@ static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __
|
||||
userptr_t addr = 0;
|
||||
|
||||
mailbox = GET_INBOX(golan, MEM_MBOX);
|
||||
size_ibox += (pas_num * GOLAN_PAS_SIZE);
|
||||
size_obox += (pas_num * GOLAN_PAS_SIZE);
|
||||
size_ibox = sizeof(struct golan_manage_pages_inbox) + (pas_num * GOLAN_PAS_SIZE);
|
||||
size_obox = sizeof(struct golan_manage_pages_outbox) + (pas_num * GOLAN_PAS_SIZE);
|
||||
|
||||
cmd = write_cmd(golan, MEM_CMD_IDX, GOLAN_CMD_OP_MANAGE_PAGES, GOLAN_PAGES_GIVE,
|
||||
MEM_MBOX, MEM_MBOX,
|
||||
@ -531,7 +539,7 @@ static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __
|
||||
in->num_entries = cpu_to_be32(pas_num);
|
||||
|
||||
for ( i = 0 , j = MANAGE_PAGES_PSA_OFFSET; i < pas_num; ++i ,++j ) {
|
||||
if (!(addr = umalloc(GOLAN_PAGE_SIZE))) {
|
||||
if ( ! ( addr = golan_get_page ( & golan->pages ) ) ) {
|
||||
rc = -ENOMEM;
|
||||
DBGC (golan ,"Couldnt allocated page \n");
|
||||
goto malloc_dma_failed;
|
||||
@ -555,7 +563,7 @@ static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __
|
||||
get_cmd( golan , MEM_CMD_IDX )->status_own,
|
||||
be32_to_cpu(CMD_SYND(golan, MEM_CMD_IDX)), pas_num);
|
||||
}
|
||||
ufree ( addr );
|
||||
golan_return_page ( &golan->pages ,addr );
|
||||
goto err_send_command;
|
||||
}
|
||||
}
|
||||
@ -834,7 +842,7 @@ static int golan_create_eq(struct golan *golan)
|
||||
return 0;
|
||||
|
||||
err_create_eq_cmd:
|
||||
ufree(virt_to_user(golan->eq.eqes));
|
||||
golan_return_page ( & golan->pages, virt_to_user ( eq->eqes ) );
|
||||
err_create_eq_eqe_alloc:
|
||||
DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
|
||||
return rc;
|
||||
@ -859,7 +867,7 @@ static void golan_destory_eq(struct golan *golan)
|
||||
rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
|
||||
GOLAN_PRINT_RC_AND_CMD_STATUS;
|
||||
|
||||
ufree(virt_to_user(golan->eq.eqes));
|
||||
golan_return_page ( &golan->pages, virt_to_user ( golan->eq.eqes ) );
|
||||
golan->eq.eqn = 0;
|
||||
|
||||
DBGC( golan, "%s Event queue (0x%x) was destroyed\n", __FUNCTION__, eqn);
|
||||
@ -1063,7 +1071,7 @@ static int golan_create_cq(struct ib_device *ibdev,
|
||||
return 0;
|
||||
|
||||
err_create_cq_cmd:
|
||||
ufree(virt_to_user(golan_cq->cqes));
|
||||
golan_return_page ( & golan->pages, virt_to_user ( golan_cq->cqes ) );
|
||||
err_create_cq_cqe_alloc:
|
||||
free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
|
||||
err_create_cq_db_alloc:
|
||||
@ -1100,7 +1108,7 @@ static void golan_destroy_cq(struct ib_device *ibdev,
|
||||
cq->cqn = 0;
|
||||
|
||||
ib_cq_set_drvdata(cq, NULL);
|
||||
ufree(virt_to_user(golan_cq->cqes));
|
||||
golan_return_page ( & golan->pages, virt_to_user ( golan_cq->cqes ) );
|
||||
free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
|
||||
free(golan_cq);
|
||||
|
||||
@ -1272,7 +1280,7 @@ static int golan_create_qp_aux(struct ib_device *ibdev,
|
||||
err_create_qp_cmd:
|
||||
free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
|
||||
err_create_qp_db_alloc:
|
||||
ufree((userptr_t)golan_qp->wqes);
|
||||
golan_return_page ( & golan->pages, ( userptr_t ) golan_qp->wqes );
|
||||
err_create_qp_wqe_alloc:
|
||||
err_create_qp_sq_size:
|
||||
err_create_qp_sq_wqe_size:
|
||||
@ -1326,7 +1334,7 @@ static int golan_modify_qp_rst_to_init(struct ib_device *ibdev,
|
||||
|
||||
in->ctx.pri_path.port = ibdev->port;
|
||||
in->ctx.flags |= cpu_to_be32(GOLAN_QP_PM_MIGRATED << GOLAN_QP_CTX_PM_STATE_BIT);
|
||||
in->ctx.pri_path.pkey_index = 0; /* default index */
|
||||
in->ctx.pri_path.pkey_index = 0;
|
||||
/* QK is 0 */
|
||||
/* QP cntr set 0 */
|
||||
return rc;
|
||||
@ -1480,7 +1488,7 @@ static void golan_destroy_qp(struct ib_device *ibdev,
|
||||
|
||||
ib_qp_set_drvdata(qp, NULL);
|
||||
free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
|
||||
ufree((userptr_t)golan_qp->wqes);
|
||||
golan_return_page ( & golan->pages, ( userptr_t ) golan_qp->wqes );
|
||||
free(golan_qp);
|
||||
|
||||
DBGC( golan ,"%s QP 0x%lx was destroyed\n", __FUNCTION__, qpn);
|
||||
@ -1694,8 +1702,8 @@ err_query_vport_gid_cmd:
|
||||
static int golan_query_vport_pkey ( struct ib_device *ibdev ) {
|
||||
struct golan *golan = ib_get_drvdata ( ibdev );
|
||||
struct golan_cmd_layout *cmd;
|
||||
struct golan_query_hca_vport_pkey_inbox *in;
|
||||
//struct golan_query_hca_vport_pkey_data *pkey_table;
|
||||
struct golan_query_hca_vport_pkey_inbox *in;
|
||||
int pkey_table_size_in_entries = (1 << (7 + golan->caps.pkey_table_size));
|
||||
int rc;
|
||||
|
||||
@ -2244,26 +2252,24 @@ static inline void golan_bring_down(struct golan *golan)
|
||||
}
|
||||
|
||||
static int golan_set_link_speed ( struct golan *golan ){
|
||||
mlx_utils utils;
|
||||
mlx_status status;
|
||||
int i = 0;
|
||||
int utils_inited = 0;
|
||||
|
||||
memset ( &utils, 0, sizeof ( utils ) );
|
||||
|
||||
status = mlx_utils_init ( &utils, golan->pci );
|
||||
MLX_CHECK_STATUS ( golan->pci, status, utils_init_err, "mlx_utils_init failed" );
|
||||
|
||||
status = mlx_pci_gw_init ( &utils );
|
||||
MLX_CHECK_STATUS ( golan->pci, status, pci_gw_init_err, "mlx_pci_gw_init failed" );
|
||||
if ( ! golan->utils ) {
|
||||
utils_inited = 1;
|
||||
status = init_mlx_utils ( & golan->utils, golan->pci );
|
||||
MLX_CHECK_STATUS ( golan->pci, status, utils_init_err, "mlx_utils_init failed" );
|
||||
}
|
||||
|
||||
for ( i = 0; i < golan->caps.num_ports; ++i ) {
|
||||
status = mlx_set_link_speed( &utils, i + 1, LINK_SPEED_IB, LINK_SPEED_SDR );
|
||||
status = mlx_set_link_speed ( golan->utils, i + 1, LINK_SPEED_IB, LINK_SPEED_SDR );
|
||||
MLX_CHECK_STATUS ( golan->pci, status, set_link_speed_err, "mlx_set_link_speed failed" );
|
||||
}
|
||||
|
||||
set_link_speed_err:
|
||||
mlx_pci_gw_teardown( &utils );
|
||||
pci_gw_init_err:
|
||||
if ( utils_inited )
|
||||
free_mlx_utils ( & golan->utils );
|
||||
utils_init_err:
|
||||
return status;
|
||||
}
|
||||
@ -2344,7 +2350,16 @@ out:
|
||||
*
|
||||
* @v ibdev Infiniband device
|
||||
*/
|
||||
static void golan_ib_close ( struct ib_device *ibdev __unused ) {}
|
||||
static void golan_ib_close ( struct ib_device *ibdev ) {
|
||||
struct golan *golan = NULL;
|
||||
|
||||
DBG ( "%s start\n", __FUNCTION__ );
|
||||
if ( ! ibdev )
|
||||
return;
|
||||
golan = ib_get_drvdata ( ibdev );
|
||||
golan_bring_down ( golan );
|
||||
DBG ( "%s end\n", __FUNCTION__ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise Infiniband link
|
||||
@ -2353,11 +2368,13 @@ static void golan_ib_close ( struct ib_device *ibdev __unused ) {}
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int golan_ib_open ( struct ib_device *ibdev ) {
|
||||
struct golan *golan = NULL;
|
||||
DBG ( "%s start\n", __FUNCTION__ );
|
||||
|
||||
if ( ! ibdev )
|
||||
return -EINVAL;
|
||||
|
||||
golan = ib_get_drvdata ( ibdev );
|
||||
golan_bring_up ( golan );
|
||||
golan_ib_update ( ibdev );
|
||||
|
||||
DBG ( "%s end\n", __FUNCTION__ );
|
||||
@ -2417,6 +2434,12 @@ static int golan_probe_normal ( struct pci_device *pci ) {
|
||||
goto err_golan_bringup;
|
||||
}
|
||||
|
||||
if ( ! DEVICE_IS_CIB ( pci->device ) ) {
|
||||
if ( init_mlx_utils ( & golan->utils, pci ) ) {
|
||||
rc = -1;
|
||||
goto err_utils_init;
|
||||
}
|
||||
}
|
||||
/* Allocate Infiniband devices */
|
||||
for (i = 0; i < golan->caps.num_ports; ++i) {
|
||||
ibdev = alloc_ibdev( 0 );
|
||||
@ -2435,10 +2458,13 @@ static int golan_probe_normal ( struct pci_device *pci ) {
|
||||
/* Register devices */
|
||||
for ( i = 0; i < golan->caps.num_ports; ++i ) {
|
||||
port = &golan->ports[i];
|
||||
if ((rc = golan_register_ibdev ( port ) ) != 0 )
|
||||
if ((rc = golan_register_ibdev ( port ) ) != 0 ) {
|
||||
goto err_golan_probe_register_ibdev;
|
||||
}
|
||||
}
|
||||
|
||||
golan_bring_down ( golan );
|
||||
|
||||
return 0;
|
||||
|
||||
i = golan->caps.num_ports;
|
||||
@ -2450,7 +2476,10 @@ err_golan_probe_register_ibdev:
|
||||
err_golan_probe_alloc_ibdev:
|
||||
for ( i-- ; ( signed int ) i >= 0 ; i-- )
|
||||
ibdev_put ( golan->ports[i].ibdev );
|
||||
|
||||
if ( ! DEVICE_IS_CIB ( pci->device ) ) {
|
||||
free_mlx_utils ( & golan->utils );
|
||||
}
|
||||
err_utils_init:
|
||||
golan_bring_down ( golan );
|
||||
err_golan_bringup:
|
||||
err_fw_ver_cmdif:
|
||||
@ -2476,13 +2505,13 @@ static void golan_remove_normal ( struct pci_device *pci ) {
|
||||
}
|
||||
for ( i = ( golan->caps.num_ports - 1 ) ; i >= 0 ; i-- ) {
|
||||
netdev_nullify ( golan->ports[i].netdev );
|
||||
netdev_put ( golan->ports[i].netdev );
|
||||
}
|
||||
for ( i = ( golan->caps.num_ports - 1 ) ; i >= 0 ; i-- ) {
|
||||
ibdev_put ( golan->ports[i].ibdev );
|
||||
}
|
||||
|
||||
golan_bring_down(golan);
|
||||
if ( ! DEVICE_IS_CIB ( pci->device ) ) {
|
||||
free_mlx_utils ( & golan->utils );
|
||||
}
|
||||
iounmap( golan->iseg );
|
||||
golan_free_pages( &golan->pages );
|
||||
free(golan);
|
||||
@ -2491,6 +2520,26 @@ static void golan_remove_normal ( struct pci_device *pci ) {
|
||||
/***************************************************************************
|
||||
* NODNIC operations
|
||||
**************************************************************************/
|
||||
static mlx_status shomron_tx_uar_send_db ( struct ib_device *ibdev,
|
||||
struct nodnic_send_wqbb *wqbb ) {
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
|
||||
struct shomron_nodnic_eth_send_wqe *eth_wqe =
|
||||
( struct shomron_nodnic_eth_send_wqe * )wqbb;
|
||||
struct shomronprm_wqe_segment_ctrl_send *ctrl;
|
||||
|
||||
if ( ! ibdev || ! eth_wqe || ! flexboot_nodnic->device_priv.uar.virt ) {
|
||||
DBG("%s: Invalid parameters\n",__FUNCTION__);
|
||||
status = MLX_FAILED;
|
||||
goto err;
|
||||
}
|
||||
wmb();
|
||||
ctrl = & eth_wqe->ctrl;
|
||||
writeq(*((__be64 *)ctrl), flexboot_nodnic->device_priv.uar.virt + 0x800);
|
||||
err:
|
||||
return status;
|
||||
}
|
||||
|
||||
static mlx_status shomron_fill_eth_send_wqe ( struct ib_device *ibdev,
|
||||
struct ib_queue_pair *qp, struct ib_address_vector *av __unused,
|
||||
struct io_buffer *iobuf, struct nodnic_send_wqbb *wqbb,
|
||||
@ -2599,12 +2648,13 @@ struct flexboot_nodnic_callbacks shomron_nodnic_callbacks = {
|
||||
.fill_completion = shomron_fill_completion,
|
||||
.cqe_set_owner = shomron_cqe_set_owner,
|
||||
.irq = flexboot_nodnic_eth_irq,
|
||||
.tx_uar_send_doorbell_fn = shomron_tx_uar_send_db,
|
||||
};
|
||||
|
||||
static int shomron_nodnic_supported = 0;
|
||||
|
||||
static int shomron_nodnic_is_supported ( struct pci_device *pci ) {
|
||||
if ( pci->device == 0x1011 )
|
||||
if ( DEVICE_IS_CIB ( pci->device ) )
|
||||
return 0;
|
||||
|
||||
return flexboot_nodnic_is_supported ( pci );
|
||||
@ -2624,15 +2674,9 @@ static int golan_probe ( struct pci_device *pci ) {
|
||||
|
||||
shomron_nodnic_supported = shomron_nodnic_is_supported ( pci );
|
||||
if ( shomron_nodnic_supported ) {
|
||||
DBG ( "%s: Using NODNIC driver\n", __FUNCTION__ );
|
||||
rc = flexboot_nodnic_probe ( pci, &shomron_nodnic_callbacks, NULL );
|
||||
if ( rc == 0 ) {
|
||||
DBG ( "%s: Using NODNIC driver\n", __FUNCTION__ );
|
||||
goto probe_done;
|
||||
}
|
||||
shomron_nodnic_supported = 0;
|
||||
}
|
||||
|
||||
if ( ! shomron_nodnic_supported ) {
|
||||
} else {
|
||||
DBG ( "%s: Using normal driver\n", __FUNCTION__ );
|
||||
rc = golan_probe_normal ( pci );
|
||||
}
|
||||
@ -2662,6 +2706,8 @@ static struct pci_device_id golan_nics[] = {
|
||||
PCI_ROM ( 0x15b3, 0x1011, "ConnectIB", "ConnectIB HCA driver: DevID 4113", 0 ),
|
||||
PCI_ROM ( 0x15b3, 0x1013, "ConnectX-4", "ConnectX-4 HCA driver, DevID 4115", 0 ),
|
||||
PCI_ROM ( 0x15b3, 0x1015, "ConnectX-4Lx", "ConnectX-4Lx HCA driver, DevID 4117", 0 ),
|
||||
PCI_ROM ( 0x15b3, 0x1017, "ConnectX-5", "ConnectX-5 HCA driver, DevID 4119", 0 ),
|
||||
PCI_ROM ( 0x15b3, 0x1019, "ConnectX-5EX", "ConnectX-5EX HCA driver, DevID 4121", 0 ),
|
||||
};
|
||||
|
||||
struct pci_driver golan_driver __pci_driver = {
|
||||
|
12
third_party/ipxe/src/drivers/infiniband/golan.h
vendored
12
third_party/ipxe/src/drivers/infiniband/golan.h
vendored
@ -22,14 +22,15 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ipxe/io.h>
|
||||
#include <ipxe/pci.h>
|
||||
#include <ipxe/pcibackup.h>
|
||||
#include <byteswap.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/io.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "CIB_PRM.h"
|
||||
#include "mlx_utils/include/public/mlx_utils.h"
|
||||
|
||||
#define GOLAN_PCI_CONFIG_BAR_SIZE 0x100000//HERMON_PCI_CONFIG_BAR_SIZE //TODO: What is the BAR size?
|
||||
|
||||
@ -319,6 +320,7 @@ struct golan {
|
||||
uint32_t pdn;
|
||||
u32 mkey;
|
||||
u32 flags;
|
||||
mlx_utils *utils;
|
||||
|
||||
struct golan_port ports[GOLAN_MAX_PORTS];
|
||||
};
|
||||
|
@ -36,6 +36,8 @@ typedef struct _nodnic_device_capabilites nodnic_device_capabilites;
|
||||
typedef struct _nodnic_qp nodnic_qp;
|
||||
typedef struct _nodnic_cq nodnic_cq;
|
||||
typedef struct _nodnic_eq nodnic_eq;
|
||||
typedef struct _nodnic_qp_db nodnic_qp_db;
|
||||
typedef struct _nodnic_arm_cq_db nodnic_arm_cq_db;
|
||||
|
||||
/* NODNIC Port states
|
||||
* Bit 0 - port open/close
|
||||
@ -73,6 +75,12 @@ typedef enum {
|
||||
struct nodnic_send_wqbb {
|
||||
mlx_uint8 force_align[NODNIC_WQBB_SIZE];
|
||||
};
|
||||
|
||||
struct nodnic_doorbell {
|
||||
mlx_physical_address doorbell_physical;
|
||||
mlx_void *map;
|
||||
nodnic_qp_db *qp_doorbell_record;
|
||||
};
|
||||
struct nodnic_ring {
|
||||
mlx_uint32 offset;
|
||||
/** Work queue entries */
|
||||
@ -91,7 +99,8 @@ struct nodnic_ring {
|
||||
mlx_uint32 num_wqes;
|
||||
mlx_uint32 qpn;
|
||||
mlx_uint32 next_idx;
|
||||
mlx_uint32 ring_pi;
|
||||
struct nodnic_doorbell recv_doorbell;
|
||||
struct nodnic_doorbell send_doorbell;
|
||||
};
|
||||
|
||||
struct nodnic_send_ring{
|
||||
@ -117,6 +126,7 @@ struct _nodnic_cq{
|
||||
mlx_void *map;
|
||||
/** cq */
|
||||
mlx_size cq_size;
|
||||
struct nodnic_doorbell arm_cq_doorbell;
|
||||
};
|
||||
|
||||
struct _nodnic_eq{
|
||||
@ -136,6 +146,10 @@ struct _nodnic_device_capabilites{
|
||||
#ifdef DEVICE_CX3
|
||||
mlx_uint8 crspace_doorbells;
|
||||
#endif
|
||||
mlx_uint8 support_rx_pi_dma;
|
||||
mlx_uint8 support_uar_tx_db;
|
||||
mlx_uint8 support_bar_cq_ctrl;
|
||||
mlx_uint8 log_uar_page_size;
|
||||
};
|
||||
|
||||
#ifdef DEVICE_CX3
|
||||
@ -151,6 +165,13 @@ struct _nodnic_port_data_flow_gw {
|
||||
} __attribute__ ((packed));
|
||||
#endif
|
||||
|
||||
typedef struct _nodnic_uar_priv{
|
||||
mlx_uint8 inited;
|
||||
mlx_uint64 offset;
|
||||
void *virt;
|
||||
unsigned long phys;
|
||||
} nodnic_uar;
|
||||
|
||||
struct _nodnic_device_priv{
|
||||
mlx_boolean is_initiailzied;
|
||||
mlx_utils *utils;
|
||||
@ -169,6 +190,7 @@ struct _nodnic_device_priv{
|
||||
#ifdef DEVICE_CX3
|
||||
mlx_void *crspace_clear_int;
|
||||
#endif
|
||||
nodnic_uar uar;
|
||||
};
|
||||
|
||||
struct _nodnic_port_priv{
|
||||
@ -181,6 +203,7 @@ struct _nodnic_port_priv{
|
||||
mlx_uint8 port_num;
|
||||
nodnic_eq eq;
|
||||
mlx_mac_address mac_filters[5];
|
||||
nodnic_arm_cq_db *arm_cq_doorbell_record;
|
||||
mlx_status (*send_doorbell)(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
IN struct nodnic_ring *ring,
|
||||
@ -197,5 +220,12 @@ struct _nodnic_port_priv{
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _nodnic_qp_db {
|
||||
mlx_uint32 recv_db;
|
||||
mlx_uint32 send_db;
|
||||
} __attribute ( ( packed ) );
|
||||
|
||||
struct _nodnic_arm_cq_db {
|
||||
mlx_uint32 dword[2];
|
||||
} __attribute ( ( packed ) );
|
||||
#endif /* STUB_NODNIC_NODNICDATASTRUCTURES_H_ */
|
||||
|
@ -47,6 +47,9 @@ typedef enum {
|
||||
#ifdef DEVICE_CX3
|
||||
nodnic_port_option_crspace_en,
|
||||
#endif
|
||||
nodnic_port_option_send_ring0_uar_index,
|
||||
nodnic_port_option_send_ring1_uar_index,
|
||||
nodnic_port_option_cq_n_index,
|
||||
}nodnic_port_option;
|
||||
|
||||
struct nodnic_port_data_entry{
|
||||
@ -226,4 +229,14 @@ nodnic_port_read_port_management_change_event(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
OUT mlx_boolean *change_event
|
||||
);
|
||||
mlx_status
|
||||
nodnic_port_set_send_uar_offset(
|
||||
IN nodnic_port_priv *port_priv
|
||||
);
|
||||
|
||||
mlx_status
|
||||
nodnic_port_update_tx_db_func(
|
||||
IN nodnic_device_priv *device_priv,
|
||||
IN nodnic_port_priv *port_priv
|
||||
);
|
||||
#endif /* STUB_NODNIC_PORT_H_ */
|
||||
|
@ -169,11 +169,17 @@ nodnic_device_clear_int (
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
mlx_uint32 disable = 1;
|
||||
#ifndef DEVICE_CX3
|
||||
status = nodnic_cmd_write(device_priv, NODNIC_NIC_DISABLE_INT_OFFSET, disable);
|
||||
#define NODNIC_CLEAR_INT_BAR_OFFSET 0x100C
|
||||
if ( device_priv->device_cap.support_bar_cq_ctrl ) {
|
||||
status = mlx_pci_mem_write ( device_priv->utils, MlxPciWidthUint32, 0,
|
||||
( mlx_uint64 ) ( NODNIC_CLEAR_INT_BAR_OFFSET ), 1, &disable );
|
||||
} else {
|
||||
status = nodnic_cmd_write(device_priv, NODNIC_NIC_DISABLE_INT_OFFSET, disable);
|
||||
}
|
||||
MLX_CHECK_STATUS(device_priv, status, clear_int_done, "failed writing to disable_bit");
|
||||
#else
|
||||
mlx_utils *utils = device_priv->utils;
|
||||
mlx_uint64 clear_int = (mlx_uint64)(device_priv->crspace_clear_int);
|
||||
mlx_uint64 clear_int = (mlx_uintn)(device_priv->crspace_clear_int);
|
||||
mlx_uint32 swapped = 0;
|
||||
|
||||
if (device_priv->device_cap.crspace_doorbells == 0) {
|
||||
@ -303,6 +309,30 @@ nodnic_device_get_cap(
|
||||
status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x14, (mlx_uint32*)&guid_l);
|
||||
MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic guid_l");
|
||||
device_priv->device_guid = guid_l | (guid_h << 32);
|
||||
|
||||
#define NODNIC_DEVICE_SUPPORT_RX_PI_DMA_OFFSET 31
|
||||
#define NODNIC_DEVICE_SUPPORT_RX_PI_DMA_MASK 0x1
|
||||
#define NODNIC_DEVICE_SUPPORT_UAR_TRX_DB_OFFSET 29
|
||||
#define NODNIC_DEVICE_SUPPORT_UAR_TRX_DB_MASK 0x1
|
||||
#define NODNIC_DEVICE_SUPPORT_BAR_CQ_CONTROL_OFFSET 27
|
||||
#define NODNIC_DEVICE_SUPPORT_BAR_CQ_CONTROL_MASK 0x1
|
||||
status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x1c, &buffer);
|
||||
MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic support_rx_pi_dma");
|
||||
if ( sizeof ( mlx_uintn ) == sizeof ( mlx_uint32 ) ) {
|
||||
device_cap->support_rx_pi_dma = FALSE;
|
||||
device_cap->support_uar_tx_db = FALSE;
|
||||
device_cap->support_bar_cq_ctrl = FALSE;
|
||||
} else {
|
||||
device_cap->support_rx_pi_dma = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_RX_PI_DMA_OFFSET);
|
||||
device_cap->support_uar_tx_db = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_UAR_TRX_DB_OFFSET);
|
||||
device_cap->support_bar_cq_ctrl = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_BAR_CQ_CONTROL_OFFSET);
|
||||
}
|
||||
|
||||
#define NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_OFFSET 0
|
||||
#define NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_MASK 0xFF
|
||||
status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x20, &buffer);
|
||||
MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic log_uar_page_size");
|
||||
device_cap->log_uar_page_size = ( buffer >> NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_OFFSET) & NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_MASK;
|
||||
read_err:
|
||||
parm_err:
|
||||
return status;
|
||||
|
@ -55,11 +55,18 @@ struct nodnic_port_data_entry nodnic_port_data_table[] = {
|
||||
PortDataEntry(nodnic_port_option_cq_addr_high, 0x68, 0, 0xFFFFFFFF),
|
||||
PortDataEntry(nodnic_port_option_port_management_change_event, 0x0, 30, 0x1),
|
||||
PortDataEntry(nodnic_port_option_port_promisc_en, 0x4, 29, 0x1),
|
||||
#ifndef DEVICE_CX3
|
||||
PortDataEntry(nodnic_port_option_arm_cq, 0x78, 8, 0xffffff),
|
||||
#else
|
||||
PortDataEntry(nodnic_port_option_arm_cq, 0x78, 8, 0xffff),
|
||||
#endif
|
||||
PortDataEntry(nodnic_port_option_port_promisc_multicast_en, 0x4, 28, 0x1),
|
||||
#ifdef DEVICE_CX3
|
||||
PortDataEntry(nodnic_port_option_crspace_en, 0x4, 27, 0x1),
|
||||
#endif
|
||||
PortDataEntry(nodnic_port_option_send_ring0_uar_index, 0x108, 0, 0xFFFFFFFF),
|
||||
PortDataEntry(nodnic_port_option_send_ring1_uar_index, 0x10c, 0, 0xFFFFFFFF),
|
||||
PortDataEntry(nodnic_port_option_cq_n_index, 0x118, 0, 0xFFFFFF),
|
||||
};
|
||||
|
||||
#define MAX_QP_DATA_ENTRIES 5
|
||||
@ -186,6 +193,30 @@ invalid_parm:
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
nodnic_port_set_send_uar_offset(
|
||||
IN nodnic_port_priv *port_priv
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
mlx_uint32 out = 0;
|
||||
|
||||
if ( ! port_priv->device->device_cap.support_uar_tx_db ) {
|
||||
MLX_DEBUG_INFO1 ( port_priv, "nodnic_port_set_send_uar_offset: tx db using uar is not supported \n");
|
||||
status = MLX_UNSUPPORTED;
|
||||
goto uar_not_supported;
|
||||
}
|
||||
|
||||
status = nodnic_port_query(port_priv,
|
||||
nodnic_port_option_send_ring0_uar_index, &out);
|
||||
MLX_CHECK_STATUS(port_priv->device, status, query_err,
|
||||
"nodnic_port_query failed");
|
||||
port_priv->device->uar.offset = out << port_priv->device->device_cap.log_uar_page_size;
|
||||
uar_not_supported:
|
||||
query_err:
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
nodnic_port_read_reset_needed(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
@ -220,6 +251,111 @@ query_err:
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
mlx_status
|
||||
nodnic_port_allocate_dbr_dma (
|
||||
IN nodnic_port_priv *port_priv,
|
||||
IN struct nodnic_doorbell *nodnic_db,
|
||||
IN mlx_uint32 dbr_addr_low_ofst,
|
||||
IN mlx_uint32 dbr_addr_high_ofst,
|
||||
IN void **dbr_addr,
|
||||
IN mlx_size size,
|
||||
IN void **map
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
mlx_uint64 address = 0;
|
||||
nodnic_device_priv *device_priv = NULL;
|
||||
|
||||
if( port_priv == NULL || nodnic_db == NULL ){
|
||||
status = MLX_INVALID_PARAMETER;
|
||||
goto invalid_parm;
|
||||
}
|
||||
|
||||
device_priv = port_priv->device;
|
||||
status = mlx_memory_alloc_dma(device_priv->utils,
|
||||
size,
|
||||
NODNIC_MEMORY_ALIGN,
|
||||
(void **)dbr_addr
|
||||
);
|
||||
MLX_FATAL_CHECK_STATUS(status, alloc_db_record_err,
|
||||
"doorbell record dma allocation error");
|
||||
|
||||
status = mlx_memory_map_dma(device_priv->utils,
|
||||
(void *)(*dbr_addr),
|
||||
size,
|
||||
&nodnic_db->doorbell_physical,
|
||||
map//nodnic_ring->map
|
||||
);
|
||||
MLX_FATAL_CHECK_STATUS(status, map_db_record_err,
|
||||
"doorbell record map dma error");
|
||||
|
||||
address = (mlx_uint64)nodnic_db->doorbell_physical;
|
||||
status = nodnic_cmd_write(device_priv,
|
||||
dbr_addr_low_ofst,
|
||||
(mlx_uint32)address);
|
||||
MLX_FATAL_CHECK_STATUS(status, set_err,
|
||||
"failed to set doorbell addr low");
|
||||
|
||||
address = address >> 32;
|
||||
status = nodnic_cmd_write(device_priv,
|
||||
dbr_addr_high_ofst,
|
||||
(mlx_uint32)address);
|
||||
MLX_FATAL_CHECK_STATUS(status, set_err,
|
||||
"failed to set doorbell addr high");
|
||||
|
||||
return status;
|
||||
|
||||
set_err:
|
||||
mlx_memory_ummap_dma(device_priv->utils, *map);
|
||||
map_db_record_err:
|
||||
mlx_memory_free_dma(device_priv->utils, size,
|
||||
(void **)dbr_addr);
|
||||
alloc_db_record_err:
|
||||
invalid_parm:
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
mlx_status
|
||||
nodnic_port_cq_dbr_dma_init(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
OUT nodnic_cq **cq
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
nodnic_device_priv *device_priv = NULL;
|
||||
|
||||
if( port_priv == NULL ){
|
||||
status = MLX_INVALID_PARAMETER;
|
||||
goto invalid_parm;
|
||||
}
|
||||
|
||||
device_priv = port_priv->device;
|
||||
if ( ! device_priv->device_cap.support_bar_cq_ctrl ) {
|
||||
status = MLX_UNSUPPORTED;
|
||||
goto uar_arm_cq_db_unsupported;
|
||||
}
|
||||
|
||||
#define NODNIC_PORT_ARM_CQ_DBR_ADDR_LOW_OFFSET 0x114
|
||||
#define NODNIC_PORT_ARM_CQ_DBR_ADDR_HIGH_OFFSET 0x110
|
||||
|
||||
status = nodnic_port_allocate_dbr_dma ( port_priv,&(*cq)->arm_cq_doorbell,
|
||||
port_priv->port_offset + NODNIC_PORT_ARM_CQ_DBR_ADDR_LOW_OFFSET,
|
||||
port_priv->port_offset + NODNIC_PORT_ARM_CQ_DBR_ADDR_HIGH_OFFSET,
|
||||
(void **)&port_priv->arm_cq_doorbell_record ,
|
||||
sizeof(nodnic_arm_cq_db),
|
||||
(void **)&((*cq)->arm_cq_doorbell.map));
|
||||
MLX_FATAL_CHECK_STATUS(status, alloc_dbr_dma_err,
|
||||
"failed to allocate doorbell record dma");
|
||||
return status;
|
||||
|
||||
alloc_dbr_dma_err:
|
||||
uar_arm_cq_db_unsupported:
|
||||
invalid_parm:
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
nodnic_port_create_cq(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
@ -257,17 +393,24 @@ nodnic_port_create_cq(
|
||||
MLX_FATAL_CHECK_STATUS(status, cq_map_err,
|
||||
"cq map error");
|
||||
|
||||
status = nodnic_port_cq_dbr_dma_init(port_priv,cq);
|
||||
|
||||
/* update cq address */
|
||||
#define NODIC_CQ_ADDR_HIGH 0x68
|
||||
#define NODIC_CQ_ADDR_LOW 0x6c
|
||||
address = (mlx_uint64)(*cq)->cq_physical;
|
||||
nodnic_port_set(port_priv, nodnic_port_option_cq_addr_low,
|
||||
(mlx_uint32)(address >> 12));
|
||||
status = nodnic_port_set(port_priv, nodnic_port_option_cq_addr_low,
|
||||
(mlx_uint32)(address) >> 12);
|
||||
MLX_FATAL_CHECK_STATUS(status, dma_set_addr_low_err,
|
||||
"cq set addr low error");
|
||||
address = address >> 32;
|
||||
nodnic_port_set(port_priv, nodnic_port_option_cq_addr_high,
|
||||
status = nodnic_port_set(port_priv, nodnic_port_option_cq_addr_high,
|
||||
(mlx_uint32)address);
|
||||
|
||||
MLX_FATAL_CHECK_STATUS(status, dma_set_addr_high_err,
|
||||
"cq set addr high error");
|
||||
return status;
|
||||
dma_set_addr_high_err:
|
||||
dma_set_addr_low_err:
|
||||
mlx_memory_ummap_dma(device_priv->utils, (*cq)->map);
|
||||
cq_map_err:
|
||||
mlx_memory_free_dma(device_priv->utils, (*cq)->cq_size,
|
||||
@ -294,6 +437,21 @@ nodnic_port_destroy_cq(
|
||||
}
|
||||
device_priv = port_priv->device;
|
||||
|
||||
if ( device_priv->device_cap.support_bar_cq_ctrl ){
|
||||
status = mlx_memory_ummap_dma(device_priv->utils,
|
||||
cq->arm_cq_doorbell.map);
|
||||
if( status != MLX_SUCCESS){
|
||||
MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
|
||||
}
|
||||
|
||||
status = mlx_memory_free_dma(device_priv->utils,
|
||||
sizeof(nodnic_arm_cq_db),
|
||||
(void **)&(port_priv->arm_cq_doorbell_record));
|
||||
if( status != MLX_SUCCESS){
|
||||
MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
mlx_memory_ummap_dma(device_priv->utils, cq->map);
|
||||
|
||||
mlx_memory_free_dma(device_priv->utils, cq->cq_size,
|
||||
@ -303,6 +461,126 @@ nodnic_port_destroy_cq(
|
||||
invalid_parm:
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
mlx_status
|
||||
nodnic_port_allocate_ring_db_dma (
|
||||
IN nodnic_port_priv *port_priv,
|
||||
IN struct nodnic_ring *nodnic_ring,
|
||||
IN struct nodnic_doorbell *nodnic_db
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
|
||||
if( port_priv == NULL || nodnic_ring == NULL || nodnic_db == NULL ){
|
||||
status = MLX_INVALID_PARAMETER;
|
||||
goto invalid_parm;
|
||||
}
|
||||
#define NODNIC_RING_DBR_ADDR_LOW_OFFSET 0x1C
|
||||
#define NODNIC_RING_DBR_ADDR_HIGH_OFFSET 0x18
|
||||
status = nodnic_port_allocate_dbr_dma ( port_priv,nodnic_db,
|
||||
nodnic_ring->offset + NODNIC_RING_DBR_ADDR_LOW_OFFSET,
|
||||
nodnic_ring->offset + NODNIC_RING_DBR_ADDR_HIGH_OFFSET,
|
||||
(void **)&nodnic_db->qp_doorbell_record,
|
||||
sizeof(nodnic_qp_db),
|
||||
(void **)&nodnic_ring->map );
|
||||
MLX_FATAL_CHECK_STATUS(status, alloc_dbr_dma_err,
|
||||
"failed to allocate doorbell record dma");
|
||||
|
||||
return status;
|
||||
alloc_dbr_dma_err:
|
||||
invalid_parm:
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
mlx_status
|
||||
nodnic_port_rx_pi_dma_alloc(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
OUT nodnic_qp **qp
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
nodnic_device_priv *device_priv = NULL;
|
||||
|
||||
if( port_priv == NULL || qp == NULL){
|
||||
status = MLX_INVALID_PARAMETER;
|
||||
goto invalid_parm;
|
||||
}
|
||||
|
||||
device_priv = port_priv->device;
|
||||
|
||||
if ( ! device_priv->device_cap.support_rx_pi_dma ) {
|
||||
goto rx_pi_dma_unsupported;
|
||||
}
|
||||
|
||||
if ( device_priv->device_cap.support_rx_pi_dma ) {
|
||||
status = nodnic_port_allocate_ring_db_dma(port_priv,
|
||||
&(*qp)->receive.nodnic_ring,&(*qp)->receive.nodnic_ring.recv_doorbell);
|
||||
MLX_FATAL_CHECK_STATUS(status, dma_alloc_err,
|
||||
"rx doorbell dma allocation error");
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
dma_alloc_err:
|
||||
rx_pi_dma_unsupported:
|
||||
invalid_parm:
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
mlx_status
|
||||
nodnic_port_send_db_dma(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
IN struct nodnic_ring *ring,
|
||||
IN mlx_uint16 index
|
||||
)
|
||||
{
|
||||
mlx_uint32 swapped = 0;
|
||||
mlx_uint32 index32 = index;
|
||||
mlx_memory_cpu_to_be32(port_priv->device->utils, index32, &swapped);
|
||||
ring->send_doorbell.qp_doorbell_record->send_db = swapped;
|
||||
|
||||
return MLX_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
mlx_status
|
||||
nodnic_port_tx_dbr_dma_init(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
OUT nodnic_qp **qp
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
nodnic_device_priv *device_priv = NULL;
|
||||
|
||||
if( port_priv == NULL || qp == NULL){
|
||||
status = MLX_INVALID_PARAMETER;
|
||||
goto invalid_parm;
|
||||
}
|
||||
|
||||
device_priv = port_priv->device;
|
||||
|
||||
if ( ! device_priv->device_cap.support_uar_tx_db || ! device_priv->uar.offset ) {
|
||||
status = MLX_UNSUPPORTED;
|
||||
goto uar_tx_db_unsupported;
|
||||
}
|
||||
status = nodnic_port_allocate_ring_db_dma(port_priv,
|
||||
&(*qp)->send.nodnic_ring,&(*qp)->send.nodnic_ring.send_doorbell);
|
||||
MLX_FATAL_CHECK_STATUS(status, dma_alloc_err,
|
||||
"tx doorbell dma allocation error");
|
||||
port_priv->send_doorbell = nodnic_port_send_db_dma;
|
||||
|
||||
return status;
|
||||
|
||||
dma_alloc_err:
|
||||
uar_tx_db_unsupported:
|
||||
invalid_parm:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
nodnic_port_create_qp(
|
||||
IN nodnic_port_priv *port_priv,
|
||||
@ -376,6 +654,13 @@ nodnic_port_create_qp(
|
||||
MLX_FATAL_CHECK_STATUS(status, receive_map_err,
|
||||
"receive wq map error");
|
||||
|
||||
status = nodnic_port_rx_pi_dma_alloc(port_priv,qp);
|
||||
MLX_FATAL_CHECK_STATUS(status, rx_pi_dma_alloc_err,
|
||||
"receive db dma error");
|
||||
|
||||
status = nodnic_port_tx_dbr_dma_init(port_priv,qp);
|
||||
|
||||
|
||||
(*qp)->send.nodnic_ring.wq_size = send_wq_size;
|
||||
(*qp)->send.nodnic_ring.num_wqes = send_wqe_num;
|
||||
(*qp)->receive.nodnic_ring.wq_size = receive_wq_size;
|
||||
@ -420,6 +705,7 @@ nodnic_port_create_qp(
|
||||
write_recv_addr_err:
|
||||
write_send_addr_err:
|
||||
mlx_memory_ummap_dma(device_priv->utils, (*qp)->receive.nodnic_ring.map);
|
||||
rx_pi_dma_alloc_err:
|
||||
receive_map_err:
|
||||
mlx_memory_ummap_dma(device_priv->utils, (*qp)->send.nodnic_ring.map);
|
||||
send_map_err:
|
||||
@ -457,6 +743,36 @@ nodnic_port_destroy_qp(
|
||||
MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
|
||||
}
|
||||
|
||||
if ( device_priv->device_cap.support_rx_pi_dma ){
|
||||
status = mlx_memory_ummap_dma(device_priv->utils,
|
||||
qp->receive.nodnic_ring.recv_doorbell.map);
|
||||
if( status != MLX_SUCCESS){
|
||||
MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
|
||||
}
|
||||
|
||||
status = mlx_memory_free_dma(device_priv->utils,
|
||||
sizeof(nodnic_qp_db),
|
||||
(void **)&(qp->receive.nodnic_ring.recv_doorbell.qp_doorbell_record));
|
||||
if( status != MLX_SUCCESS){
|
||||
MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
if ( device_priv->device_cap.support_uar_tx_db || ! device_priv->uar.offset){
|
||||
status = mlx_memory_ummap_dma(device_priv->utils,
|
||||
qp->send.nodnic_ring.send_doorbell.map);
|
||||
if( status != MLX_SUCCESS){
|
||||
MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
|
||||
}
|
||||
|
||||
status = mlx_memory_free_dma(device_priv->utils,
|
||||
sizeof(nodnic_qp_db),
|
||||
(void **)&(qp->send.nodnic_ring.send_doorbell.qp_doorbell_record));
|
||||
if( status != MLX_SUCCESS){
|
||||
MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
status = mlx_memory_free_dma(device_priv->utils,
|
||||
qp->receive.nodnic_ring.wq_size,
|
||||
(void **)&(qp->receive.wqe_virt));
|
||||
@ -520,7 +836,7 @@ nodnic_port_send_db_connectx3(
|
||||
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
|
||||
mlx_uint32 index32 = index;
|
||||
mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
|
||||
(mlx_uint64)&(ptr->send_doorbell), 1, &index32);
|
||||
(mlx_uintn)&(ptr->send_doorbell), 1, &index32);
|
||||
return MLX_SUCCESS;
|
||||
}
|
||||
|
||||
@ -535,10 +851,24 @@ nodnic_port_recv_db_connectx3(
|
||||
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
|
||||
mlx_uint32 index32 = index;
|
||||
mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
|
||||
(mlx_uint64)&(ptr->recv_doorbell), 1, &index32);
|
||||
(mlx_uintn)&(ptr->recv_doorbell), 1, &index32);
|
||||
return MLX_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
static
|
||||
mlx_status
|
||||
nodnic_port_recv_db_dma(
|
||||
IN nodnic_port_priv *port_priv __attribute__((unused)),
|
||||
IN struct nodnic_ring *ring,
|
||||
IN mlx_uint16 index
|
||||
)
|
||||
{
|
||||
mlx_uint32 swapped = 0;
|
||||
mlx_uint32 index32 = index;
|
||||
mlx_memory_cpu_to_be32(port_priv->device->utils, index32, &swapped);
|
||||
ring->recv_doorbell.qp_doorbell_record->recv_db = swapped;
|
||||
return MLX_SUCCESS;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
nodnic_port_update_ring_doorbell(
|
||||
@ -678,11 +1008,10 @@ nodnic_port_add_mac_filter(
|
||||
goto bad_param;
|
||||
}
|
||||
|
||||
memset(&zero_mac, 0, sizeof(zero_mac));
|
||||
|
||||
device = port_priv->device;
|
||||
utils = device->utils;
|
||||
|
||||
mlx_memory_set(utils, &zero_mac, 0, sizeof(zero_mac));
|
||||
/* check if mac already exists */
|
||||
for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
|
||||
mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
|
||||
@ -759,11 +1088,10 @@ nodnic_port_remove_mac_filter(
|
||||
goto bad_param;
|
||||
}
|
||||
|
||||
memset(&zero_mac, 0, sizeof(zero_mac));
|
||||
|
||||
device = port_priv->device;
|
||||
utils = device->utils;
|
||||
|
||||
mlx_memory_set(utils, &zero_mac, 0, sizeof(zero_mac));
|
||||
/* serch for mac filter */
|
||||
for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
|
||||
mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
|
||||
@ -832,7 +1160,7 @@ nodnic_port_set_dma_connectx3(
|
||||
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
|
||||
mlx_uint32 data = (value ? 0xffffffff : 0x0);
|
||||
mlx_pci_mem_write(utils, MlxPciWidthUint32, 0,
|
||||
(mlx_uint64)&(ptr->dma_en), 1, &data);
|
||||
(mlx_uintn)&(ptr->dma_en), 1, &data);
|
||||
return MLX_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
@ -1029,6 +1357,10 @@ nodnic_port_thin_init(
|
||||
port_priv->set_dma = nodnic_port_set_dma_connectx3;
|
||||
}
|
||||
#endif
|
||||
if ( device_priv->device_cap.support_rx_pi_dma ) {
|
||||
port_priv->recv_doorbell = nodnic_port_recv_db_dma;
|
||||
}
|
||||
|
||||
/* clear reset_needed */
|
||||
nodnic_port_read_reset_needed(port_priv, &reset_needed);
|
||||
|
||||
|
@ -30,6 +30,11 @@ mlx_pci_init_priv(
|
||||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_teardown_priv(
|
||||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_read_priv(
|
||||
IN mlx_utils *utils,
|
||||
|
@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include "../../../mlx_utils_flexboot/include/mlx_logging_priv.h"
|
||||
|
||||
#define MLX_PRINT(...) MLX_PRINT_PRIVATE(__VA_ARGS__)
|
||||
#define MLX_DEBUG_FATAL_ERROR(...) MLX_DEBUG_FATAL_ERROR_PRIVATE(__VA_ARGS__)
|
||||
#define MLX_DEBUG_ERROR(...) MLX_DEBUG_ERROR_PRIVATE(__VA_ARGS__)
|
||||
#define MLX_DEBUG_WARN(...) MLX_DEBUG_WARN_PRIVATE(__VA_ARGS__)
|
||||
|
@ -36,6 +36,11 @@ mlx_pci_init(
|
||||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_teardown(
|
||||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_read(
|
||||
IN mlx_utils *utils,
|
||||
|
@ -124,6 +124,11 @@ struct mlx_link_speed {
|
||||
/* -------------- */
|
||||
mlx_uint32 ib_proto_oper :16;
|
||||
mlx_uint32 ib_link_width_oper :16;
|
||||
/* -------------- */
|
||||
mlx_uint32 reserved7 :32;
|
||||
/* -------------- */
|
||||
mlx_uint32 eth_proto_lp_advertise :32;
|
||||
mlx_uint32 reserved[3];
|
||||
};
|
||||
|
||||
mlx_status
|
||||
|
@ -42,6 +42,7 @@ struct nvconfig_tlv_mapping nvconfig_tlv_mapping[] = {
|
||||
TlvMappingEntry(0x2020, 0x2020, NVRAM_TLV_CLASS_PHYSICAL_PORT, FALSE),
|
||||
TlvMappingEntry(0x2021, 0x221, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2023, 0x223, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2006, 0x206, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2100, 0x230, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2101, 0x231, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2102, 0x232, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
@ -53,6 +54,7 @@ struct nvconfig_tlv_mapping nvconfig_tlv_mapping[] = {
|
||||
TlvMappingEntry(0x2108, 0x238, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2109, 0x239, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x210A, 0x23A, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2022, 0x222, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2200, 0x240, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2201, 0x241, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2202, 0x242, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
@ -60,6 +62,11 @@ struct nvconfig_tlv_mapping nvconfig_tlv_mapping[] = {
|
||||
TlvMappingEntry(0x2204, 0x244, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2205, 0x245, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2207, 0x247, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2002, 0x202, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x2004, 0x204, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x110, 0x110, NVRAM_TLV_CLASS_HOST, FALSE),
|
||||
TlvMappingEntry(0x192, 0x192, NVRAM_TLV_CLASS_GLOBAL, FALSE),
|
||||
TlvMappingEntry(0x101, 0x101, NVRAM_TLV_CLASS_GLOBAL, TRUE),
|
||||
TlvMappingEntry(0, 0, 0, 0),
|
||||
};
|
||||
|
||||
|
@ -107,6 +107,22 @@ struct nvconfig_nvda {
|
||||
mlx_uint8 data[NVCONFIG_MAX_TLV_SIZE];
|
||||
};
|
||||
|
||||
struct nv_conf_cap {
|
||||
/** WOL En/Dis **/
|
||||
mlx_uint8 wol_en;
|
||||
/** VPI En/Dis **/
|
||||
mlx_uint8 vpi_en;
|
||||
};
|
||||
|
||||
struct mlx_nvconfig_virt_net_addr {
|
||||
mlx_uint32 reserved1 :29;
|
||||
mlx_uint32 erase_on_powerup:1;
|
||||
mlx_uint32 reserverd2 :1;
|
||||
mlx_uint32 virtual_mac_en :1;
|
||||
mlx_uint32 virtual_mac_high;
|
||||
mlx_uint32 virtual_mac_low;
|
||||
};
|
||||
|
||||
|
||||
mlx_status
|
||||
nvconfig_query_capability(
|
||||
|
@ -86,13 +86,13 @@ nvconfig_get_boot_ext_default_conf(
|
||||
"TLV not found. Using hard-coded defaults ");
|
||||
port_conf_def->linkup_timeout = nic_boot_ext_conf->linkup_timeout;
|
||||
port_conf_def->ip_ver = nic_boot_ext_conf->ip_ver;
|
||||
|
||||
port_conf_def->undi_network_wait_to = nic_boot_ext_conf->undi_network_wait_to;
|
||||
return MLX_SUCCESS;
|
||||
|
||||
nvdata_access_err:
|
||||
port_conf_def->linkup_timeout = DEFAULT_BOOT_LINK_UP_TO;
|
||||
port_conf_def->ip_ver = DEFAULT_BOOT_IP_VER;
|
||||
|
||||
port_conf_def->undi_network_wait_to = DEFAULT_BOOT_UNDI_NETWORK_WAIT_TO;
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -185,8 +185,12 @@ nvconfig_get_iscsi_gen_default_conf(
|
||||
port_conf_def->iscsi_chap_auth_en = iscsi_gen->chap_auth_en;
|
||||
port_conf_def->iscsi_lun_busy_retry_count = iscsi_gen->lun_busy_retry_count;
|
||||
port_conf_def->iscsi_link_up_delay_time = iscsi_gen->link_up_delay_time;
|
||||
port_conf_def->iscsi_drive_num = iscsi_gen->drive_num;
|
||||
|
||||
return MLX_SUCCESS;
|
||||
|
||||
nvdata_access_err:
|
||||
port_conf_def->iscsi_drive_num = DEFAULT_ISCSI_DRIVE_NUM;
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -327,6 +331,27 @@ nvdata_access_err:
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
mlx_status
|
||||
nvconfig_get_rom_cap_default_conf( IN void *data,
|
||||
IN int status, OUT void *def_struct) {
|
||||
union mlx_nvconfig_rom_cap_conf *rom_cap_conf =
|
||||
(union mlx_nvconfig_rom_cap_conf *) data;
|
||||
struct mlx_nvconfig_conf_defaults *conf_def =
|
||||
(struct mlx_nvconfig_conf_defaults *) def_struct;
|
||||
|
||||
MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
|
||||
"TLV not found. Using hard-coded defaults ");
|
||||
conf_def->boot_ip_ver_en = rom_cap_conf->boot_ip_ver_en;
|
||||
|
||||
return MLX_SUCCESS;
|
||||
|
||||
nvdata_access_err:
|
||||
rom_cap_conf->boot_ip_ver_en = DEFAULT_BOOT_IP_VERSION_EN;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct tlv_default tlv_port_defaults[] = {
|
||||
TlvDefaultEntry(BOOT_SETTINGS_TYPE, union mlx_nvconfig_nic_boot_conf, &nvconfig_get_boot_default_conf),
|
||||
TlvDefaultEntry(BOOT_SETTINGS_EXT_TYPE, union mlx_nvconfig_nic_boot_ext_conf, &nvconfig_get_boot_ext_default_conf),
|
||||
@ -343,6 +368,7 @@ static struct tlv_default tlv_general_defaults[] = {
|
||||
TlvDefaultEntry(GLOPAL_PCI_CAPS_TYPE, union mlx_nvconfig_virt_caps, &nvconfig_get_nv_virt_caps_default_conf),
|
||||
TlvDefaultEntry(GLOPAL_PCI_SETTINGS_TYPE, union mlx_nvconfig_virt_conf, &nvconfig_get_nv_virt_default_conf),
|
||||
TlvDefaultEntry(OCSD_OCBB_TYPE, union mlx_nvconfig_ocsd_ocbb_conf, &nvconfig_get_ocsd_ocbb_default_conf),
|
||||
TlvDefaultEntry(NV_ROM_CAP_TYPE, union mlx_nvconfig_rom_cap_conf, &nvconfig_get_rom_cap_default_conf),
|
||||
};
|
||||
|
||||
static
|
||||
|
@ -32,9 +32,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#define DEFAULT_BOOT_VLAN 1
|
||||
#define DEFAULT_ISCSI_DHCP_PARAM_EN 1
|
||||
#define DEFAULT_ISCSI_IPV4_DHCP_EN 1
|
||||
#define DEFAULT_ISCSI_DRIVE_NUM 0x80
|
||||
#define DEFAULT_OCSD_OCBB_EN 1
|
||||
#define DEFAULT_BOOT_IP_VER 0
|
||||
#define DEFAULT_BOOT_LINK_UP_TO 0
|
||||
#define DEFAULT_BOOT_UNDI_NETWORK_WAIT_TO 30
|
||||
#define DEFAULT_BOOT_IP_VERSION_EN 1
|
||||
|
||||
struct mlx_nvconfig_port_conf_defaults {
|
||||
mlx_uint8 pptx;
|
||||
@ -56,11 +59,13 @@ struct mlx_nvconfig_port_conf_defaults {
|
||||
mlx_boolean iscsi_ipv4_dhcp_en;
|
||||
mlx_uint8 iscsi_lun_busy_retry_count;
|
||||
mlx_uint8 iscsi_link_up_delay_time;
|
||||
mlx_uint8 iscsi_drive_num;
|
||||
mlx_uint8 client_identifier;
|
||||
mlx_uint8 mac_admin_bit;
|
||||
mlx_uint8 default_link_type;
|
||||
mlx_uint8 linkup_timeout;
|
||||
mlx_uint8 ip_ver;
|
||||
mlx_uint8 undi_network_wait_to;
|
||||
};
|
||||
|
||||
struct mlx_nvconfig_conf_defaults {
|
||||
@ -71,6 +76,7 @@ struct mlx_nvconfig_conf_defaults {
|
||||
mlx_uint8 uar_bar_size;
|
||||
mlx_uint8 flexboot_menu_to;
|
||||
mlx_boolean ocsd_ocbb_en;
|
||||
mlx_boolean boot_ip_ver_en;
|
||||
};
|
||||
|
||||
mlx_status
|
||||
|
@ -33,12 +33,15 @@ enum {
|
||||
OCSD_OCBB_TYPE = 0x2011,
|
||||
FLOW_CONTROL_TYPE = 0x2020,
|
||||
BOOT_SETTINGS_TYPE = 0x2021,
|
||||
NV_ROM_FLEXBOOT_DEBUG = 0x2004,
|
||||
|
||||
ISCSI_GENERAL_SETTINGS_TYPE = 0x2100,
|
||||
IB_BOOT_SETTING_TYPE = 0x2022,
|
||||
IB_DHCP_SETTINGS_TYPE = 0x2023,
|
||||
GLOPAL_PCI_SETTINGS_TYPE = 0x80,
|
||||
GLOPAL_PCI_CAPS_TYPE = 0x81,
|
||||
GLOBAL_ROM_INI_TYPE = 0x100,
|
||||
NV_VIRT_NET_ADDR = 0x110,
|
||||
|
||||
// Types for iSCSI strings
|
||||
DHCP_VEND_ID = 0x2101,
|
||||
@ -59,6 +62,8 @@ enum {
|
||||
FIRST_TGT_ISCSI_NAME = 0x2204,
|
||||
FIRST_TGT_CHAP_ID = 0x2205,
|
||||
FIRST_TGT_CHAP_PWD = 0x2207,
|
||||
NV_ROM_DEBUG_LEVEL = 0x2002,
|
||||
NV_ROM_CAP_TYPE = 0x101,
|
||||
};
|
||||
|
||||
union mlx_nvconfig_nic_boot_conf {
|
||||
@ -78,7 +83,9 @@ union mlx_nvconfig_nic_boot_ext_conf {
|
||||
struct {
|
||||
mlx_uint32 linkup_timeout : 8;
|
||||
mlx_uint32 ip_ver : 2;
|
||||
mlx_uint32 reserved0 : 22;
|
||||
mlx_uint32 reserved0 : 6;
|
||||
mlx_uint32 undi_network_wait_to : 8;
|
||||
mlx_uint32 reserved1 : 8;
|
||||
};
|
||||
mlx_uint32 dword;
|
||||
};
|
||||
@ -194,7 +201,8 @@ union mlx_nvconfig_iscsi_general {
|
||||
/*-------------------*/
|
||||
mlx_uint32 lun_busy_retry_count:8;
|
||||
mlx_uint32 link_up_delay_time :8;
|
||||
mlx_uint32 reserved4 :16;
|
||||
mlx_uint32 drive_num :8;
|
||||
mlx_uint32 reserved4 :8;
|
||||
};
|
||||
mlx_uint32 dword[3];
|
||||
};
|
||||
@ -226,34 +234,98 @@ union mlx_nvconfig_vpi_link_conf {
|
||||
};
|
||||
|
||||
struct mlx_nvcofnig_romini {
|
||||
mlx_uint32 reserved0 :1;
|
||||
mlx_uint32 reserved0 :1;
|
||||
mlx_uint32 shared_memory_en :1;
|
||||
mlx_uint32 hii_vpi_en :1;
|
||||
mlx_uint32 tech_enum :1;
|
||||
mlx_uint32 reserved1 :4;
|
||||
mlx_uint32 hii_vpi_en :1;
|
||||
mlx_uint32 tech_enum :1;
|
||||
mlx_uint32 reserved1 :4;
|
||||
mlx_uint32 static_component_name_string :1;
|
||||
mlx_uint32 hii_iscsi_configuration :1;
|
||||
mlx_uint32 hii_ibm_aim :1;
|
||||
mlx_uint32 hii_ibm_aim :1;
|
||||
mlx_uint32 hii_platform_setup :1;
|
||||
mlx_uint32 hii_bdf_decimal :1;
|
||||
mlx_uint32 hii_read_only :1;
|
||||
mlx_uint32 reserved2 :10;
|
||||
mlx_uint32 reserved2 :10;
|
||||
mlx_uint32 mac_enum :1;
|
||||
mlx_uint32 port_enum :1;
|
||||
mlx_uint32 port_enum :1;
|
||||
mlx_uint32 flash_en :1;
|
||||
mlx_uint32 fmp_en :1;
|
||||
mlx_uint32 bofm_en :1;
|
||||
mlx_uint32 platform_to_driver_en :1;
|
||||
mlx_uint32 platform_to_driver_en:1;
|
||||
mlx_uint32 hii_en :1;
|
||||
mlx_uint32 undi_en :1;
|
||||
/* -------------- */
|
||||
mlx_uint64 dhcp_user_class;
|
||||
/* -------------- */
|
||||
mlx_uint32 reserved3 :22;
|
||||
mlx_uint32 reserved3 :10;
|
||||
mlx_uint32 ucm_single_port :1;
|
||||
mlx_uint32 tivoli_wa_en :1;
|
||||
mlx_uint32 dhcp_pxe_discovery_control_dis :1;
|
||||
mlx_uint32 hii_flexaddr_override:1;
|
||||
mlx_uint32 hii_flexaddr_setting :1;
|
||||
mlx_uint32 guided_ops :1;
|
||||
mlx_uint32 hii_type :4;
|
||||
mlx_uint32 hii_mriname2 :1;
|
||||
mlx_uint32 hii_aim_ucm_ver2 :1;
|
||||
mlx_uint32 uri_boot_retry_delay :4;
|
||||
mlx_uint32 uri_boot_retry :4;
|
||||
mlx_uint32 option_rom_debug :1;
|
||||
mlx_uint32 promiscuous_vlan :1;
|
||||
|
||||
} __attribute__ ((packed));
|
||||
|
||||
union mlx_nvconfig_debug_conf {
|
||||
struct {
|
||||
mlx_uint32 dbg_log_en :1;
|
||||
mlx_uint32 reserved1 :31;
|
||||
/***************************************************/
|
||||
mlx_uint32 stp_dbg_lvl :2;
|
||||
mlx_uint32 romprefix_dbg_lvl :2;
|
||||
mlx_uint32 dhcp_dbg_lvl :2;
|
||||
mlx_uint32 dhcpv6_dbg_lvl :2;
|
||||
mlx_uint32 arp_dbg_lvl :2;
|
||||
mlx_uint32 neighbor_dbg_lvl :2;
|
||||
mlx_uint32 ndp_dbg_lvl :2;
|
||||
mlx_uint32 uri_dbg_lvl :2;
|
||||
mlx_uint32 driver_dbg_lvl :2;
|
||||
mlx_uint32 nodnic_dbg_lvl :2;
|
||||
mlx_uint32 nodnic_cmd_dbg_lvl :2;
|
||||
mlx_uint32 nodnic_device_dbg_lvl :2;
|
||||
mlx_uint32 nodnic_port_dbg_lvl :2;
|
||||
mlx_uint32 netdevice_dbg_lvl :2;
|
||||
mlx_uint32 tftp_dbg_lvl :2;
|
||||
mlx_uint32 udp_dbg_lvl :2;
|
||||
/***************************************************/
|
||||
mlx_uint32 tcp_dbg_lvl :2;
|
||||
mlx_uint32 tcpip_dbg_lvl :2;
|
||||
mlx_uint32 ipv4_dbg_lvl :2;
|
||||
mlx_uint32 ipv6_dbg_lvl :2;
|
||||
mlx_uint32 drv_set_dbg_lvl :2;
|
||||
mlx_uint32 stat_update_dbg_lvl :2;
|
||||
mlx_uint32 pxe_undi_dbg_lvl :2;
|
||||
mlx_uint32 reserved2 :18;
|
||||
};
|
||||
mlx_uint32 dword[3];
|
||||
};
|
||||
|
||||
union mlx_nvconfig_flexboot_debug {
|
||||
struct {
|
||||
mlx_uint32 reserved0 :29;
|
||||
mlx_uint32 panic_behavior :2;
|
||||
mlx_uint32 boot_to_shell :1;
|
||||
};
|
||||
mlx_uint32 dword;
|
||||
};
|
||||
|
||||
union mlx_nvconfig_rom_cap_conf {
|
||||
struct {
|
||||
mlx_uint32 reserved0 :28;
|
||||
mlx_uint32 uefi_logs_en :1;
|
||||
mlx_uint32 flexboot_debug_en :1;
|
||||
mlx_uint32 boot_debug_log_en :1;
|
||||
mlx_uint32 boot_ip_ver_en :1;
|
||||
};
|
||||
mlx_uint32 dword;
|
||||
};
|
||||
|
||||
#endif /* MLX_NVCONFIG_PRM_H_ */
|
||||
|
@ -316,7 +316,7 @@ mlx_icmd_send_command(
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
mlx_uint32 icmd_status = MLX_FAILED;
|
||||
mlx_uint32 icmd_status = 0;
|
||||
|
||||
if (utils == NULL || data == NULL) {
|
||||
status = MLX_INVALID_PARAMETER;
|
||||
|
@ -20,6 +20,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../../include/private/mlx_pci_priv.h"
|
||||
#include "../../include/public/mlx_pci.h"
|
||||
|
||||
@ -38,6 +39,21 @@ bail:
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
mlx_pci_teardown(
|
||||
IN mlx_utils *utils
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
if( utils == NULL){
|
||||
status = MLX_INVALID_PARAMETER;
|
||||
goto bail;
|
||||
}
|
||||
status = mlx_pci_teardown_priv(utils);
|
||||
bail:
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
mlx_pci_read(
|
||||
IN mlx_utils *utils,
|
||||
|
@ -20,10 +20,10 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../../include/private/mlx_utils_priv.h"
|
||||
#include "../../include/public/mlx_pci.h"
|
||||
#include "../../include/public/mlx_utils.h"
|
||||
|
||||
mlx_status
|
||||
mlx_utils_init(
|
||||
IN mlx_utils *utils,
|
||||
@ -44,11 +44,12 @@ bail:
|
||||
|
||||
mlx_status
|
||||
mlx_utils_teardown(
|
||||
IN mlx_utils *utils __attribute__ ((unused))
|
||||
IN mlx_utils *utils
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
mlx_utils_free_lock(utils);
|
||||
mlx_pci_teardown(utils);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include <compiler.h>
|
||||
|
||||
#define MLX_DEBUG_FATAL_ERROR_PRIVATE(...) do { \
|
||||
DBG("%s: ",__func__); \
|
||||
DBG(__VA_ARGS__); \
|
||||
printf("%s: ",__func__); \
|
||||
printf(__VA_ARGS__); \
|
||||
} while ( 0 )
|
||||
|
||||
#define MLX_DEBUG_ERROR_PRIVATE(id, ...) do { \
|
||||
@ -56,6 +56,7 @@
|
||||
DBG2(__VA_ARGS__); \
|
||||
} while ( 0 )
|
||||
|
||||
#define MLX_PRINT_PRIVATE(...) printf(__VA_ARGS__)
|
||||
|
||||
|
||||
#endif /* STUB_MLXUTILS_INCLUDE_PRIVATE_FLEXBOOT_DEBUG_H_ */
|
||||
|
@ -33,7 +33,7 @@ typedef uint8_t mlx_uint8;
|
||||
typedef uint16_t mlx_uint16;
|
||||
typedef uint32_t mlx_uint32;
|
||||
typedef uint64_t mlx_uint64;
|
||||
typedef uint32_t mlx_uintn;
|
||||
typedef unsigned long mlx_uintn;
|
||||
|
||||
typedef int8_t mlx_int8;
|
||||
typedef int16_t mlx_int16;;
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <ipxe/pci.h>
|
||||
|
||||
#include "../../mlx_utils/include/private/mlx_pci_priv.h"
|
||||
|
||||
|
||||
@ -120,6 +121,18 @@ mlx_pci_init_priv(
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
mlx_pci_teardown_priv(
|
||||
IN mlx_utils *utils __attribute__ ((unused))
|
||||
)
|
||||
{
|
||||
mlx_status status = MLX_SUCCESS;
|
||||
#ifdef DEVICE_CX3
|
||||
iounmap( utils->config );
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
mlx_status
|
||||
mlx_pci_read_priv(
|
||||
IN mlx_utils *utils,
|
||||
|
325
third_party/ipxe/src/drivers/linux/af_packet.c
vendored
Normal file
325
third_party/ipxe/src/drivers/linux/af_packet.c
vendored
Normal file
@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (C) 2016 David Decotigny <ddecotig@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/list.h>
|
||||
#include <ipxe/linux.h>
|
||||
#include <ipxe/malloc.h>
|
||||
#include <ipxe/device.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
#include <ipxe/iobuf.h>
|
||||
#include <ipxe/ethernet.h>
|
||||
#include <ipxe/settings.h>
|
||||
#include <ipxe/socket.h>
|
||||
|
||||
/* This hack prevents pre-2.6.32 headers from redefining struct sockaddr */
|
||||
#define __GLIBC__ 2
|
||||
#include <linux/socket.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_packet.h>
|
||||
#undef __GLIBC__
|
||||
#include <byteswap.h>
|
||||
|
||||
/* linux-specifc syscall params */
|
||||
#define LINUX_AF_PACKET 17
|
||||
#define LINUX_SOCK_RAW 3
|
||||
#define LINUX_SIOCGIFINDEX 0x8933
|
||||
#define LINUX_SIOCGIFHWADDR 0x8927
|
||||
|
||||
#define RX_BUF_SIZE 1536
|
||||
|
||||
/** @file
|
||||
*
|
||||
* The AF_PACKET driver.
|
||||
*
|
||||
* Bind to an existing linux network interface.
|
||||
*/
|
||||
|
||||
struct af_packet_nic {
|
||||
/** Linux network interface name */
|
||||
char * ifname;
|
||||
/** Packet socket descriptor */
|
||||
int fd;
|
||||
/** ifindex */
|
||||
int ifindex;
|
||||
};
|
||||
|
||||
/** Open the linux interface */
|
||||
static int af_packet_nic_open ( struct net_device * netdev )
|
||||
{
|
||||
struct af_packet_nic * nic = netdev->priv;
|
||||
struct sockaddr_ll socket_address;
|
||||
struct ifreq if_data;
|
||||
int ret;
|
||||
|
||||
nic->fd = linux_socket(LINUX_AF_PACKET, LINUX_SOCK_RAW,
|
||||
htons(ETH_P_ALL));
|
||||
if (nic->fd < 0) {
|
||||
DBGC(nic, "af_packet %p socket(AF_PACKET) = %d (%s)\n",
|
||||
nic, nic->fd, linux_strerror(linux_errno));
|
||||
return nic->fd;
|
||||
}
|
||||
|
||||
/* resolve ifindex of ifname */
|
||||
memset(&if_data, 0, sizeof(if_data));
|
||||
strncpy(if_data.ifr_name, nic->ifname, sizeof(if_data.ifr_name));
|
||||
ret = linux_ioctl(nic->fd, LINUX_SIOCGIFINDEX, &if_data);
|
||||
if (ret < 0) {
|
||||
DBGC(nic, "af_packet %p ioctl(SIOCGIFINDEX) = %d (%s)\n",
|
||||
nic, ret, linux_strerror(linux_errno));
|
||||
linux_close(nic->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nic->ifindex = if_data.ifr_ifindex;
|
||||
|
||||
/* bind to interface */
|
||||
memset(&socket_address, 0, sizeof(socket_address));
|
||||
socket_address.sll_family = LINUX_AF_PACKET;
|
||||
socket_address.sll_ifindex = nic->ifindex;
|
||||
socket_address.sll_protocol = htons(ETH_P_ALL);
|
||||
ret = linux_bind(nic->fd, (void *) &socket_address,
|
||||
sizeof(socket_address));
|
||||
if (ret == -1) {
|
||||
DBGC(nic, "af_packet %p bind() = %d (%s)\n",
|
||||
nic, ret, linux_strerror(linux_errno));
|
||||
linux_close(nic->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set nonblocking mode to make af_packet_nic_poll() easier */
|
||||
ret = linux_fcntl(nic->fd, F_SETFL, O_NONBLOCK);
|
||||
if (ret != 0) {
|
||||
DBGC(nic, "af_packet %p fcntl(%d, ...) = %d (%s)\n",
|
||||
nic, nic->fd, ret, linux_strerror(linux_errno));
|
||||
linux_close(nic->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Close the packet socket */
|
||||
static void af_packet_nic_close ( struct net_device *netdev )
|
||||
{
|
||||
struct af_packet_nic * nic = netdev->priv;
|
||||
linux_close(nic->fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit an ethernet packet.
|
||||
*
|
||||
* The packet can be written to the socket and marked as complete immediately.
|
||||
*/
|
||||
static int af_packet_nic_transmit ( struct net_device *netdev,
|
||||
struct io_buffer *iobuf )
|
||||
{
|
||||
struct af_packet_nic * nic = netdev->priv;
|
||||
struct sockaddr_ll socket_address;
|
||||
const struct ethhdr * eh;
|
||||
int rc;
|
||||
|
||||
memset(&socket_address, 0, sizeof(socket_address));
|
||||
socket_address.sll_family = LINUX_AF_PACKET;
|
||||
socket_address.sll_ifindex = nic->ifindex;
|
||||
socket_address.sll_halen = ETH_ALEN;
|
||||
|
||||
eh = iobuf->data;
|
||||
memcpy(socket_address.sll_addr, eh->h_dest, ETH_ALEN);
|
||||
|
||||
rc = linux_sendto(nic->fd, iobuf->data, iobuf->tail - iobuf->data,
|
||||
0, (struct sockaddr *)&socket_address,
|
||||
sizeof(socket_address));
|
||||
|
||||
DBGC2(nic, "af_packet %p wrote %d bytes\n", nic, rc);
|
||||
netdev_tx_complete(netdev, iobuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Poll for new packets */
|
||||
static void af_packet_nic_poll ( struct net_device *netdev )
|
||||
{
|
||||
struct af_packet_nic * nic = netdev->priv;
|
||||
struct pollfd pfd;
|
||||
struct io_buffer * iobuf;
|
||||
int r;
|
||||
|
||||
pfd.fd = nic->fd;
|
||||
pfd.events = POLLIN;
|
||||
if (linux_poll(&pfd, 1, 0) == -1) {
|
||||
DBGC(nic, "af_packet %p poll failed (%s)\n",
|
||||
nic, linux_strerror(linux_errno));
|
||||
return;
|
||||
}
|
||||
if ((pfd.revents & POLLIN) == 0)
|
||||
return;
|
||||
|
||||
/* At this point we know there is at least one new packet to be read */
|
||||
|
||||
iobuf = alloc_iob(RX_BUF_SIZE);
|
||||
if (! iobuf)
|
||||
goto allocfail;
|
||||
|
||||
while ((r = linux_read(nic->fd, iobuf->data, RX_BUF_SIZE)) > 0) {
|
||||
DBGC2(nic, "af_packet %p read %d bytes\n", nic, r);
|
||||
|
||||
iob_put(iobuf, r);
|
||||
netdev_rx(netdev, iobuf);
|
||||
|
||||
iobuf = alloc_iob(RX_BUF_SIZE);
|
||||
if (! iobuf)
|
||||
goto allocfail;
|
||||
}
|
||||
|
||||
free_iob(iobuf);
|
||||
return;
|
||||
|
||||
allocfail:
|
||||
DBGC(nic, "af_packet %p alloc_iob failed\n", nic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set irq.
|
||||
*
|
||||
* Not used on linux, provide a dummy implementation.
|
||||
*/
|
||||
static void af_packet_nic_irq ( struct net_device *netdev, int enable )
|
||||
{
|
||||
struct af_packet_nic *nic = netdev->priv;
|
||||
|
||||
DBGC(nic, "af_packet %p irq enable = %d\n", nic, enable);
|
||||
}
|
||||
|
||||
|
||||
static int af_packet_update_properties ( struct net_device *netdev )
|
||||
{
|
||||
struct af_packet_nic *nic = netdev->priv;
|
||||
struct ifreq if_data;
|
||||
int ret;
|
||||
|
||||
/* retrieve default MAC address */
|
||||
int fd = linux_socket(LINUX_AF_PACKET, LINUX_SOCK_RAW, 0);
|
||||
if (fd < 0) {
|
||||
DBGC(nic, "af_packet %p cannot create raw socket (%s)\n",
|
||||
nic, linux_strerror(linux_errno));
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* retrieve host's MAC address */
|
||||
memset(&if_data, 0, sizeof(if_data));
|
||||
strncpy(if_data.ifr_name, nic->ifname, sizeof(if_data.ifr_name));
|
||||
ret = linux_ioctl(fd, LINUX_SIOCGIFHWADDR, &if_data);
|
||||
if (ret < 0) {
|
||||
DBGC(nic, "af_packet %p cannot get mac addr (%s)\n",
|
||||
nic, linux_strerror(linux_errno));
|
||||
linux_close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
linux_close(fd);
|
||||
/* struct sockaddr = { u16 family, u8 pad[14] (equiv. sa_data) }; */
|
||||
memcpy(netdev->ll_addr, if_data.ifr_hwaddr.pad, ETH_ALEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** AF_PACKET operations */
|
||||
static struct net_device_operations af_packet_nic_operations = {
|
||||
.open = af_packet_nic_open,
|
||||
.close = af_packet_nic_close,
|
||||
.transmit = af_packet_nic_transmit,
|
||||
.poll = af_packet_nic_poll,
|
||||
.irq = af_packet_nic_irq,
|
||||
};
|
||||
|
||||
/** Handle a device request for the af_packet driver */
|
||||
static int af_packet_nic_probe ( struct linux_device *device,
|
||||
struct linux_device_request *request )
|
||||
{
|
||||
struct linux_setting *if_setting;
|
||||
struct net_device *netdev;
|
||||
struct af_packet_nic *nic;
|
||||
int rc;
|
||||
|
||||
netdev = alloc_etherdev(sizeof(*nic));
|
||||
if (! netdev)
|
||||
return -ENOMEM;
|
||||
|
||||
netdev_init(netdev, &af_packet_nic_operations);
|
||||
nic = netdev->priv;
|
||||
linux_set_drvdata(device, netdev);
|
||||
netdev->dev = &device->dev;
|
||||
|
||||
memset(nic, 0, sizeof(*nic));
|
||||
|
||||
/* Look for the mandatory if setting */
|
||||
if_setting = linux_find_setting("if", &request->settings);
|
||||
|
||||
/* No if setting */
|
||||
if (! if_setting) {
|
||||
printf("af_packet missing a mandatory if setting\n");
|
||||
rc = -EINVAL;
|
||||
goto err_settings;
|
||||
}
|
||||
|
||||
nic->ifname = if_setting->value;
|
||||
snprintf ( device->dev.name, sizeof ( device->dev.name ), "%s",
|
||||
nic->ifname );
|
||||
device->dev.desc.bus_type = BUS_TYPE_TAP;
|
||||
af_packet_update_properties(netdev);
|
||||
if_setting->applied = 1;
|
||||
|
||||
/* Apply rest of the settings */
|
||||
linux_apply_settings(&request->settings, &netdev->settings.settings);
|
||||
|
||||
/* Register network device */
|
||||
if ((rc = register_netdev(netdev)) != 0)
|
||||
goto err_register;
|
||||
|
||||
netdev_link_up(netdev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_settings:
|
||||
unregister_netdev(netdev);
|
||||
err_register:
|
||||
netdev_nullify(netdev);
|
||||
netdev_put(netdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** Remove the device */
|
||||
static void af_packet_nic_remove ( struct linux_device *device )
|
||||
{
|
||||
struct net_device *netdev = linux_get_drvdata(device);
|
||||
unregister_netdev(netdev);
|
||||
netdev_nullify(netdev);
|
||||
netdev_put(netdev);
|
||||
}
|
||||
|
||||
/** AF_PACKET linux_driver */
|
||||
struct linux_driver af_packet_nic_driver __linux_driver = {
|
||||
.name = "af_packet",
|
||||
.probe = af_packet_nic_probe,
|
||||
.remove = af_packet_nic_remove,
|
||||
.can_probe = 1,
|
||||
};
|
@ -1381,7 +1381,7 @@ ath5k_poll(struct net80211_device *dev)
|
||||
unsigned int counter = 1000;
|
||||
|
||||
if (currticks() - sc->last_calib_ticks >
|
||||
ATH5K_CALIB_INTERVAL * ticks_per_sec()) {
|
||||
ATH5K_CALIB_INTERVAL * TICKS_PER_SEC) {
|
||||
ath5k_calibrate(sc);
|
||||
sc->last_calib_ticks = currticks();
|
||||
}
|
||||
|
2
third_party/ipxe/src/drivers/net/forcedeth.c
vendored
2
third_party/ipxe/src/drivers/net/forcedeth.c
vendored
@ -1176,7 +1176,7 @@ nv_mgmt_get_version ( struct forcedeth_private *priv )
|
||||
ioaddr + NvRegTransmitterControl );
|
||||
start = currticks();
|
||||
|
||||
while ( currticks() > start + 5 * ticks_per_sec() ) {
|
||||
while ( currticks() > start + 5 * TICKS_PER_SEC ) {
|
||||
data_ready2 = readl ( ioaddr + NvRegTransmitterControl );
|
||||
if ( ( data_ready & NVREG_XMITCTL_DATA_READY ) !=
|
||||
( data_ready2 & NVREG_XMITCTL_DATA_READY ) ) {
|
||||
|
2
third_party/ipxe/src/drivers/net/intel.c
vendored
2
third_party/ipxe/src/drivers/net/intel.c
vendored
@ -1069,7 +1069,7 @@ static struct pci_device_id intel_nics[] = {
|
||||
PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
|
||||
PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", INTEL_NO_PHY_RST ),
|
||||
PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", INTEL_NO_PHY_RST ),
|
||||
PCI_ROM ( 0x8086, 0x15b7, "i219lm-2", "I219-LM (2)", 0 ),
|
||||
PCI_ROM ( 0x8086, 0x15b7, "i219lm-2", "I219-LM (2)", INTEL_NO_PHY_RST ),
|
||||
PCI_ROM ( 0x8086, 0x15b8, "i219v-2", "I219-V (2)", 0 ),
|
||||
PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
|
||||
PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),
|
||||
|
10
third_party/ipxe/src/drivers/net/thunderx.c
vendored
10
third_party/ipxe/src/drivers/net/thunderx.c
vendored
@ -1146,10 +1146,17 @@ static int txnic_lmac_probe ( struct txnic_lmac *lmac ) {
|
||||
* @v lmac Logical MAC
|
||||
*/
|
||||
static void txnic_lmac_remove ( struct txnic_lmac *lmac ) {
|
||||
uint64_t config;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( lmac->vnic != NULL );
|
||||
|
||||
/* Disable packet receive and transmit */
|
||||
config = readq ( lmac->regs + BGX_CMR_CONFIG );
|
||||
config &= ~( BGX_CMR_CONFIG_DATA_PKT_TX_EN |
|
||||
BGX_CMR_CONFIG_DATA_PKT_RX_EN );
|
||||
writeq ( config, ( lmac->regs + BGX_CMR_CONFIG ) );
|
||||
|
||||
/* Unregister network device */
|
||||
unregister_netdev ( lmac->vnic->netdev );
|
||||
|
||||
@ -1338,9 +1345,6 @@ static void txnic_pf_remove ( struct pci_device *pci ) {
|
||||
/* Remove from list of physical functions */
|
||||
list_del ( &pf->list );
|
||||
|
||||
/* Disable physical function */
|
||||
writeq ( 0, ( pf->regs + TXNIC_PF_CFG ) );
|
||||
|
||||
/* Unmap registers */
|
||||
iounmap ( pf->regs );
|
||||
|
||||
|
90
third_party/ipxe/src/drivers/net/virtio-net.c
vendored
90
third_party/ipxe/src/drivers/net/virtio-net.c
vendored
@ -77,13 +77,8 @@ enum {
|
||||
QUEUE_NB
|
||||
};
|
||||
|
||||
enum {
|
||||
/** Max number of pending rx packets */
|
||||
NUM_RX_BUF = 8,
|
||||
|
||||
/** Max Ethernet frame length, including FCS and VLAN tag */
|
||||
RX_BUF_SIZE = 1522,
|
||||
};
|
||||
/** Max number of pending rx packets */
|
||||
#define NUM_RX_BUF 8
|
||||
|
||||
struct virtnet_nic {
|
||||
/** Base pio register address */
|
||||
@ -104,8 +99,8 @@ struct virtnet_nic {
|
||||
/** Pending rx packet count */
|
||||
unsigned int rx_num_iobufs;
|
||||
|
||||
/** Virtio net packet header, we only need one */
|
||||
struct virtio_net_hdr_modern empty_header;
|
||||
/** Virtio net dummy packet headers */
|
||||
struct virtio_net_hdr_modern empty_header[QUEUE_NB];
|
||||
};
|
||||
|
||||
/** Add an iobuf to a virtqueue
|
||||
@ -120,19 +115,24 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
|
||||
int vq_idx, struct io_buffer *iobuf ) {
|
||||
struct virtnet_nic *virtnet = netdev->priv;
|
||||
struct vring_virtqueue *vq = &virtnet->virtqueue[vq_idx];
|
||||
struct virtio_net_hdr_modern *header = &virtnet->empty_header[vq_idx];
|
||||
unsigned int out = ( vq_idx == TX_INDEX ) ? 2 : 0;
|
||||
unsigned int in = ( vq_idx == TX_INDEX ) ? 0 : 2;
|
||||
size_t header_len = virtnet->virtio_version
|
||||
? sizeof ( virtnet->empty_header )
|
||||
: sizeof ( virtnet->empty_header.legacy );
|
||||
size_t header_len = ( virtnet->virtio_version ?
|
||||
sizeof ( *header ) : sizeof ( header->legacy ) );
|
||||
struct vring_list list[] = {
|
||||
{
|
||||
/* Share a single zeroed virtio net header between all
|
||||
* rx and tx packets. This works because this driver
|
||||
* packets in a ring. This works because this driver
|
||||
* does not use any advanced features so none of the
|
||||
* header fields get used.
|
||||
*
|
||||
* Some host implementations (notably Google Compute
|
||||
* Platform) are known to unconditionally write back
|
||||
* to header->flags for received packets. Work around
|
||||
* this by using separate RX and TX headers.
|
||||
*/
|
||||
.addr = ( char* ) &virtnet->empty_header,
|
||||
.addr = ( char* ) header,
|
||||
.length = header_len,
|
||||
},
|
||||
{
|
||||
@ -155,12 +155,13 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
|
||||
*/
|
||||
static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
|
||||
struct virtnet_nic *virtnet = netdev->priv;
|
||||
size_t len = ( netdev->max_pkt_len + 4 /* VLAN */ );
|
||||
|
||||
while ( virtnet->rx_num_iobufs < NUM_RX_BUF ) {
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
/* Try to allocate a buffer, stop for now if out of memory */
|
||||
iobuf = alloc_iob ( RX_BUF_SIZE );
|
||||
iobuf = alloc_iob ( len );
|
||||
if ( ! iobuf )
|
||||
break;
|
||||
|
||||
@ -168,13 +169,30 @@ static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
|
||||
list_add ( &iobuf->list, &virtnet->rx_iobufs );
|
||||
|
||||
/* Mark packet length until we know the actual size */
|
||||
iob_put ( iobuf, RX_BUF_SIZE );
|
||||
iob_put ( iobuf, len );
|
||||
|
||||
virtnet_enqueue_iob ( netdev, RX_INDEX, iobuf );
|
||||
virtnet->rx_num_iobufs++;
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper to free all virtqueue memory
|
||||
*
|
||||
* @v netdev Network device
|
||||
*/
|
||||
static void virtnet_free_virtqueues ( struct net_device *netdev ) {
|
||||
struct virtnet_nic *virtnet = netdev->priv;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < QUEUE_NB; i++ ) {
|
||||
virtio_pci_unmap_capability ( &virtnet->virtqueue[i].notification );
|
||||
vp_free_vq ( &virtnet->virtqueue[i] );
|
||||
}
|
||||
|
||||
free ( virtnet->virtqueue );
|
||||
virtnet->virtqueue = NULL;
|
||||
}
|
||||
|
||||
/** Open network device, legacy virtio 0.9.5
|
||||
*
|
||||
* @v netdev Network device
|
||||
@ -200,8 +218,7 @@ static int virtnet_open_legacy ( struct net_device *netdev ) {
|
||||
if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i] ) == -1 ) {
|
||||
DBGC ( virtnet, "VIRTIO-NET %p cannot register queue %d\n",
|
||||
virtnet, i );
|
||||
free ( virtnet->virtqueue );
|
||||
virtnet->virtqueue = NULL;
|
||||
virtnet_free_virtqueues ( netdev );
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
@ -216,7 +233,8 @@ static int virtnet_open_legacy ( struct net_device *netdev ) {
|
||||
|
||||
/* Driver is ready */
|
||||
features = vp_get_features ( ioaddr );
|
||||
vp_set_features ( ioaddr, features & ( 1 << VIRTIO_NET_F_MAC ) );
|
||||
vp_set_features ( ioaddr, features & ( ( 1 << VIRTIO_NET_F_MAC ) |
|
||||
( 1 << VIRTIO_NET_F_MTU ) ) );
|
||||
vp_set_status ( ioaddr, VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK );
|
||||
return 0;
|
||||
}
|
||||
@ -239,6 +257,7 @@ static int virtnet_open_modern ( struct net_device *netdev ) {
|
||||
}
|
||||
vpm_set_features ( &virtnet->vdev, features & (
|
||||
( 1ULL << VIRTIO_NET_F_MAC ) |
|
||||
( 1ULL << VIRTIO_NET_F_MTU ) |
|
||||
( 1ULL << VIRTIO_F_VERSION_1 ) |
|
||||
( 1ULL << VIRTIO_F_ANY_LAYOUT ) ) );
|
||||
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FEATURES_OK );
|
||||
@ -263,8 +282,7 @@ static int virtnet_open_modern ( struct net_device *netdev ) {
|
||||
if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue ) ) {
|
||||
DBGC ( virtnet, "VIRTIO-NET %p cannot register queues\n",
|
||||
virtnet );
|
||||
free ( virtnet->virtqueue );
|
||||
virtnet->virtqueue = NULL;
|
||||
virtnet_free_virtqueues ( netdev );
|
||||
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
|
||||
return -ENOENT;
|
||||
}
|
||||
@ -304,7 +322,6 @@ static void virtnet_close ( struct net_device *netdev ) {
|
||||
struct virtnet_nic *virtnet = netdev->priv;
|
||||
struct io_buffer *iobuf;
|
||||
struct io_buffer *next_iobuf;
|
||||
int i;
|
||||
|
||||
if ( virtnet->virtio_version ) {
|
||||
vpm_reset ( &virtnet->vdev );
|
||||
@ -313,12 +330,7 @@ static void virtnet_close ( struct net_device *netdev ) {
|
||||
}
|
||||
|
||||
/* Virtqueues can be freed now that NIC is reset */
|
||||
for ( i = 0 ; i < QUEUE_NB ; i++ ) {
|
||||
virtio_pci_unmap_capability ( &virtnet->virtqueue[i].notification );
|
||||
}
|
||||
|
||||
free ( virtnet->virtqueue );
|
||||
virtnet->virtqueue = NULL;
|
||||
virtnet_free_virtqueues ( netdev );
|
||||
|
||||
/* Free rx iobufs */
|
||||
list_for_each_entry_safe ( iobuf, next_iobuf, &virtnet->rx_iobufs, list ) {
|
||||
@ -375,7 +387,7 @@ static void virtnet_process_rx_packets ( struct net_device *netdev ) {
|
||||
virtnet->rx_num_iobufs--;
|
||||
|
||||
/* Update iobuf length */
|
||||
iob_unput ( iobuf, RX_BUF_SIZE );
|
||||
iob_unput ( iobuf, iob_len ( iobuf ) );
|
||||
iob_put ( iobuf, len - sizeof ( struct virtio_net_hdr ) );
|
||||
|
||||
DBGC2 ( virtnet, "VIRTIO-NET %p rx complete iobuf %p len %zd\n",
|
||||
@ -447,6 +459,7 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
|
||||
struct net_device *netdev;
|
||||
struct virtnet_nic *virtnet;
|
||||
u32 features;
|
||||
u16 mtu;
|
||||
int rc;
|
||||
|
||||
/* Allocate and hook up net device */
|
||||
@ -466,7 +479,7 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
|
||||
adjust_pci_device ( pci );
|
||||
vp_reset ( ioaddr );
|
||||
|
||||
/* Load MAC address */
|
||||
/* Load MAC address and MTU */
|
||||
features = vp_get_features ( ioaddr );
|
||||
if ( features & ( 1 << VIRTIO_NET_F_MAC ) ) {
|
||||
vp_get ( ioaddr, offsetof ( struct virtio_net_config, mac ),
|
||||
@ -474,6 +487,12 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
|
||||
DBGC ( virtnet, "VIRTIO-NET %p mac=%s\n", virtnet,
|
||||
eth_ntoa ( netdev->hw_addr ) );
|
||||
}
|
||||
if ( features & ( 1ULL << VIRTIO_NET_F_MTU ) ) {
|
||||
vp_get ( ioaddr, offsetof ( struct virtio_net_config, mtu ),
|
||||
&mtu, sizeof ( mtu ) );
|
||||
DBGC ( virtnet, "VIRTIO-NET %p mtu=%d\n", virtnet, mtu );
|
||||
netdev->max_pkt_len = ( mtu + ETH_HLEN );
|
||||
}
|
||||
|
||||
/* Register network device */
|
||||
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
||||
@ -503,6 +522,7 @@ static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
|
||||
struct net_device *netdev;
|
||||
struct virtnet_nic *virtnet;
|
||||
u64 features;
|
||||
u16 mtu;
|
||||
int rc, common, isr, notify, config, device;
|
||||
|
||||
common = virtio_pci_find_capability ( pci, VIRTIO_PCI_CAP_COMMON_CFG );
|
||||
@ -569,7 +589,7 @@ static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
|
||||
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE );
|
||||
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_DRIVER );
|
||||
|
||||
/* Load MAC address */
|
||||
/* Load MAC address and MTU */
|
||||
if ( device ) {
|
||||
features = vpm_get_features ( &virtnet->vdev );
|
||||
if ( features & ( 1ULL << VIRTIO_NET_F_MAC ) ) {
|
||||
@ -579,6 +599,14 @@ static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
|
||||
DBGC ( virtnet, "VIRTIO-NET %p mac=%s\n", virtnet,
|
||||
eth_ntoa ( netdev->hw_addr ) );
|
||||
}
|
||||
if ( features & ( 1ULL << VIRTIO_NET_F_MTU ) ) {
|
||||
vpm_get ( &virtnet->vdev,
|
||||
offsetof ( struct virtio_net_config, mtu ),
|
||||
&mtu, sizeof ( mtu ) );
|
||||
DBGC ( virtnet, "VIRTIO-NET %p mtu=%d\n", virtnet,
|
||||
mtu );
|
||||
netdev->max_pkt_len = ( mtu + ETH_HLEN );
|
||||
}
|
||||
}
|
||||
|
||||
/* We need a valid MAC address */
|
||||
|
10
third_party/ipxe/src/drivers/net/virtio-net.h
vendored
10
third_party/ipxe/src/drivers/net/virtio-net.h
vendored
@ -4,6 +4,7 @@
|
||||
/* The feature bitmap for virtio net */
|
||||
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
|
||||
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
|
||||
#define VIRTIO_NET_F_MTU 3 /* Initial MTU advice */
|
||||
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
|
||||
#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */
|
||||
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
|
||||
@ -25,6 +26,15 @@ struct virtio_net_config
|
||||
{
|
||||
/* The config defining mac address (if VIRTIO_NET_F_MAC) */
|
||||
u8 mac[6];
|
||||
/* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
|
||||
u16 status;
|
||||
/* Maximum number of each of transmit and receive queues;
|
||||
* see VIRTIO_NET_F_MQ and VIRTIO_NET_CTRL_MQ.
|
||||
* Legal values are between 1 and 0x8000
|
||||
*/
|
||||
u16 max_virtqueue_pairs;
|
||||
/* Default maximum transmit unit advice */
|
||||
u16 mtu;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* This is the first element of the scatter-gather list. If you don't
|
||||
|
304
third_party/ipxe/src/hci/commands/cert_cmd.c
vendored
Normal file
304
third_party/ipxe/src/hci/commands/cert_cmd.c
vendored
Normal file
@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <ipxe/x509.h>
|
||||
#include <ipxe/certstore.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/command.h>
|
||||
#include <ipxe/parseopt.h>
|
||||
#include <usr/imgmgmt.h>
|
||||
#include <usr/certmgmt.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Certificate management commands
|
||||
*
|
||||
*/
|
||||
|
||||
/** "cert<xxx>" options */
|
||||
struct cert_options {
|
||||
/** Certificate subject name */
|
||||
char *name;
|
||||
/** Keep certificate file after parsing */
|
||||
int keep;
|
||||
};
|
||||
|
||||
/** "cert<xxx>" option list */
|
||||
static union {
|
||||
/* "certstore" takes both options */
|
||||
struct option_descriptor certstore[2];
|
||||
/* "certstat" takes only --subject */
|
||||
struct option_descriptor certstat[1];
|
||||
/* "certfree" takes only --subject */
|
||||
struct option_descriptor certfree[1];
|
||||
} opts = {
|
||||
.certstore = {
|
||||
OPTION_DESC ( "subject", 's', required_argument,
|
||||
struct cert_options, name, parse_string ),
|
||||
OPTION_DESC ( "keep", 'k', no_argument,
|
||||
struct cert_options, keep, parse_flag ),
|
||||
},
|
||||
};
|
||||
|
||||
/** A "cert<xxx>" command descriptor */
|
||||
struct cert_command_descriptor {
|
||||
/** Command descriptor */
|
||||
struct command_descriptor cmd;
|
||||
/** Payload
|
||||
*
|
||||
* @v cert X.509 certificate
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * payload ) ( struct x509_certificate *cert );
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct "cert<xxx>" command descriptor
|
||||
*
|
||||
* @v _struct Options structure type
|
||||
* @v _options Option descriptor array
|
||||
* @v _min_args Minimum number of non-option arguments
|
||||
* @v _max_args Maximum number of non-option arguments
|
||||
* @v _usage Command usage
|
||||
* @v _payload Payload method
|
||||
* @ret _command Command descriptor
|
||||
*/
|
||||
#define CERT_COMMAND_DESC( _struct, _options, _min_args, _max_args, \
|
||||
_usage, _payload ) \
|
||||
{ \
|
||||
.cmd = COMMAND_DESC ( _struct, _options, _min_args, \
|
||||
_max_args, _usage ), \
|
||||
.payload = _payload, \
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute "cert<xxx>" command
|
||||
*
|
||||
* @v argc Argument count
|
||||
* @v argv Argument list
|
||||
* @v certcmd Command descriptor
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int cert_exec ( int argc, char **argv,
|
||||
struct cert_command_descriptor *certcmd ) {
|
||||
struct command_descriptor *cmd = &certcmd->cmd;
|
||||
struct cert_options opts;
|
||||
struct image *image = NULL;
|
||||
struct x509_certificate *cert;
|
||||
struct x509_certificate *tmp;
|
||||
unsigned int count = 0;
|
||||
size_t offset = 0;
|
||||
int next;
|
||||
int rc;
|
||||
|
||||
/* Parse options */
|
||||
if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 )
|
||||
goto err_parse;
|
||||
|
||||
/* Acquire image, if applicable */
|
||||
if ( ( optind < argc ) &&
|
||||
( ( rc = imgacquire ( argv[optind], 0, &image ) ) != 0 ) )
|
||||
goto err_acquire;
|
||||
|
||||
/* Get first entry in certificate store */
|
||||
tmp = list_first_entry ( &certstore.links, struct x509_certificate,
|
||||
store.list );
|
||||
|
||||
/* Iterate over certificates */
|
||||
while ( 1 ) {
|
||||
|
||||
/* Get next certificate from image or store as applicable */
|
||||
if ( image ) {
|
||||
|
||||
/* Get next certificate from image */
|
||||
if ( offset >= image->len )
|
||||
break;
|
||||
next = image_x509 ( image, offset, &cert );
|
||||
if ( next < 0 ) {
|
||||
rc = next;
|
||||
printf ( "Could not parse certificate: %s\n",
|
||||
strerror ( rc ) );
|
||||
goto err_x509;
|
||||
}
|
||||
offset = next;
|
||||
|
||||
} else {
|
||||
|
||||
/* Get next certificate from store */
|
||||
cert = tmp;
|
||||
if ( ! cert )
|
||||
break;
|
||||
tmp = list_next_entry ( tmp, &certstore.links,
|
||||
store.list );
|
||||
x509_get ( cert );
|
||||
}
|
||||
|
||||
/* Skip non-matching names, if a name was specified */
|
||||
if ( opts.name && ( x509_check_name ( cert, opts.name ) != 0 )){
|
||||
x509_put ( cert );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Execute payload */
|
||||
if ( ( rc = certcmd->payload ( cert ) ) != 0 ) {
|
||||
x509_put ( cert );
|
||||
goto err_payload;
|
||||
}
|
||||
|
||||
/* Count number of certificates processed */
|
||||
count++;
|
||||
|
||||
/* Drop reference to certificate */
|
||||
x509_put ( cert );
|
||||
}
|
||||
|
||||
/* Fail if a name was specified and no matching certificates
|
||||
* were found.
|
||||
*/
|
||||
if ( opts.name && ( count == 0 ) ) {
|
||||
printf ( "\"%s\" : no such certificate\n", opts.name );
|
||||
rc = -ENOENT;
|
||||
goto err_none;
|
||||
}
|
||||
|
||||
err_none:
|
||||
err_payload:
|
||||
err_x509:
|
||||
if ( image && ( ! opts.keep ) )
|
||||
unregister_image ( image );
|
||||
err_acquire:
|
||||
err_parse:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* "certstat" payload
|
||||
*
|
||||
* @v cert X.509 certificate
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int certstat_payload ( struct x509_certificate *cert ) {
|
||||
|
||||
certstat ( cert );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** "certstat" command descriptor */
|
||||
static struct cert_command_descriptor certstat_cmd =
|
||||
CERT_COMMAND_DESC ( struct cert_options, opts.certstat, 0, 0, NULL,
|
||||
certstat_payload );
|
||||
|
||||
/**
|
||||
* The "certstat" command
|
||||
*
|
||||
* @v argc Argument count
|
||||
* @v argv Argument list
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int certstat_exec ( int argc, char **argv ) {
|
||||
|
||||
return cert_exec ( argc, argv, &certstat_cmd );
|
||||
}
|
||||
|
||||
/**
|
||||
* "certstore" payload
|
||||
*
|
||||
* @v cert X.509 certificate
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int certstore_payload ( struct x509_certificate *cert ) {
|
||||
|
||||
/* Mark certificate as having been added explicitly */
|
||||
cert->flags |= X509_FL_EXPLICIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** "certstore" command descriptor */
|
||||
static struct cert_command_descriptor certstore_cmd =
|
||||
CERT_COMMAND_DESC ( struct cert_options, opts.certstore, 0, 1,
|
||||
"[<uri|image>]", certstore_payload );
|
||||
|
||||
/**
|
||||
* The "certstore" command
|
||||
*
|
||||
* @v argc Argument count
|
||||
* @v argv Argument list
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int certstore_exec ( int argc, char **argv ) {
|
||||
|
||||
return cert_exec ( argc, argv, &certstore_cmd );
|
||||
}
|
||||
|
||||
/**
|
||||
* "certfree" payload
|
||||
*
|
||||
* @v cert X.509 certificate
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int certfree_payload ( struct x509_certificate *cert ) {
|
||||
|
||||
/* Remove from certificate store */
|
||||
certstore_del ( cert );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** "certfree" command descriptor */
|
||||
static struct cert_command_descriptor certfree_cmd =
|
||||
CERT_COMMAND_DESC ( struct cert_options, opts.certfree, 0, 0, NULL,
|
||||
certfree_payload );
|
||||
|
||||
/**
|
||||
* The "certfree" command
|
||||
*
|
||||
* @v argc Argument count
|
||||
* @v argv Argument list
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int certfree_exec ( int argc, char **argv ) {
|
||||
|
||||
return cert_exec ( argc, argv, &certfree_cmd );
|
||||
}
|
||||
|
||||
/** Certificate management commands */
|
||||
struct command certmgmt_commands[] __command = {
|
||||
{
|
||||
.name = "certstat",
|
||||
.exec = certstat_exec,
|
||||
},
|
||||
{
|
||||
.name = "certstore",
|
||||
.exec = certstore_exec,
|
||||
},
|
||||
{
|
||||
.name = "certfree",
|
||||
.exec = certfree_exec,
|
||||
},
|
||||
};
|
2
third_party/ipxe/src/hci/commands/time_cmd.c
vendored
2
third_party/ipxe/src/hci/commands/time_cmd.c
vendored
@ -68,7 +68,7 @@ static int time_exec ( int argc, char **argv ) {
|
||||
start = currticks();
|
||||
rc = execv ( argv[1], argv + 1 );
|
||||
elapsed = ( currticks() - start );
|
||||
decisecs = ( 10 * elapsed / ticks_per_sec() );
|
||||
decisecs = ( 10 * elapsed / TICKS_PER_SEC );
|
||||
|
||||
printf ( "%s: %d.%ds\n", argv[0],
|
||||
( decisecs / 10 ), ( decisecs % 10 ) );
|
||||
|
@ -17,5 +17,6 @@ extern struct x509_chain certstore;
|
||||
extern struct x509_certificate * certstore_find ( struct asn1_cursor *raw );
|
||||
extern struct x509_certificate * certstore_find_key ( struct asn1_cursor *key );
|
||||
extern void certstore_add ( struct x509_certificate *cert );
|
||||
extern void certstore_del ( struct x509_certificate *cert );
|
||||
|
||||
#endif /* _IPXE_CERTSTORE_H */
|
||||
|
3
third_party/ipxe/src/include/ipxe/dhcp.h
vendored
3
third_party/ipxe/src/include/ipxe/dhcp.h
vendored
@ -83,6 +83,9 @@ struct dhcp_packet;
|
||||
/** Root path */
|
||||
#define DHCP_ROOT_PATH 17
|
||||
|
||||
/** Maximum transmission unit */
|
||||
#define DHCP_MTU 26
|
||||
|
||||
/** Vendor encapsulated options */
|
||||
#define DHCP_VENDOR_ENCAP 43
|
||||
|
||||
|
@ -34,7 +34,7 @@ FILE_LICENCE ( BSD3 );
|
||||
|
||||
#if _MSC_EXTENSIONS
|
||||
//
|
||||
// use Microsoft* C complier dependent integer width types
|
||||
// use Microsoft* C compiler dependent integer width types
|
||||
//
|
||||
typedef unsigned __int64 UINT64;
|
||||
typedef __int64 INT64;
|
||||
|
@ -30,9 +30,16 @@ FILE_LICENCE ( BSD3 );
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
//
|
||||
// RVCT does not support the __builtin_unreachable() macro
|
||||
//
|
||||
#ifdef __ARMCC_VERSION
|
||||
#define UNREACHABLE()
|
||||
#endif
|
||||
|
||||
#if _MSC_EXTENSIONS
|
||||
//
|
||||
// use Microsoft* C complier dependent integer width types
|
||||
// use Microsoft* C compiler dependent integer width types
|
||||
//
|
||||
typedef unsigned __int64 UINT64;
|
||||
typedef __int64 INT64;
|
||||
|
151
third_party/ipxe/src/include/ipxe/efi/Base.h
vendored
151
third_party/ipxe/src/include/ipxe/efi/Base.h
vendored
@ -86,6 +86,117 @@ VERIFY_SIZE_OF (CHAR16, 2);
|
||||
#define GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
#endif
|
||||
|
||||
//
|
||||
// Should be used in combination with NORETURN to avoid 'noreturn' returns
|
||||
// warnings.
|
||||
//
|
||||
#ifndef UNREACHABLE
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)
|
||||
///
|
||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||
/// up to the compiler to remove any code past that point.
|
||||
/// Not implemented by GCC 4.4 or earlier.
|
||||
///
|
||||
#define UNREACHABLE() __builtin_unreachable ()
|
||||
#elif defined (__has_feature)
|
||||
#if __has_builtin (__builtin_unreachable)
|
||||
///
|
||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||
/// up to the compiler to remove any code past that point.
|
||||
///
|
||||
#define UNREACHABLE() __builtin_unreachable ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UNREACHABLE
|
||||
///
|
||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||
/// up to the compiler to remove any code past that point.
|
||||
///
|
||||
#define UNREACHABLE()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Signaling compilers and analyzers that a certain function cannot return may
|
||||
// remove all following code and thus lead to better optimization and less
|
||||
// false positives.
|
||||
//
|
||||
#ifndef NORETURN
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
///
|
||||
/// Signal compilers and analyzers that the function cannot return.
|
||||
/// It is up to the compiler to remove any code past a call to functions
|
||||
/// flagged with this attribute.
|
||||
///
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#elif defined(_MSC_EXTENSIONS) && !defined(MDE_CPU_EBC)
|
||||
///
|
||||
/// Signal compilers and analyzers that the function cannot return.
|
||||
/// It is up to the compiler to remove any code past a call to functions
|
||||
/// flagged with this attribute.
|
||||
///
|
||||
#define NORETURN __declspec(noreturn)
|
||||
#else
|
||||
///
|
||||
/// Signal compilers and analyzers that the function cannot return.
|
||||
/// It is up to the compiler to remove any code past a call to functions
|
||||
/// flagged with this attribute.
|
||||
///
|
||||
#define NORETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Should be used in combination with ANALYZER_NORETURN to avoid 'noreturn'
|
||||
// returns warnings.
|
||||
//
|
||||
#ifndef ANALYZER_UNREACHABLE
|
||||
#ifdef __clang_analyzer__
|
||||
#if __has_builtin (__builtin_unreachable)
|
||||
///
|
||||
/// Signal the analyzer that this call is not reachable.
|
||||
/// This excludes compilers.
|
||||
///
|
||||
#define ANALYZER_UNREACHABLE() __builtin_unreachable ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ANALYZER_UNREACHABLE
|
||||
///
|
||||
/// Signal the analyzer that this call is not reachable.
|
||||
/// This excludes compilers.
|
||||
///
|
||||
#define ANALYZER_UNREACHABLE()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Static Analyzers may issue errors about potential NULL-dereferences when
|
||||
// dereferencing a pointer, that has been checked before, outside of a
|
||||
// NULL-check. This may lead to false positives, such as when using ASSERT()
|
||||
// for verification.
|
||||
//
|
||||
#ifndef ANALYZER_NORETURN
|
||||
#ifdef __has_feature
|
||||
#if __has_feature (attribute_analyzer_noreturn)
|
||||
///
|
||||
/// Signal analyzers that the function cannot return.
|
||||
/// This excludes compilers.
|
||||
///
|
||||
#define ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ANALYZER_NORETURN
|
||||
///
|
||||
/// Signal the analyzer that the function cannot return.
|
||||
/// This excludes compilers.
|
||||
///
|
||||
#define ANALYZER_NORETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// For symbol name in assembly code, an extra "_" is sometimes necessary
|
||||
//
|
||||
@ -193,7 +304,7 @@ struct _LIST_ENTRY {
|
||||
|
||||
//
|
||||
// UEFI specification claims 1 and 0. We are concerned about the
|
||||
// complier portability so we did it this way.
|
||||
// compiler portability so we did it this way.
|
||||
//
|
||||
|
||||
///
|
||||
@ -480,7 +591,31 @@ struct _LIST_ENTRY {
|
||||
|
||||
#define VA_COPY(Dest, Start) __va_copy (Dest, Start)
|
||||
|
||||
#elif defined(__GNUC__) && !defined(NO_BUILTIN_VA_FUNCS)
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS)
|
||||
//
|
||||
// X64 only. Use MS ABI version of GCC built-in macros for variable argument lists.
|
||||
//
|
||||
///
|
||||
/// Both GCC and LLVM 3.8 for X64 support new variable argument intrinsics for Microsoft ABI
|
||||
///
|
||||
|
||||
///
|
||||
/// Variable used to traverse the list of arguments. This type can vary by
|
||||
/// implementation and could be an array or structure.
|
||||
///
|
||||
typedef __builtin_ms_va_list VA_LIST;
|
||||
|
||||
#define VA_START(Marker, Parameter) __builtin_ms_va_start (Marker, Parameter)
|
||||
|
||||
#define VA_ARG(Marker, TYPE) ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))
|
||||
|
||||
#define VA_END(Marker) __builtin_ms_va_end (Marker)
|
||||
|
||||
#define VA_COPY(Dest, Start) __builtin_ms_va_copy (Dest, Start)
|
||||
|
||||
#else
|
||||
//
|
||||
// Use GCC built-in macros for variable argument lists.
|
||||
//
|
||||
@ -499,6 +634,8 @@ typedef __builtin_va_list VA_LIST;
|
||||
|
||||
#define VA_COPY(Dest, Start) __builtin_va_copy (Dest, Start)
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
///
|
||||
/// Variable used to traverse the list of arguments. This type can vary by
|
||||
@ -1038,7 +1175,7 @@ typedef UINTN RETURN_STATUS;
|
||||
#if defined(_MSC_EXTENSIONS) && !defined (__INTEL_COMPILER) && !defined (MDE_CPU_EBC)
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
/**
|
||||
Get the return address of the calling funcation.
|
||||
Get the return address of the calling function.
|
||||
|
||||
Based on intrinsic function _ReturnAddress that provides the address of
|
||||
the instruction in the calling function that will be executed after
|
||||
@ -1046,27 +1183,27 @@ typedef UINTN RETURN_STATUS;
|
||||
|
||||
@param L Return Level.
|
||||
|
||||
@return The return address of the calling funcation or 0 if L != 0.
|
||||
@return The return address of the calling function or 0 if L != 0.
|
||||
|
||||
**/
|
||||
#define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0)
|
||||
#elif defined(__GNUC__)
|
||||
void * __builtin_return_address (unsigned int level);
|
||||
/**
|
||||
Get the return address of the calling funcation.
|
||||
Get the return address of the calling function.
|
||||
|
||||
Based on built-in Function __builtin_return_address that returns
|
||||
the return address of the current function, or of one of its callers.
|
||||
|
||||
@param L Return Level.
|
||||
|
||||
@return The return address of the calling funcation.
|
||||
@return The return address of the calling function.
|
||||
|
||||
**/
|
||||
#define RETURN_ADDRESS(L) __builtin_return_address (L)
|
||||
#else
|
||||
/**
|
||||
Get the return address of the calling funcation.
|
||||
Get the return address of the calling function.
|
||||
|
||||
@param L Return Level.
|
||||
|
||||
|
@ -81,7 +81,7 @@ FILE_LICENCE ( BSD3 );
|
||||
#pragma warning ( disable : 4057 )
|
||||
|
||||
//
|
||||
// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning
|
||||
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
|
||||
//
|
||||
#pragma warning ( disable : 4127 )
|
||||
|
||||
@ -121,7 +121,7 @@ FILE_LICENCE ( BSD3 );
|
||||
#if defined(_MSC_EXTENSIONS)
|
||||
|
||||
//
|
||||
// use Microsoft C complier dependent integer width types
|
||||
// use Microsoft C compiler dependent integer width types
|
||||
//
|
||||
|
||||
///
|
||||
|
@ -5,11 +5,10 @@
|
||||
PCI Local Bus Specification, 2.2
|
||||
PCI-to-PCI Bridge Architecture Specification, Revision 1.2
|
||||
PC Card Standard, 8.0
|
||||
PCI Power Management Interface Specifiction, Revision 1.2
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2014 - 2105, Hewlett-Packard Development Company, L.P.<BR>
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2014 - 2015, Hewlett-Packard Development Company, L.P.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -638,6 +637,7 @@ typedef union {
|
||||
#define EFI_PCI_CAPABILITY_ID_SLOTID 0x04
|
||||
#define EFI_PCI_CAPABILITY_ID_MSI 0x05
|
||||
#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06
|
||||
#define EFI_PCI_CAPABILITY_ID_SHPC 0x0C
|
||||
|
||||
///
|
||||
/// Capabilities List Header
|
||||
@ -648,18 +648,6 @@ typedef struct {
|
||||
UINT8 NextItemPtr;
|
||||
} EFI_PCI_CAPABILITY_HDR;
|
||||
|
||||
///
|
||||
/// Power Management Register Block Definition
|
||||
/// Section 3.2, PCI Power Management Interface Specifiction, Revision 1.2
|
||||
///
|
||||
typedef struct {
|
||||
EFI_PCI_CAPABILITY_HDR Hdr;
|
||||
UINT16 PMC;
|
||||
UINT16 PMCSR;
|
||||
UINT8 BridgeExtention;
|
||||
UINT8 Data;
|
||||
} EFI_PCI_CAPABILITY_PMI;
|
||||
|
||||
///
|
||||
/// PMC - Power Management Capabilities
|
||||
/// Section 3.2.3, PCI Power Management Interface Specifiction, Revision 1.2
|
||||
@ -668,7 +656,7 @@ typedef union {
|
||||
struct {
|
||||
UINT16 Version : 3;
|
||||
UINT16 PmeClock : 1;
|
||||
UINT16 : 1;
|
||||
UINT16 Reserved : 1;
|
||||
UINT16 DeviceSpecificInitialization : 1;
|
||||
UINT16 AuxCurrent : 3;
|
||||
UINT16 D1Support : 1;
|
||||
@ -687,7 +675,9 @@ typedef union {
|
||||
typedef union {
|
||||
struct {
|
||||
UINT16 PowerState : 2;
|
||||
UINT16 : 6;
|
||||
UINT16 ReservedForPciExpress : 1;
|
||||
UINT16 NoSoftReset : 1;
|
||||
UINT16 Reserved : 4;
|
||||
UINT16 PmeEnable : 1;
|
||||
UINT16 DataSelect : 4;
|
||||
UINT16 DataScale : 2;
|
||||
@ -696,6 +686,36 @@ typedef union {
|
||||
UINT16 Data;
|
||||
} EFI_PCI_PMCSR;
|
||||
|
||||
#define PCI_POWER_STATE_D0 0
|
||||
#define PCI_POWER_STATE_D1 1
|
||||
#define PCI_POWER_STATE_D2 2
|
||||
#define PCI_POWER_STATE_D3_HOT 3
|
||||
|
||||
///
|
||||
/// PMCSR_BSE - PMCSR PCI-to-PCI Bridge Support Extensions
|
||||
/// Section 3.2.5, PCI Power Management Interface Specifiction, Revision 1.2
|
||||
///
|
||||
typedef union {
|
||||
struct {
|
||||
UINT8 Reserved : 6;
|
||||
UINT8 B2B3 : 1;
|
||||
UINT8 BusPowerClockControl : 1;
|
||||
} Bits;
|
||||
UINT8 Uint8;
|
||||
} EFI_PCI_PMCSR_BSE;
|
||||
|
||||
///
|
||||
/// Power Management Register Block Definition
|
||||
/// Section 3.2, PCI Power Management Interface Specifiction, Revision 1.2
|
||||
///
|
||||
typedef struct {
|
||||
EFI_PCI_CAPABILITY_HDR Hdr;
|
||||
EFI_PCI_PMC PMC;
|
||||
EFI_PCI_PMCSR PMCSR;
|
||||
EFI_PCI_PMCSR_BSE BridgeExtention;
|
||||
UINT8 Data;
|
||||
} EFI_PCI_CAPABILITY_PMI;
|
||||
|
||||
///
|
||||
/// A.G.P Capability
|
||||
/// Section 6.1.4, Accelerated Graphics Port Interface Specification, Revision 1.0
|
||||
|
@ -2,7 +2,7 @@
|
||||
Provides string functions, linked list functions, math functions, synchronization
|
||||
functions, file path functions, and CPU architecture-specific functions.
|
||||
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
@ -189,6 +189,8 @@ typedef struct {
|
||||
/**
|
||||
Returns the length of a Null-terminated Unicode string.
|
||||
|
||||
This function is similar as strlen_s defined in C11.
|
||||
|
||||
If String is not aligned on a 16-bit boundary, then ASSERT().
|
||||
|
||||
@param String A pointer to a Null-terminated Unicode string.
|
||||
@ -211,10 +213,14 @@ StrnLenS (
|
||||
Copies the string pointed to by Source (including the terminating null char)
|
||||
to the array pointed to by Destination.
|
||||
|
||||
This function is similar as strcpy_s defined in C11.
|
||||
|
||||
If Destination is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If Source is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Unicode string.
|
||||
@param DestMax The maximum number of Destination Unicode
|
||||
char, including terminating null char.
|
||||
@ -243,10 +249,14 @@ StrCpyS (
|
||||
Source to the array pointed to by Destination. If no null char is copied from
|
||||
Source, then Destination[Length] is always set to null.
|
||||
|
||||
This function is similar as strncpy_s defined in C11.
|
||||
|
||||
If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Unicode string.
|
||||
@param DestMax The maximum number of Destination Unicode
|
||||
char, including terminating null char.
|
||||
@ -277,10 +287,14 @@ StrnCpyS (
|
||||
Appends a copy of the string pointed to by Source (including the terminating
|
||||
null char) to the end of the string pointed to by Destination.
|
||||
|
||||
This function is similar as strcat_s defined in C11.
|
||||
|
||||
If Destination is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If Source is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Unicode string.
|
||||
@param DestMax The maximum number of Destination Unicode
|
||||
char, including terminating null char.
|
||||
@ -313,10 +327,14 @@ StrCatS (
|
||||
copied from Source, then Destination[StrLen(Destination) + Length] is always
|
||||
set to null.
|
||||
|
||||
This function is similar as strncat_s defined in C11.
|
||||
|
||||
If Destination is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If Source is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Unicode string.
|
||||
@param DestMax The maximum number of Destination Unicode
|
||||
char, including terminating null char.
|
||||
@ -348,6 +366,8 @@ StrnCatS (
|
||||
/**
|
||||
Returns the length of a Null-terminated Ascii string.
|
||||
|
||||
This function is similar as strlen_s defined in C11.
|
||||
|
||||
@param String A pointer to a Null-terminated Ascii string.
|
||||
@param MaxSize The maximum number of Destination Ascii
|
||||
char, including terminating null char.
|
||||
@ -368,8 +388,12 @@ AsciiStrnLenS (
|
||||
Copies the string pointed to by Source (including the terminating null char)
|
||||
to the array pointed to by Destination.
|
||||
|
||||
This function is similar as strcpy_s defined in C11.
|
||||
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Ascii string.
|
||||
@param DestMax The maximum number of Destination Ascii
|
||||
char, including terminating null char.
|
||||
@ -398,8 +422,12 @@ AsciiStrCpyS (
|
||||
Source to the array pointed to by Destination. If no null char is copied from
|
||||
Source, then Destination[Length] is always set to null.
|
||||
|
||||
This function is similar as strncpy_s defined in C11.
|
||||
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Ascii string.
|
||||
@param DestMax The maximum number of Destination Ascii
|
||||
char, including terminating null char.
|
||||
@ -430,8 +458,12 @@ AsciiStrnCpyS (
|
||||
Appends a copy of the string pointed to by Source (including the terminating
|
||||
null char) to the end of the string pointed to by Destination.
|
||||
|
||||
This function is similar as strcat_s defined in C11.
|
||||
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Ascii string.
|
||||
@param DestMax The maximum number of Destination Ascii
|
||||
char, including terminating null char.
|
||||
@ -464,8 +496,12 @@ AsciiStrCatS (
|
||||
copied from Source, then Destination[StrLen(Destination) + Length] is always
|
||||
set to null.
|
||||
|
||||
This function is similar as strncat_s defined in C11.
|
||||
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Destination A pointer to a Null-terminated Ascii string.
|
||||
@param DestMax The maximum number of Destination Ascii
|
||||
char, including terminating null char.
|
||||
@ -986,7 +1022,11 @@ StrHexToUint64 (
|
||||
IN CONST CHAR16 *String
|
||||
);
|
||||
|
||||
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
||||
|
||||
/**
|
||||
[ATTENTION] This function is deprecated for security reason.
|
||||
|
||||
Convert a Null-terminated Unicode string to a Null-terminated
|
||||
ASCII string and returns the ASCII string.
|
||||
|
||||
@ -1026,6 +1066,56 @@ UnicodeStrToAsciiStr (
|
||||
OUT CHAR8 *Destination
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
Convert a Null-terminated Unicode string to a Null-terminated
|
||||
ASCII string.
|
||||
|
||||
This function is similar to AsciiStrCpyS.
|
||||
|
||||
This function converts the content of the Unicode string Source
|
||||
to the ASCII string Destination by copying the lower 8 bits of
|
||||
each Unicode character. The function terminates the ASCII string
|
||||
Destination by appending a Null-terminator character at the end.
|
||||
|
||||
The caller is responsible to make sure Destination points to a buffer with size
|
||||
equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
|
||||
|
||||
If any Unicode characters in Source contain non-zero value in
|
||||
the upper 8 bits, then ASSERT().
|
||||
|
||||
If Source is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Source The pointer to a Null-terminated Unicode string.
|
||||
@param Destination The pointer to a Null-terminated ASCII string.
|
||||
@param DestMax The maximum number of Destination Ascii
|
||||
char, including terminating null char.
|
||||
|
||||
@retval RETURN_SUCCESS String is converted.
|
||||
@retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
|
||||
@retval RETURN_INVALID_PARAMETER If Destination is NULL.
|
||||
If Source is NULL.
|
||||
If PcdMaximumAsciiStringLength is not zero,
|
||||
and DestMax is greater than
|
||||
PcdMaximumAsciiStringLength.
|
||||
If PcdMaximumUnicodeStringLength is not zero,
|
||||
and DestMax is greater than
|
||||
PcdMaximumUnicodeStringLength.
|
||||
If DestMax is 0.
|
||||
@retval RETURN_ACCESS_DENIED If Source and Destination overlap.
|
||||
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
UnicodeStrToAsciiStrS (
|
||||
IN CONST CHAR16 *Source,
|
||||
OUT CHAR8 *Destination,
|
||||
IN UINTN DestMax
|
||||
);
|
||||
|
||||
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
||||
|
||||
@ -1529,8 +1619,11 @@ AsciiStrHexToUint64 (
|
||||
IN CONST CHAR8 *String
|
||||
);
|
||||
|
||||
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
||||
|
||||
/**
|
||||
[ATTENTION] This function is deprecated for security reason.
|
||||
|
||||
Convert one Null-terminated ASCII string to a Null-terminated
|
||||
Unicode string and returns the Unicode string.
|
||||
|
||||
@ -1564,6 +1657,52 @@ AsciiStrToUnicodeStr (
|
||||
OUT CHAR16 *Destination
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
Convert one Null-terminated ASCII string to a Null-terminated
|
||||
Unicode string.
|
||||
|
||||
This function is similar to StrCpyS.
|
||||
|
||||
This function converts the contents of the ASCII string Source to the Unicode
|
||||
string Destination. The function terminates the Unicode string Destination by
|
||||
appending a Null-terminator character at the end.
|
||||
|
||||
The caller is responsible to make sure Destination points to a buffer with size
|
||||
equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
|
||||
|
||||
If Destination is not aligned on a 16-bit boundary, then ASSERT().
|
||||
If an error would be returned, then the function will also ASSERT().
|
||||
|
||||
If an error is returned, then the Destination is unmodified.
|
||||
|
||||
@param Source The pointer to a Null-terminated ASCII string.
|
||||
@param Destination The pointer to a Null-terminated Unicode string.
|
||||
@param DestMax The maximum number of Destination Unicode
|
||||
char, including terminating null char.
|
||||
|
||||
@retval RETURN_SUCCESS String is converted.
|
||||
@retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
|
||||
@retval RETURN_INVALID_PARAMETER If Destination is NULL.
|
||||
If Source is NULL.
|
||||
If PcdMaximumUnicodeStringLength is not zero,
|
||||
and DestMax is greater than
|
||||
PcdMaximumUnicodeStringLength.
|
||||
If PcdMaximumAsciiStringLength is not zero,
|
||||
and DestMax is greater than
|
||||
PcdMaximumAsciiStringLength.
|
||||
If DestMax is 0.
|
||||
@retval RETURN_ACCESS_DENIED If Source and Destination overlap.
|
||||
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
AsciiStrToUnicodeStrS (
|
||||
IN CONST CHAR8 *Source,
|
||||
OUT CHAR16 *Destination,
|
||||
IN UINTN DestMax
|
||||
);
|
||||
|
||||
/**
|
||||
Converts an 8-bit value to an 8-bit BCD value.
|
||||
@ -1635,7 +1774,7 @@ PathRemoveLastItem(
|
||||
|
||||
@param[in] Path The pointer to the string containing the path.
|
||||
|
||||
@return Returns Path, otherwise returns NULL to indicate that an error has occured.
|
||||
@return Returns Path, otherwise returns NULL to indicate that an error has occurred.
|
||||
**/
|
||||
CHAR16*
|
||||
EFIAPI
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
HOB related definitions in PI.
|
||||
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
@ -11,7 +11,7 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
@par Revision Reference:
|
||||
PI Version 1.4
|
||||
PI Version 1.4a
|
||||
|
||||
**/
|
||||
|
||||
@ -295,7 +295,7 @@ typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE;
|
||||
#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE 0x01000000
|
||||
|
||||
#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000
|
||||
#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00800000
|
||||
#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000
|
||||
|
||||
//
|
||||
// Physical memory relative reliability attribute. This
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __EFI_APPLE_NET_BOOT_PROTOCOL_H__
|
||||
#define __EFI_APPLE_NET_BOOT_PROTOCOL_H__
|
||||
#ifndef _IPXE_EFI_APPLE_NET_BOOT_PROTOCOL_H
|
||||
#define _IPXE_EFI_APPLE_NET_BOOT_PROTOCOL_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
@ -43,4 +43,4 @@ struct _EFI_APPLE_NET_BOOT_PROTOCOL
|
||||
GET_DHCP_RESPONSE GetBsdpResponse;
|
||||
};
|
||||
|
||||
#endif /*__EFI_APPLE_NET_BOOT_PROTOCOL_H__ */
|
||||
#endif /*_IPXE_EFI_APPLE_NET_BOOT_PROTOCOL_H */
|
||||
|
208
third_party/ipxe/src/include/ipxe/efi/Protocol/BlockIo2.h
vendored
Normal file
208
third_party/ipxe/src/include/ipxe/efi/Protocol/BlockIo2.h
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
/** @file
|
||||
Block IO2 protocol as defined in the UEFI 2.3.1 specification.
|
||||
|
||||
The Block IO2 protocol defines an extension to the Block IO protocol which
|
||||
enables the ability to read and write data at a block level in a non-blocking
|
||||
manner.
|
||||
|
||||
Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __BLOCK_IO2_H__
|
||||
#define __BLOCK_IO2_H__
|
||||
|
||||
FILE_LICENCE ( BSD3 );
|
||||
|
||||
#include <ipxe/efi/Protocol/BlockIo.h>
|
||||
|
||||
#define EFI_BLOCK_IO2_PROTOCOL_GUID \
|
||||
{ \
|
||||
0xa77b2472, 0xe282, 0x4e9f, {0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1} \
|
||||
}
|
||||
|
||||
typedef struct _EFI_BLOCK_IO2_PROTOCOL EFI_BLOCK_IO2_PROTOCOL;
|
||||
|
||||
/**
|
||||
The struct of Block IO2 Token.
|
||||
**/
|
||||
typedef struct {
|
||||
|
||||
///
|
||||
/// If Event is NULL, then blocking I/O is performed.If Event is not NULL and
|
||||
/// non-blocking I/O is supported, then non-blocking I/O is performed, and
|
||||
/// Event will be signaled when the read request is completed.
|
||||
///
|
||||
EFI_EVENT Event;
|
||||
|
||||
///
|
||||
/// Defines whether or not the signaled event encountered an error.
|
||||
///
|
||||
EFI_STATUS TransactionStatus;
|
||||
} EFI_BLOCK_IO2_TOKEN;
|
||||
|
||||
|
||||
/**
|
||||
Reset the block device hardware.
|
||||
|
||||
@param[in] This Indicates a pointer to the calling context.
|
||||
@param[in] ExtendedVerification Indicates that the driver may perform a more
|
||||
exhausive verification operation of the device
|
||||
during reset.
|
||||
|
||||
@retval EFI_SUCCESS The device was reset.
|
||||
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
|
||||
not be reset.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_BLOCK_RESET_EX) (
|
||||
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||
IN BOOLEAN ExtendedVerification
|
||||
);
|
||||
|
||||
/**
|
||||
Read BufferSize bytes from Lba into Buffer.
|
||||
|
||||
This function reads the requested number of blocks from the device. All the
|
||||
blocks are read, or an error is returned.
|
||||
If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and
|
||||
non-blocking I/O is being used, the Event associated with this request will
|
||||
not be signaled.
|
||||
|
||||
@param[in] This Indicates a pointer to the calling context.
|
||||
@param[in] MediaId Id of the media, changes every time the media is
|
||||
replaced.
|
||||
@param[in] Lba The starting Logical Block Address to read from.
|
||||
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||
@param[out] Buffer A pointer to the destination buffer for the data. The
|
||||
caller is responsible for either having implicit or
|
||||
explicit ownership of the buffer.
|
||||
|
||||
@retval EFI_SUCCESS The read request was queued if Token->Event is
|
||||
not NULL.The data was read correctly from the
|
||||
device if the Token->Event is NULL.
|
||||
@retval EFI_DEVICE_ERROR The device reported an error while performing
|
||||
the read.
|
||||
@retval EFI_NO_MEDIA There is no media in the device.
|
||||
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
|
||||
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
|
||||
intrinsic block size of the device.
|
||||
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
|
||||
or the buffer is not on proper alignment.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||
of resources.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_BLOCK_READ_EX) (
|
||||
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||
IN UINT32 MediaId,
|
||||
IN EFI_LBA LBA,
|
||||
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||
IN UINTN BufferSize,
|
||||
OUT VOID *Buffer
|
||||
);
|
||||
|
||||
/**
|
||||
Write BufferSize bytes from Lba into Buffer.
|
||||
|
||||
This function writes the requested number of blocks to the device. All blocks
|
||||
are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA,
|
||||
EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is
|
||||
being used, the Event associated with this request will not be signaled.
|
||||
|
||||
@param[in] This Indicates a pointer to the calling context.
|
||||
@param[in] MediaId The media ID that the write request is for.
|
||||
@param[in] Lba The starting logical block address to be written. The
|
||||
caller is responsible for writing to only legitimate
|
||||
locations.
|
||||
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||
@param[in] Buffer A pointer to the source buffer for the data.
|
||||
|
||||
@retval EFI_SUCCESS The write request was queued if Event is not NULL.
|
||||
The data was written correctly to the device if
|
||||
the Event is NULL.
|
||||
@retval EFI_WRITE_PROTECTED The device can not be written to.
|
||||
@retval EFI_NO_MEDIA There is no media in the device.
|
||||
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
|
||||
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
|
||||
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
|
||||
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
|
||||
or the buffer is not on proper alignment.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||
of resources.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_BLOCK_WRITE_EX) (
|
||||
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||
IN UINT32 MediaId,
|
||||
IN EFI_LBA LBA,
|
||||
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||
IN UINTN BufferSize,
|
||||
IN VOID *Buffer
|
||||
);
|
||||
|
||||
/**
|
||||
Flush the Block Device.
|
||||
|
||||
If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED
|
||||
is returned and non-blocking I/O is being used, the Event associated with
|
||||
this request will not be signaled.
|
||||
|
||||
@param[in] This Indicates a pointer to the calling context.
|
||||
@param[in,out] Token A pointer to the token associated with the transaction
|
||||
|
||||
@retval EFI_SUCCESS The flush request was queued if Event is not NULL.
|
||||
All outstanding data was written correctly to the
|
||||
device if the Event is NULL.
|
||||
@retval EFI_DEVICE_ERROR The device reported an error while writting back
|
||||
the data.
|
||||
@retval EFI_WRITE_PROTECTED The device cannot be written to.
|
||||
@retval EFI_NO_MEDIA There is no media in the device.
|
||||
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||
of resources.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_BLOCK_FLUSH_EX) (
|
||||
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||
IN OUT EFI_BLOCK_IO2_TOKEN *Token
|
||||
);
|
||||
|
||||
///
|
||||
/// The Block I/O2 protocol defines an extension to the Block I/O protocol which
|
||||
/// enables the ability to read and write data at a block level in a non-blocking
|
||||
// manner.
|
||||
///
|
||||
struct _EFI_BLOCK_IO2_PROTOCOL {
|
||||
///
|
||||
/// A pointer to the EFI_BLOCK_IO_MEDIA data for this device.
|
||||
/// Type EFI_BLOCK_IO_MEDIA is defined in BlockIo.h.
|
||||
///
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
|
||||
EFI_BLOCK_RESET_EX Reset;
|
||||
EFI_BLOCK_READ_EX ReadBlocksEx;
|
||||
EFI_BLOCK_WRITE_EX WriteBlocksEx;
|
||||
EFI_BLOCK_FLUSH_EX FlushBlocksEx;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEfiBlockIo2ProtocolGuid;
|
||||
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
from a software point of view. The path must persist from boot to boot, so
|
||||
it can not contain things like PCI bus numbers that change from boot to boot.
|
||||
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
@ -511,7 +511,7 @@ typedef struct {
|
||||
UINT16 HBAPortNumber;
|
||||
///
|
||||
/// The Port multiplier port number that facilitates the connection
|
||||
/// to the device. Bit 15 should be set if the device is directly
|
||||
/// to the device. Must be set to 0xFFFF if the device is directly
|
||||
/// connected to the HBA.
|
||||
///
|
||||
UINT16 PortMultiplierPortNumber;
|
||||
@ -856,6 +856,15 @@ typedef struct {
|
||||
UINT8 SlotNumber;
|
||||
} SD_DEVICE_PATH;
|
||||
|
||||
///
|
||||
/// EMMC (Embedded MMC) Device Path SubType.
|
||||
///
|
||||
#define MSG_EMMC_DP 0x1D
|
||||
typedef struct {
|
||||
EFI_DEVICE_PATH_PROTOCOL Header;
|
||||
UINT8 SlotNumber;
|
||||
} EMMC_DEVICE_PATH;
|
||||
|
||||
///
|
||||
/// iSCSI Device Path SubType
|
||||
///
|
||||
@ -1241,6 +1250,7 @@ typedef union {
|
||||
WIFI_DEVICE_PATH WiFi;
|
||||
UFS_DEVICE_PATH Ufs;
|
||||
SD_DEVICE_PATH Sd;
|
||||
EMMC_DEVICE_PATH Emmc;
|
||||
HARDDRIVE_DEVICE_PATH HardDrive;
|
||||
CDROM_DEVICE_PATH CD;
|
||||
|
||||
@ -1297,6 +1307,7 @@ typedef union {
|
||||
WIFI_DEVICE_PATH *WiFi;
|
||||
UFS_DEVICE_PATH *Ufs;
|
||||
SD_DEVICE_PATH *Sd;
|
||||
EMMC_DEVICE_PATH *Emmc;
|
||||
HARDDRIVE_DEVICE_PATH *HardDrive;
|
||||
CDROM_DEVICE_PATH *CD;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
The file provides services to access to images in the images database.
|
||||
|
||||
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -17,6 +17,8 @@
|
||||
|
||||
FILE_LICENCE ( BSD3 );
|
||||
|
||||
#include <ipxe/efi/Protocol/GraphicsOutput.h>
|
||||
|
||||
#define EFI_HII_IMAGE_PROTOCOL_GUID \
|
||||
{ 0x31a6406a, 0x6bdf, 0x4e46, { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } }
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/** @file
|
||||
EFI Multicast Trivial File Tranfer Protocol Definition
|
||||
EFI Multicast Trivial File Transfer Protocol Definition
|
||||
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
@ -214,7 +214,7 @@ EFI_STATUS
|
||||
);
|
||||
|
||||
/**
|
||||
Timeout callback funtion.
|
||||
Timeout callback function.
|
||||
|
||||
@param This The pointer to the EFI_MTFTP4_PROTOCOL instance.
|
||||
@param Token The token that is provided in the
|
||||
|
@ -162,7 +162,7 @@ typedef EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SIMPLE_TEXT_OUTPUT_INTERFACE;
|
||||
Reset the text output device hardware and optionaly run diagnostics
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param ExtendedVerification Driver may perform more exhaustive verfication
|
||||
@param ExtendedVerification Driver may perform more exhaustive verification
|
||||
operation of the device during reset.
|
||||
|
||||
@retval EFI_SUCCESS The text output device was reset.
|
||||
|
@ -3,7 +3,8 @@
|
||||
IFR is primarily consumed by the EFI presentation engine, and produced by EFI
|
||||
internal application and drivers as well as all add-in card option-ROM drivers
|
||||
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
@ -211,6 +212,7 @@ typedef struct _EFI_HII_FONT_PACKAGE_HDR {
|
||||
#define EFI_HII_GIBT_GLYPHS 0x11
|
||||
#define EFI_HII_GIBT_GLYPH_DEFAULT 0x12
|
||||
#define EFI_HII_GIBT_GLYPHS_DEFAULT 0x13
|
||||
#define EFI_HII_GIBT_GLYPH_VARIABILITY 0x14
|
||||
#define EFI_HII_GIBT_DUPLICATE 0x20
|
||||
#define EFI_HII_GIBT_SKIP2 0x21
|
||||
#define EFI_HII_GIBT_SKIP1 0x22
|
||||
@ -283,6 +285,13 @@ typedef struct _EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK {
|
||||
UINT8 BitmapData[1];
|
||||
} EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK;
|
||||
|
||||
typedef struct _EFI_HII_GIBT_VARIABILITY_BLOCK {
|
||||
EFI_HII_GLYPH_BLOCK Header;
|
||||
EFI_HII_GLYPH_INFO Cell;
|
||||
UINT8 GlyphPackInBits;
|
||||
UINT8 BitmapData [1];
|
||||
} EFI_HII_GIBT_VARIABILITY_BLOCK;
|
||||
|
||||
typedef struct _EFI_HII_GIBT_SKIP1_BLOCK {
|
||||
EFI_HII_GLYPH_BLOCK Header;
|
||||
UINT8 SkipCount;
|
||||
@ -491,6 +500,7 @@ typedef struct _EFI_HII_IMAGE_BLOCK {
|
||||
#define EFI_HII_IIBT_IMAGE_24BIT 0x16
|
||||
#define EFI_HII_IIBT_IMAGE_24BIT_TRANS 0x17
|
||||
#define EFI_HII_IIBT_IMAGE_JPEG 0x18
|
||||
#define EFI_HII_IIBT_IMAGE_PNG 0x19
|
||||
#define EFI_HII_IIBT_DUPLICATE 0x20
|
||||
#define EFI_HII_IIBT_SKIP2 0x21
|
||||
#define EFI_HII_IIBT_SKIP1 0x22
|
||||
@ -611,6 +621,12 @@ typedef struct _EFI_HII_IIBT_JPEG_BLOCK {
|
||||
UINT8 Data[1];
|
||||
} EFI_HII_IIBT_JPEG_BLOCK;
|
||||
|
||||
typedef struct _EFI_HII_IIBT_PNG_BLOCK {
|
||||
EFI_HII_IMAGE_BLOCK Header;
|
||||
UINT32 Size;
|
||||
UINT8 Data[1];
|
||||
} EFI_HII_IIBT_PNG_BLOCK;
|
||||
|
||||
typedef struct _EFI_HII_IIBT_SKIP1_BLOCK {
|
||||
EFI_HII_IMAGE_BLOCK Header;
|
||||
UINT8 SkipCount;
|
||||
@ -2112,4 +2128,10 @@ typedef struct _EFI_HII_AIBT_SKIP2_BLOCK {
|
||||
///
|
||||
#define STRING_TOKEN(t) t
|
||||
|
||||
///
|
||||
/// IMAGE_TOKEN is not defined in UEFI specification. But it is placed
|
||||
/// here for the easy access by C files and VFR source files.
|
||||
///
|
||||
#define IMAGE_TOKEN(t) t
|
||||
|
||||
#endif
|
||||
|
@ -1081,7 +1081,7 @@ typedef struct s_pxe_cpb_start_31 {
|
||||
|
||||
///
|
||||
/// protocol driver can provide anything for this Unique_ID, UNDI remembers
|
||||
/// that as just a 64bit value assocaited to the interface specified by
|
||||
/// that as just a 64bit value associated to the interface specified by
|
||||
/// the ifnum and gives it back as a parameter to all the call-back routines
|
||||
/// when calling for that interface!
|
||||
///
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user