2006-08-28 00:02:08 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2006 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
|
2012-07-20 20:55:45 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
* 02110-1301, USA.
|
2015-03-02 12:54:40 +01:00
|
|
|
*
|
|
|
|
* 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.
|
2006-08-28 00:02:08 +02:00
|
|
|
*/
|
|
|
|
|
2015-03-02 12:54:40 +01:00
|
|
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
2009-05-01 16:41:06 +02:00
|
|
|
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
#include <errno.h>
|
2016-07-10 20:25:26 +02:00
|
|
|
#include <byteswap.h>
|
|
|
|
#include <ipxe/uaccess.h>
|
2010-04-19 21:16:01 +02:00
|
|
|
#include <ipxe/acpi.h>
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
#include <ipxe/interface.h>
|
2006-08-28 00:02:08 +02:00
|
|
|
|
|
|
|
/** @file
|
|
|
|
*
|
|
|
|
* ACPI support functions
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Utility functions
|
|
|
|
*
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
|
2017-07-27 16:04:35 +02:00
|
|
|
/**
|
|
|
|
* Compute ACPI table checksum
|
|
|
|
*
|
|
|
|
* @v table Any ACPI table
|
|
|
|
* @ret checksum 0 if checksum is good
|
|
|
|
*/
|
|
|
|
static uint8_t acpi_checksum ( userptr_t table ) {
|
|
|
|
struct acpi_header acpi;
|
|
|
|
uint8_t sum = 0;
|
2017-07-28 21:19:31 +02:00
|
|
|
uint8_t data = 0;
|
2017-07-27 16:04:35 +02:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
/* Read table length */
|
|
|
|
copy_from_user ( &acpi.length, table,
|
|
|
|
offsetof ( typeof ( acpi ), length ),
|
|
|
|
sizeof ( acpi.length ) );
|
|
|
|
|
|
|
|
/* Compute checksum */
|
|
|
|
for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
|
|
|
|
copy_from_user ( &data, table, i, sizeof ( data ) );
|
|
|
|
sum += data;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
2006-08-28 00:02:08 +02:00
|
|
|
/**
|
|
|
|
* Fix up ACPI table checksum
|
|
|
|
*
|
|
|
|
* @v acpi ACPI table header
|
|
|
|
*/
|
2017-03-27 17:20:34 +02:00
|
|
|
void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
2006-08-28 00:02:08 +02:00
|
|
|
|
2017-07-27 16:04:35 +02:00
|
|
|
/* Update checksum */
|
|
|
|
acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
|
2006-08-28 00:02:08 +02:00
|
|
|
}
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
|
2016-07-10 20:25:26 +02:00
|
|
|
/**
|
|
|
|
* Locate ACPI table
|
|
|
|
*
|
|
|
|
* @v signature Requested table signature
|
|
|
|
* @v index Requested index of table with this signature
|
|
|
|
* @ret table Table, or UNULL if not found
|
|
|
|
*/
|
2017-05-22 20:27:30 +02:00
|
|
|
userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
|
2017-03-27 17:20:34 +02:00
|
|
|
struct acpi_header acpi;
|
2016-07-10 20:25:26 +02:00
|
|
|
struct acpi_rsdt *rsdtab;
|
|
|
|
typeof ( rsdtab->entry[0] ) entry;
|
2017-05-22 20:27:30 +02:00
|
|
|
userptr_t rsdt;
|
2016-07-10 20:25:26 +02:00
|
|
|
userptr_t table;
|
|
|
|
size_t len;
|
|
|
|
unsigned int count;
|
|
|
|
unsigned int i;
|
|
|
|
|
2017-05-22 20:27:30 +02:00
|
|
|
/* Locate RSDT */
|
|
|
|
rsdt = acpi_find_rsdt();
|
|
|
|
if ( ! rsdt ) {
|
|
|
|
DBG ( "RSDT not found\n" );
|
|
|
|
return UNULL;
|
|
|
|
}
|
|
|
|
|
2016-07-10 20:25:26 +02:00
|
|
|
/* Read RSDT header */
|
|
|
|
copy_from_user ( &acpi, rsdt, 0, sizeof ( acpi ) );
|
|
|
|
if ( acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) {
|
|
|
|
DBGC ( rsdt, "RSDT %#08lx has invalid signature:\n",
|
|
|
|
user_to_phys ( rsdt, 0 ) );
|
|
|
|
DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
|
|
|
|
sizeof ( acpi ) );
|
|
|
|
return UNULL;
|
|
|
|
}
|
|
|
|
len = le32_to_cpu ( acpi.length );
|
|
|
|
if ( len < sizeof ( rsdtab->acpi ) ) {
|
|
|
|
DBGC ( rsdt, "RSDT %#08lx has invalid length:\n",
|
|
|
|
user_to_phys ( rsdt, 0 ) );
|
|
|
|
DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
|
|
|
|
sizeof ( acpi ) );
|
|
|
|
return UNULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate number of entries */
|
|
|
|
count = ( ( len - sizeof ( rsdtab->acpi ) ) / sizeof ( entry ) );
|
|
|
|
|
|
|
|
/* Search through entries */
|
|
|
|
for ( i = 0 ; i < count ; i++ ) {
|
|
|
|
|
|
|
|
/* Get table address */
|
|
|
|
copy_from_user ( &entry, rsdt,
|
|
|
|
offsetof ( typeof ( *rsdtab ), entry[i] ),
|
|
|
|
sizeof ( entry ) );
|
|
|
|
|
|
|
|
/* Read table header */
|
|
|
|
table = phys_to_user ( entry );
|
|
|
|
copy_from_user ( &acpi.signature, table, 0,
|
|
|
|
sizeof ( acpi.signature ) );
|
|
|
|
|
|
|
|
/* Check table signature */
|
|
|
|
if ( acpi.signature != cpu_to_le32 ( signature ) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Check index */
|
|
|
|
if ( index-- )
|
|
|
|
continue;
|
|
|
|
|
2017-07-27 16:04:35 +02:00
|
|
|
/* Check table integrity */
|
|
|
|
if ( acpi_checksum ( table ) != 0 ) {
|
|
|
|
DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
|
|
|
|
"at %08lx\n", user_to_phys ( rsdt, 0 ),
|
|
|
|
acpi_name ( signature ),
|
|
|
|
user_to_phys ( table, 0 ) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-07-10 20:25:26 +02:00
|
|
|
DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
|
|
|
|
user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
|
|
|
|
user_to_phys ( table, 0 ) );
|
|
|
|
return table;
|
|
|
|
}
|
|
|
|
|
|
|
|
DBGC ( rsdt, "RSDT %#08lx could not find %s\n",
|
|
|
|
user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
|
|
|
|
return UNULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extract \_Sx value from DSDT/SSDT
|
|
|
|
*
|
|
|
|
* @v zsdt DSDT or SSDT
|
|
|
|
* @v signature Signature (e.g. "_S5_")
|
|
|
|
* @ret sx \_Sx value, or negative error
|
|
|
|
*
|
|
|
|
* In theory, extracting the \_Sx value from the DSDT/SSDT requires a
|
|
|
|
* full ACPI parser plus some heuristics to work around the various
|
|
|
|
* broken encodings encountered in real ACPI implementations.
|
|
|
|
*
|
|
|
|
* In practice, we can get the same result by scanning through the
|
|
|
|
* DSDT/SSDT for the signature (e.g. "_S5_"), extracting the first
|
|
|
|
* four bytes, removing any bytes with bit 3 set, and treating
|
|
|
|
* whatever is left as a little-endian value. This is one of the
|
|
|
|
* uglier hacks I have ever implemented, but it's still prettier than
|
|
|
|
* the ACPI specification itself.
|
|
|
|
*/
|
|
|
|
static int acpi_sx_zsdt ( userptr_t zsdt, uint32_t signature ) {
|
2017-03-27 17:20:34 +02:00
|
|
|
struct acpi_header acpi;
|
2016-07-10 20:25:26 +02:00
|
|
|
union {
|
|
|
|
uint32_t dword;
|
|
|
|
uint8_t byte[4];
|
|
|
|
} buf;
|
|
|
|
size_t offset;
|
|
|
|
size_t len;
|
|
|
|
unsigned int sx;
|
|
|
|
uint8_t *byte;
|
|
|
|
|
|
|
|
/* Read table header */
|
|
|
|
copy_from_user ( &acpi, zsdt, 0, sizeof ( acpi ) );
|
|
|
|
len = le32_to_cpu ( acpi.length );
|
|
|
|
|
|
|
|
/* Locate signature */
|
|
|
|
for ( offset = sizeof ( acpi ) ;
|
|
|
|
( ( offset + sizeof ( buf ) /* signature */ + 3 /* pkg header */
|
|
|
|
+ sizeof ( buf ) /* value */ ) < len ) ;
|
|
|
|
offset++ ) {
|
|
|
|
|
|
|
|
/* Check signature */
|
|
|
|
copy_from_user ( &buf, zsdt, offset, sizeof ( buf ) );
|
|
|
|
if ( buf.dword != cpu_to_le32 ( signature ) )
|
|
|
|
continue;
|
|
|
|
DBGC ( zsdt, "DSDT/SSDT %#08lx found %s at offset %#zx\n",
|
|
|
|
user_to_phys ( zsdt, 0 ), acpi_name ( signature ),
|
|
|
|
offset );
|
|
|
|
offset += sizeof ( buf );
|
|
|
|
|
|
|
|
/* Read first four bytes of value */
|
|
|
|
copy_from_user ( &buf, zsdt, ( offset + 3 /* pkg header */ ),
|
|
|
|
sizeof ( buf ) );
|
|
|
|
DBGC ( zsdt, "DSDT/SSDT %#08lx found %s containing "
|
|
|
|
"%02x:%02x:%02x:%02x\n", user_to_phys ( zsdt, 0 ),
|
|
|
|
acpi_name ( signature ), buf.byte[0], buf.byte[1],
|
|
|
|
buf.byte[2], buf.byte[3] );
|
|
|
|
|
|
|
|
/* Extract \Sx value. There are three potential
|
|
|
|
* encodings that we might encounter:
|
|
|
|
*
|
|
|
|
* - SLP_TYPa, SLP_TYPb, rsvd, rsvd
|
|
|
|
*
|
|
|
|
* - <byteprefix>, SLP_TYPa, <byteprefix>, SLP_TYPb, ...
|
|
|
|
*
|
|
|
|
* - <dwordprefix>, SLP_TYPa, SLP_TYPb, 0, 0
|
|
|
|
*
|
|
|
|
* Since <byteprefix> and <dwordprefix> both have bit
|
|
|
|
* 3 set, and valid SLP_TYPx must have bit 3 clear
|
|
|
|
* (since SLP_TYPx is a 3-bit field), we can just skip
|
|
|
|
* any bytes with bit 3 set.
|
|
|
|
*/
|
|
|
|
byte = &buf.byte[0];
|
|
|
|
if ( *byte & 0x08 )
|
|
|
|
byte++;
|
|
|
|
sx = *(byte++);
|
|
|
|
if ( *byte & 0x08 )
|
|
|
|
byte++;
|
|
|
|
sx |= ( *byte << 8 );
|
|
|
|
return sx;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extract \_Sx value from DSDT/SSDT
|
|
|
|
*
|
|
|
|
* @v signature Signature (e.g. "_S5_")
|
|
|
|
* @ret sx \_Sx value, or negative error
|
|
|
|
*/
|
2017-05-22 20:27:30 +02:00
|
|
|
int acpi_sx ( uint32_t signature ) {
|
2016-07-10 20:25:26 +02:00
|
|
|
struct acpi_fadt fadtab;
|
2017-05-22 20:27:30 +02:00
|
|
|
userptr_t rsdt;
|
2016-07-10 20:25:26 +02:00
|
|
|
userptr_t fadt;
|
|
|
|
userptr_t dsdt;
|
|
|
|
userptr_t ssdt;
|
|
|
|
unsigned int i;
|
|
|
|
int sx;
|
|
|
|
|
2017-05-22 20:27:30 +02:00
|
|
|
/* Locate RSDT */
|
|
|
|
rsdt = acpi_find_rsdt();
|
|
|
|
if ( ! rsdt ) {
|
|
|
|
DBG ( "RSDT not found\n" );
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
2016-07-10 20:25:26 +02:00
|
|
|
/* Try DSDT first */
|
2017-05-22 20:27:30 +02:00
|
|
|
fadt = acpi_find ( FADT_SIGNATURE, 0 );
|
2016-07-10 20:25:26 +02:00
|
|
|
if ( fadt ) {
|
|
|
|
copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
|
|
|
|
dsdt = phys_to_user ( fadtab.dsdt );
|
|
|
|
if ( ( sx = acpi_sx_zsdt ( dsdt, signature ) ) >= 0 )
|
|
|
|
return sx;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Try all SSDTs */
|
|
|
|
for ( i = 0 ; ; i++ ) {
|
2017-05-22 20:27:30 +02:00
|
|
|
ssdt = acpi_find ( SSDT_SIGNATURE, i );
|
2016-07-10 20:25:26 +02:00
|
|
|
if ( ! ssdt )
|
|
|
|
break;
|
|
|
|
if ( ( sx = acpi_sx_zsdt ( ssdt, signature ) ) >= 0 )
|
|
|
|
return sx;
|
|
|
|
}
|
|
|
|
|
|
|
|
DBGC ( rsdt, "RSDT %#08lx could not find \\_Sx \"%s\"\n",
|
|
|
|
user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
2017-03-27 17:20:34 +02:00
|
|
|
* Descriptors
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
*
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2017-03-27 17:20:34 +02:00
|
|
|
* Add ACPI descriptor
|
|
|
|
*
|
|
|
|
* @v desc ACPI descriptor
|
|
|
|
*/
|
|
|
|
void acpi_add ( struct acpi_descriptor *desc ) {
|
|
|
|
|
|
|
|
/* Add to list of descriptors */
|
|
|
|
ref_get ( desc->refcnt );
|
|
|
|
list_add_tail ( &desc->list, &desc->model->descs );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove ACPI descriptor
|
|
|
|
*
|
|
|
|
* @v desc ACPI descriptor
|
|
|
|
*/
|
|
|
|
void acpi_del ( struct acpi_descriptor *desc ) {
|
|
|
|
|
|
|
|
/* Remove from list of descriptors */
|
|
|
|
list_check_contains_entry ( desc, &desc->model->descs, list );
|
|
|
|
list_del ( &desc->list );
|
|
|
|
ref_put ( desc->refcnt );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get object's ACPI descriptor
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
*
|
|
|
|
* @v intf Interface
|
2017-03-27 17:20:34 +02:00
|
|
|
* @ret desc ACPI descriptor, or NULL
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
*/
|
2017-03-27 17:20:34 +02:00
|
|
|
struct acpi_descriptor * acpi_describe ( struct interface *intf ) {
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
struct interface *dest;
|
|
|
|
acpi_describe_TYPE ( void * ) *op =
|
|
|
|
intf_get_dest_op ( intf, acpi_describe, &dest );
|
|
|
|
void *object = intf_object ( dest );
|
2017-03-27 17:20:34 +02:00
|
|
|
struct acpi_descriptor *desc;
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
|
|
|
|
if ( op ) {
|
2017-03-27 17:20:34 +02:00
|
|
|
desc = op ( object );
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
} else {
|
2017-03-27 17:20:34 +02:00
|
|
|
desc = NULL;
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
intf_put ( dest );
|
2017-03-27 17:20:34 +02:00
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Install ACPI tables
|
|
|
|
*
|
|
|
|
* @v install Table installation method
|
|
|
|
* @ret rc Return status code
|
|
|
|
*/
|
|
|
|
int acpi_install ( int ( * install ) ( struct acpi_header *acpi ) ){
|
|
|
|
struct acpi_model *model;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
for_each_table_entry ( model, ACPI_MODELS ) {
|
|
|
|
if ( ( rc = model->install ( install ) ) != 0 )
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-09-03 17:11:51 +02:00
|
|
|
}
|