mirror of
https://github.com/ipxe/ipxe
synced 2025-12-21 04:20:17 +03:00
[acpi] Remove userptr_t from ACPI table parsing
Simplify the ACPI table parsing code by assuming that all table content is fully accessible via pointer dereferences. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -20,9 +20,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
*
|
*
|
||||||
* @v signature Requested table signature
|
* @v signature Requested table signature
|
||||||
* @v index Requested index of table with this signature
|
* @v index Requested index of table with this signature
|
||||||
* @ret table Table, or UNULL if not found
|
* @ret table Table, or NULL if not found
|
||||||
*/
|
*/
|
||||||
static inline __attribute__ (( always_inline )) userptr_t
|
static inline __attribute__ (( always_inline )) const struct acpi_header *
|
||||||
ACPI_INLINE ( rsdp, acpi_find ) ( uint32_t signature, unsigned int index ) {
|
ACPI_INLINE ( rsdp, acpi_find ) ( uint32_t signature, unsigned int index ) {
|
||||||
|
|
||||||
return acpi_find_via_rsdt ( signature, index );
|
return acpi_find_via_rsdt ( signature, index );
|
||||||
|
|||||||
@@ -102,20 +102,19 @@ static void acpi_udelay ( unsigned long usecs ) {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int acpi_timer_probe ( void ) {
|
static int acpi_timer_probe ( void ) {
|
||||||
struct acpi_fadt fadtab;
|
const struct acpi_fadt *fadt;
|
||||||
userptr_t fadt;
|
|
||||||
unsigned int pm_tmr_blk;
|
unsigned int pm_tmr_blk;
|
||||||
|
|
||||||
/* Locate FADT */
|
/* Locate FADT */
|
||||||
fadt = acpi_table ( FADT_SIGNATURE, 0 );
|
fadt = container_of ( acpi_table ( FADT_SIGNATURE, 0 ),
|
||||||
|
struct acpi_fadt, acpi );
|
||||||
if ( ! fadt ) {
|
if ( ! fadt ) {
|
||||||
DBGC ( &acpi_timer, "ACPI could not find FADT\n" );
|
DBGC ( &acpi_timer, "ACPI could not find FADT\n" );
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read FADT */
|
/* Read FADT */
|
||||||
copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
|
pm_tmr_blk = le32_to_cpu ( fadt->pm_tmr_blk );
|
||||||
pm_tmr_blk = le32_to_cpu ( fadtab.pm_tmr_blk );
|
|
||||||
if ( ! pm_tmr_blk ) {
|
if ( ! pm_tmr_blk ) {
|
||||||
DBGC ( &acpi_timer, "ACPI has no timer\n" );
|
DBGC ( &acpi_timer, "ACPI has no timer\n" );
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
* uglier hacks I have ever implemented, but it's still prettier than
|
* uglier hacks I have ever implemented, but it's still prettier than
|
||||||
* the ACPI specification itself.
|
* the ACPI specification itself.
|
||||||
*/
|
*/
|
||||||
static int acpi_extract_sx ( userptr_t zsdt, size_t len, size_t offset,
|
static int acpi_extract_sx ( const struct acpi_header *zsdt, size_t len,
|
||||||
void *data ) {
|
size_t offset, void *data ) {
|
||||||
unsigned int *sx = data;
|
unsigned int *sx = data;
|
||||||
uint8_t bytes[4];
|
uint8_t bytes[4];
|
||||||
uint8_t *byte;
|
uint8_t *byte;
|
||||||
@@ -77,7 +77,8 @@ static int acpi_extract_sx ( userptr_t zsdt, size_t len, size_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read first four bytes of value */
|
/* Read first four bytes of value */
|
||||||
copy_from_user ( bytes, zsdt, offset, sizeof ( bytes ) );
|
memcpy ( bytes, ( ( ( const void * ) zsdt ) + offset ),
|
||||||
|
sizeof ( bytes ) );
|
||||||
DBGC ( colour, "ACPI found \\_Sx containing %02x:%02x:%02x:%02x\n",
|
DBGC ( colour, "ACPI found \\_Sx containing %02x:%02x:%02x:%02x\n",
|
||||||
bytes[0], bytes[1], bytes[2], bytes[3] );
|
bytes[0], bytes[1], bytes[2], bytes[3] );
|
||||||
|
|
||||||
@@ -111,8 +112,7 @@ static int acpi_extract_sx ( userptr_t zsdt, size_t len, size_t offset,
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int acpi_poweroff ( void ) {
|
int acpi_poweroff ( void ) {
|
||||||
struct acpi_fadt fadtab;
|
const struct acpi_fadt *fadt;
|
||||||
userptr_t fadt;
|
|
||||||
unsigned int pm1a_cnt_blk;
|
unsigned int pm1a_cnt_blk;
|
||||||
unsigned int pm1b_cnt_blk;
|
unsigned int pm1b_cnt_blk;
|
||||||
unsigned int pm1a_cnt;
|
unsigned int pm1a_cnt;
|
||||||
@@ -123,16 +123,16 @@ int acpi_poweroff ( void ) {
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Locate FADT */
|
/* Locate FADT */
|
||||||
fadt = acpi_table ( FADT_SIGNATURE, 0 );
|
fadt = container_of ( acpi_table ( FADT_SIGNATURE, 0 ),
|
||||||
|
struct acpi_fadt, acpi );
|
||||||
if ( ! fadt ) {
|
if ( ! fadt ) {
|
||||||
DBGC ( colour, "ACPI could not find FADT\n" );
|
DBGC ( colour, "ACPI could not find FADT\n" );
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read FADT */
|
/* Read FADT */
|
||||||
copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
|
pm1a_cnt_blk = le32_to_cpu ( fadt->pm1a_cnt_blk );
|
||||||
pm1a_cnt_blk = le32_to_cpu ( fadtab.pm1a_cnt_blk );
|
pm1b_cnt_blk = le32_to_cpu ( fadt->pm1b_cnt_blk );
|
||||||
pm1b_cnt_blk = le32_to_cpu ( fadtab.pm1b_cnt_blk );
|
|
||||||
pm1a_cnt = ( pm1a_cnt_blk + ACPI_PM1_CNT );
|
pm1a_cnt = ( pm1a_cnt_blk + ACPI_PM1_CNT );
|
||||||
pm1b_cnt = ( pm1b_cnt_blk + ACPI_PM1_CNT );
|
pm1b_cnt = ( pm1b_cnt_blk + ACPI_PM1_CNT );
|
||||||
|
|
||||||
|
|||||||
@@ -53,50 +53,51 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
*
|
*
|
||||||
* @v start Start address to search
|
* @v start Start address to search
|
||||||
* @v len Length to search
|
* @v len Length to search
|
||||||
* @ret rsdt ACPI root system description table, or UNULL
|
* @ret rsdt ACPI root system description table, or NULL
|
||||||
*/
|
*/
|
||||||
static userptr_t rsdp_find_rsdt_range ( userptr_t start, size_t len ) {
|
static const struct acpi_rsdt * rsdp_find_rsdt_range ( const void *start,
|
||||||
|
size_t len ) {
|
||||||
static const char signature[8] = RSDP_SIGNATURE;
|
static const char signature[8] = RSDP_SIGNATURE;
|
||||||
struct acpi_rsdp rsdp;
|
const struct acpi_rsdp *rsdp;
|
||||||
userptr_t rsdt;
|
const struct acpi_rsdt *rsdt;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
uint8_t sum;
|
uint8_t sum;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Search for RSDP */
|
/* Search for RSDP */
|
||||||
for ( offset = 0 ; ( ( offset + sizeof ( rsdp ) ) < len ) ;
|
for ( offset = 0 ; ( ( offset + sizeof ( *rsdp ) ) < len ) ;
|
||||||
offset += RSDP_STRIDE ) {
|
offset += RSDP_STRIDE ) {
|
||||||
|
|
||||||
/* Check signature and checksum */
|
/* Check signature and checksum */
|
||||||
copy_from_user ( &rsdp, start, offset, sizeof ( rsdp ) );
|
rsdp = ( start + offset );
|
||||||
if ( memcmp ( rsdp.signature, signature,
|
if ( memcmp ( rsdp->signature, signature,
|
||||||
sizeof ( signature ) ) != 0 )
|
sizeof ( signature ) ) != 0 )
|
||||||
continue;
|
continue;
|
||||||
for ( sum = 0, i = 0 ; i < sizeof ( rsdp ) ; i++ )
|
for ( sum = 0, i = 0 ; i < sizeof ( *rsdp ) ; i++ )
|
||||||
sum += *( ( ( uint8_t * ) &rsdp ) + i );
|
sum += *( ( ( uint8_t * ) rsdp ) + i );
|
||||||
if ( sum != 0 )
|
if ( sum != 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Extract RSDT */
|
/* Extract RSDT */
|
||||||
rsdt = phys_to_virt ( le32_to_cpu ( rsdp.rsdt ) );
|
rsdt = phys_to_virt ( le32_to_cpu ( rsdp->rsdt ) );
|
||||||
DBGC ( rsdt, "RSDT %#08lx found via RSDP %#08lx\n",
|
DBGC ( rsdt, "RSDT %#08lx found via RSDP %#08lx\n",
|
||||||
virt_to_phys ( rsdt ),
|
virt_to_phys ( rsdt ),
|
||||||
( virt_to_phys ( start ) + offset ) );
|
( virt_to_phys ( start ) + offset ) );
|
||||||
return rsdt;
|
return rsdt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locate ACPI root system description table
|
* Locate ACPI root system description table
|
||||||
*
|
*
|
||||||
* @ret rsdt ACPI root system description table, or UNULL
|
* @ret rsdt ACPI root system description table, or NULL
|
||||||
*/
|
*/
|
||||||
static userptr_t rsdp_find_rsdt ( void ) {
|
static const struct acpi_rsdt * rsdp_find_rsdt ( void ) {
|
||||||
static userptr_t rsdt;
|
static const struct acpi_rsdt *rsdt;
|
||||||
|
const void *ebda;
|
||||||
uint16_t ebda_seg;
|
uint16_t ebda_seg;
|
||||||
userptr_t ebda;
|
|
||||||
size_t ebda_len;
|
size_t ebda_len;
|
||||||
|
|
||||||
/* Return existing RSDT if already found */
|
/* Return existing RSDT if already found */
|
||||||
@@ -119,7 +120,7 @@ static userptr_t rsdp_find_rsdt ( void ) {
|
|||||||
if ( rsdt )
|
if ( rsdt )
|
||||||
return rsdt;
|
return rsdt;
|
||||||
|
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE_ACPI ( rsdp, acpi_find_rsdt, rsdp_find_rsdt );
|
PROVIDE_ACPI ( rsdp, acpi_find_rsdt, rsdp_find_rsdt );
|
||||||
|
|||||||
116
src/core/acpi.c
116
src/core/acpi.c
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <ipxe/uaccess.h>
|
#include <ipxe/uaccess.h>
|
||||||
@@ -54,25 +55,17 @@ typeof ( acpi_find ) *acpi_finder __attribute__ (( weak )) = acpi_find;
|
|||||||
/**
|
/**
|
||||||
* Compute ACPI table checksum
|
* Compute ACPI table checksum
|
||||||
*
|
*
|
||||||
* @v table Any ACPI table
|
* @v acpi Any ACPI table header
|
||||||
* @ret checksum 0 if checksum is good
|
* @ret checksum 0 if checksum is good
|
||||||
*/
|
*/
|
||||||
static uint8_t acpi_checksum ( userptr_t table ) {
|
static uint8_t acpi_checksum ( const struct acpi_header *acpi ) {
|
||||||
struct acpi_header acpi;
|
const uint8_t *byte = ( ( const void * ) acpi );
|
||||||
|
size_t len = le32_to_cpu ( acpi->length );
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
uint8_t data = 0;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* Read table length */
|
|
||||||
copy_from_user ( &acpi.length, table,
|
|
||||||
offsetof ( typeof ( acpi ), length ),
|
|
||||||
sizeof ( acpi.length ) );
|
|
||||||
|
|
||||||
/* Compute checksum */
|
/* Compute checksum */
|
||||||
for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
|
while ( len-- )
|
||||||
copy_from_user ( &data, table, i, sizeof ( data ) );
|
sum += *(byte++);
|
||||||
sum += data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
@@ -85,7 +78,7 @@ static uint8_t acpi_checksum ( userptr_t table ) {
|
|||||||
void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
||||||
|
|
||||||
/* Update checksum */
|
/* Update checksum */
|
||||||
acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
|
acpi->checksum -= acpi_checksum ( acpi );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,9 +86,10 @@ void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
|||||||
*
|
*
|
||||||
* @v signature Requested table signature
|
* @v signature Requested table signature
|
||||||
* @v index Requested index of table with this signature
|
* @v index Requested index of table with this signature
|
||||||
* @ret table Table, or UNULL if not found
|
* @ret table Table, or NULL if not found
|
||||||
*/
|
*/
|
||||||
userptr_t acpi_table ( uint32_t signature, unsigned int index ) {
|
const struct acpi_header * acpi_table ( uint32_t signature,
|
||||||
|
unsigned int index ) {
|
||||||
|
|
||||||
return ( *acpi_finder ) ( signature, index );
|
return ( *acpi_finder ) ( signature, index );
|
||||||
}
|
}
|
||||||
@@ -105,14 +99,12 @@ userptr_t acpi_table ( uint32_t signature, unsigned int index ) {
|
|||||||
*
|
*
|
||||||
* @v signature Requested table signature
|
* @v signature Requested table signature
|
||||||
* @v index Requested index of table with this signature
|
* @v index Requested index of table with this signature
|
||||||
* @ret table Table, or UNULL if not found
|
* @ret table Table, or NULL if not found
|
||||||
*/
|
*/
|
||||||
userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) {
|
const struct acpi_header * acpi_find_via_rsdt ( uint32_t signature,
|
||||||
struct acpi_header acpi;
|
unsigned int index ) {
|
||||||
struct acpi_rsdt *rsdtab;
|
const struct acpi_rsdt *rsdt;
|
||||||
typeof ( rsdtab->entry[0] ) entry;
|
const struct acpi_header *table;
|
||||||
userptr_t rsdt;
|
|
||||||
userptr_t table;
|
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@@ -121,45 +113,38 @@ userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) {
|
|||||||
rsdt = acpi_find_rsdt();
|
rsdt = acpi_find_rsdt();
|
||||||
if ( ! rsdt ) {
|
if ( ! rsdt ) {
|
||||||
DBG ( "RSDT not found\n" );
|
DBG ( "RSDT not found\n" );
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read RSDT header */
|
/* Read RSDT header */
|
||||||
copy_from_user ( &acpi, rsdt, 0, sizeof ( acpi ) );
|
if ( rsdt->acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) {
|
||||||
if ( acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) {
|
|
||||||
DBGC ( colour, "RSDT %#08lx has invalid signature:\n",
|
DBGC ( colour, "RSDT %#08lx has invalid signature:\n",
|
||||||
virt_to_phys ( rsdt ) );
|
virt_to_phys ( rsdt ) );
|
||||||
DBGC_HDA ( colour, virt_to_phys ( rsdt ), &acpi,
|
DBGC_HDA ( colour, virt_to_phys ( rsdt ), &rsdt->acpi,
|
||||||
sizeof ( acpi ) );
|
sizeof ( rsdt->acpi ) );
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
len = le32_to_cpu ( acpi.length );
|
len = le32_to_cpu ( rsdt->acpi.length );
|
||||||
if ( len < sizeof ( rsdtab->acpi ) ) {
|
if ( len < sizeof ( rsdt->acpi ) ) {
|
||||||
DBGC ( colour, "RSDT %#08lx has invalid length:\n",
|
DBGC ( colour, "RSDT %#08lx has invalid length:\n",
|
||||||
virt_to_phys ( rsdt ) );
|
virt_to_phys ( rsdt ) );
|
||||||
DBGC_HDA ( colour, virt_to_phys ( rsdt ), &acpi,
|
DBGC_HDA ( colour, virt_to_phys ( rsdt ), &rsdt->acpi,
|
||||||
sizeof ( acpi ) );
|
sizeof ( rsdt->acpi ) );
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate number of entries */
|
/* Calculate number of entries */
|
||||||
count = ( ( len - sizeof ( rsdtab->acpi ) ) / sizeof ( entry ) );
|
count = ( ( len - sizeof ( rsdt->acpi ) ) /
|
||||||
|
sizeof ( rsdt->entry[0] ) );
|
||||||
|
|
||||||
/* Search through entries */
|
/* Search through entries */
|
||||||
for ( i = 0 ; i < count ; i++ ) {
|
for ( i = 0 ; i < count ; i++ ) {
|
||||||
|
|
||||||
/* Get table address */
|
|
||||||
copy_from_user ( &entry, rsdt,
|
|
||||||
offsetof ( typeof ( *rsdtab ), entry[i] ),
|
|
||||||
sizeof ( entry ) );
|
|
||||||
|
|
||||||
/* Read table header */
|
/* Read table header */
|
||||||
table = phys_to_virt ( entry );
|
table = phys_to_virt ( rsdt->entry[i] );
|
||||||
copy_from_user ( &acpi.signature, table, 0,
|
|
||||||
sizeof ( acpi.signature ) );
|
|
||||||
|
|
||||||
/* Check table signature */
|
/* Check table signature */
|
||||||
if ( acpi.signature != cpu_to_le32 ( signature ) )
|
if ( table->signature != cpu_to_le32 ( signature ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Check index */
|
/* Check index */
|
||||||
@@ -169,13 +154,13 @@ userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) {
|
|||||||
/* Check table integrity */
|
/* Check table integrity */
|
||||||
if ( acpi_checksum ( table ) != 0 ) {
|
if ( acpi_checksum ( table ) != 0 ) {
|
||||||
DBGC ( colour, "RSDT %#08lx found %s with bad "
|
DBGC ( colour, "RSDT %#08lx found %s with bad "
|
||||||
"checksum at %08lx\n", virt_to_phys ( rsdt ),
|
"checksum at %#08lx\n", virt_to_phys ( rsdt ),
|
||||||
acpi_name ( signature ),
|
acpi_name ( signature ),
|
||||||
virt_to_phys ( table ) );
|
virt_to_phys ( table ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBGC ( colour, "RSDT %#08lx found %s at %08lx\n",
|
DBGC ( colour, "RSDT %#08lx found %s at %#08lx\n",
|
||||||
virt_to_phys ( rsdt ), acpi_name ( signature ),
|
virt_to_phys ( rsdt ), acpi_name ( signature ),
|
||||||
virt_to_phys ( table ) );
|
virt_to_phys ( table ) );
|
||||||
return table;
|
return table;
|
||||||
@@ -183,7 +168,7 @@ userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) {
|
|||||||
|
|
||||||
DBGC ( colour, "RSDT %#08lx could not find %s\n",
|
DBGC ( colour, "RSDT %#08lx could not find %s\n",
|
||||||
virt_to_phys ( rsdt ), acpi_name ( signature ) );
|
virt_to_phys ( rsdt ), acpi_name ( signature ) );
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,26 +180,27 @@ userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) {
|
|||||||
* @v extract Extraction method
|
* @v extract Extraction method
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int acpi_zsdt ( userptr_t zsdt, uint32_t signature, void *data,
|
static int acpi_zsdt ( const struct acpi_header *zsdt,
|
||||||
int ( * extract ) ( userptr_t zsdt, size_t len,
|
uint32_t signature, void *data,
|
||||||
size_t offset, void *data ) ) {
|
int ( * extract ) ( const struct acpi_header *zsdt,
|
||||||
struct acpi_header acpi;
|
size_t len, size_t offset,
|
||||||
|
void *data ) ) {
|
||||||
uint32_t buf;
|
uint32_t buf;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t len;
|
size_t len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Read table header */
|
/* Read table header */
|
||||||
copy_from_user ( &acpi, zsdt, 0, sizeof ( acpi ) );
|
len = le32_to_cpu ( zsdt->length );
|
||||||
len = le32_to_cpu ( acpi.length );
|
|
||||||
|
|
||||||
/* Locate signature */
|
/* Locate signature */
|
||||||
for ( offset = sizeof ( acpi ) ;
|
for ( offset = sizeof ( *zsdt ) ;
|
||||||
( ( offset + sizeof ( buf ) /* signature */ ) < len ) ;
|
( ( offset + sizeof ( buf ) /* signature */ ) < len ) ;
|
||||||
offset++ ) {
|
offset++ ) {
|
||||||
|
|
||||||
/* Check signature */
|
/* Check signature */
|
||||||
copy_from_user ( &buf, zsdt, offset, sizeof ( buf ) );
|
memcpy ( &buf, ( ( ( const void * ) zsdt ) + offset ),
|
||||||
|
sizeof ( buf ) );
|
||||||
if ( buf != cpu_to_le32 ( signature ) )
|
if ( buf != cpu_to_le32 ( signature ) )
|
||||||
continue;
|
continue;
|
||||||
DBGC ( zsdt, "DSDT/SSDT %#08lx found %s at offset %#zx\n",
|
DBGC ( zsdt, "DSDT/SSDT %#08lx found %s at offset %#zx\n",
|
||||||
@@ -238,20 +224,20 @@ static int acpi_zsdt ( userptr_t zsdt, uint32_t signature, void *data,
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int acpi_extract ( uint32_t signature, void *data,
|
int acpi_extract ( uint32_t signature, void *data,
|
||||||
int ( * extract ) ( userptr_t zsdt, size_t len,
|
int ( * extract ) ( const struct acpi_header *zsdt,
|
||||||
size_t offset, void *data ) ) {
|
size_t len, size_t offset,
|
||||||
struct acpi_fadt fadtab;
|
void *data ) ) {
|
||||||
userptr_t fadt;
|
const struct acpi_fadt *fadt;
|
||||||
userptr_t dsdt;
|
const struct acpi_header *dsdt;
|
||||||
userptr_t ssdt;
|
const struct acpi_header *ssdt;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Try DSDT first */
|
/* Try DSDT first */
|
||||||
fadt = acpi_table ( FADT_SIGNATURE, 0 );
|
fadt = container_of ( acpi_table ( FADT_SIGNATURE, 0 ),
|
||||||
|
struct acpi_fadt, acpi );
|
||||||
if ( fadt ) {
|
if ( fadt ) {
|
||||||
copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
|
dsdt = phys_to_virt ( fadt->dsdt );
|
||||||
dsdt = phys_to_virt ( fadtab.dsdt );
|
|
||||||
if ( ( rc = acpi_zsdt ( dsdt, signature, data,
|
if ( ( rc = acpi_zsdt ( dsdt, signature, data,
|
||||||
extract ) ) == 0 )
|
extract ) ) == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -64,14 +64,15 @@ static int acpi_settings_applies ( struct settings *settings __unused,
|
|||||||
static int acpi_settings_fetch ( struct settings *settings,
|
static int acpi_settings_fetch ( struct settings *settings,
|
||||||
struct setting *setting,
|
struct setting *setting,
|
||||||
void *data, size_t len ) {
|
void *data, size_t len ) {
|
||||||
struct acpi_header acpi;
|
const struct acpi_header *acpi;
|
||||||
|
const uint8_t *src;
|
||||||
|
uint8_t *dst;
|
||||||
uint32_t tag_high;
|
uint32_t tag_high;
|
||||||
uint32_t tag_low;
|
uint32_t tag_low;
|
||||||
uint32_t tag_signature;
|
uint32_t tag_signature;
|
||||||
unsigned int tag_index;
|
unsigned int tag_index;
|
||||||
size_t tag_offset;
|
size_t tag_offset;
|
||||||
size_t tag_len;
|
size_t tag_len;
|
||||||
userptr_t table;
|
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t max_len;
|
size_t max_len;
|
||||||
int delta;
|
int delta;
|
||||||
@@ -88,15 +89,12 @@ static int acpi_settings_fetch ( struct settings *settings,
|
|||||||
acpi_name ( tag_signature ), tag_index, tag_offset, tag_len );
|
acpi_name ( tag_signature ), tag_index, tag_offset, tag_len );
|
||||||
|
|
||||||
/* Locate ACPI table */
|
/* Locate ACPI table */
|
||||||
table = acpi_table ( tag_signature, tag_index );
|
acpi = acpi_table ( tag_signature, tag_index );
|
||||||
if ( ! table )
|
if ( ! acpi )
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
/* Read table header */
|
|
||||||
copy_from_user ( &acpi, table, 0, sizeof ( acpi ) );
|
|
||||||
|
|
||||||
/* Calculate starting offset and maximum available length */
|
/* Calculate starting offset and maximum available length */
|
||||||
max_len = le32_to_cpu ( acpi.length );
|
max_len = le32_to_cpu ( acpi->length );
|
||||||
if ( tag_offset > max_len )
|
if ( tag_offset > max_len )
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
offset = tag_offset;
|
offset = tag_offset;
|
||||||
@@ -115,10 +113,11 @@ static int acpi_settings_fetch ( struct settings *settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read data */
|
/* Read data */
|
||||||
|
src = ( ( ( const void * ) acpi ) + offset );
|
||||||
|
dst = data;
|
||||||
for ( i = 0 ; ( ( i < max_len ) && ( i < len ) ) ; i++ ) {
|
for ( i = 0 ; ( ( i < max_len ) && ( i < len ) ) ; i++ ) {
|
||||||
copy_from_user ( data, table, offset, 1 );
|
*(dst++) = *src;
|
||||||
data++;
|
src += delta;
|
||||||
offset += delta;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set type if not already specified */
|
/* Set type if not already specified */
|
||||||
|
|||||||
@@ -142,8 +142,9 @@ static struct acpimac_extractor acpimac_rtxmac = {
|
|||||||
* string that appears shortly after an "AMAC" or "MACA" signature.
|
* string that appears shortly after an "AMAC" or "MACA" signature.
|
||||||
* This should work for most implementations encountered in practice.
|
* This should work for most implementations encountered in practice.
|
||||||
*/
|
*/
|
||||||
static int acpimac_extract ( userptr_t zsdt, size_t len, size_t offset,
|
static int acpimac_extract ( const struct acpi_header *zsdt, size_t len,
|
||||||
void *data, struct acpimac_extractor *extractor ){
|
size_t offset, void *data,
|
||||||
|
struct acpimac_extractor *extractor ) {
|
||||||
size_t prefix_len = strlen ( extractor->prefix );
|
size_t prefix_len = strlen ( extractor->prefix );
|
||||||
uint8_t *hw_addr = data;
|
uint8_t *hw_addr = data;
|
||||||
size_t skip = 0;
|
size_t skip = 0;
|
||||||
@@ -161,7 +162,7 @@ static int acpimac_extract ( userptr_t zsdt, size_t len, size_t offset,
|
|||||||
skip++ ) {
|
skip++ ) {
|
||||||
|
|
||||||
/* Read value */
|
/* Read value */
|
||||||
copy_from_user ( buf, zsdt, ( offset + skip ),
|
memcpy ( buf, ( ( ( const void * ) zsdt ) + offset + skip ),
|
||||||
sizeof ( buf ) );
|
sizeof ( buf ) );
|
||||||
|
|
||||||
/* Check for expected format */
|
/* Check for expected format */
|
||||||
@@ -203,8 +204,8 @@ static int acpimac_extract ( userptr_t zsdt, size_t len, size_t offset,
|
|||||||
* @v data Data buffer
|
* @v data Data buffer
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int acpimac_extract_auxmac ( userptr_t zsdt, size_t len, size_t offset,
|
static int acpimac_extract_auxmac ( const struct acpi_header *zsdt,
|
||||||
void *data ) {
|
size_t len, size_t offset, void *data ) {
|
||||||
|
|
||||||
return acpimac_extract ( zsdt, len, offset, data, &acpimac_auxmac );
|
return acpimac_extract ( zsdt, len, offset, data, &acpimac_auxmac );
|
||||||
}
|
}
|
||||||
@@ -218,8 +219,8 @@ static int acpimac_extract_auxmac ( userptr_t zsdt, size_t len, size_t offset,
|
|||||||
* @v data Data buffer
|
* @v data Data buffer
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int acpimac_extract_rtxmac ( userptr_t zsdt, size_t len, size_t offset,
|
static int acpimac_extract_rtxmac ( const struct acpi_header *zsdt,
|
||||||
void *data ) {
|
size_t len, size_t offset, void *data ) {
|
||||||
|
|
||||||
return acpimac_extract ( zsdt, len, offset, data, &acpimac_rtxmac );
|
return acpimac_extract ( zsdt, len, offset, data, &acpimac_rtxmac );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,49 +46,43 @@ static struct ecam_mapping ecam;
|
|||||||
*/
|
*/
|
||||||
static int ecam_find ( uint32_t busdevfn, struct pci_range *range,
|
static int ecam_find ( uint32_t busdevfn, struct pci_range *range,
|
||||||
struct ecam_allocation *alloc ) {
|
struct ecam_allocation *alloc ) {
|
||||||
struct ecam_allocation tmp;
|
struct ecam_table *mcfg;
|
||||||
|
struct ecam_allocation *tmp;
|
||||||
unsigned int best = 0;
|
unsigned int best = 0;
|
||||||
unsigned int offset;
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
userptr_t mcfg;
|
unsigned int i;
|
||||||
uint32_t length;
|
|
||||||
uint32_t start;
|
uint32_t start;
|
||||||
|
|
||||||
/* Return empty range on error */
|
/* Return empty range on error */
|
||||||
range->count = 0;
|
range->count = 0;
|
||||||
|
|
||||||
/* Locate MCFG table */
|
/* Locate MCFG table */
|
||||||
mcfg = acpi_table ( ECAM_SIGNATURE, 0 );
|
mcfg = container_of ( acpi_table ( ECAM_SIGNATURE, 0 ),
|
||||||
|
struct ecam_table, acpi );
|
||||||
if ( ! mcfg ) {
|
if ( ! mcfg ) {
|
||||||
DBGC ( &ecam, "ECAM found no MCFG table\n" );
|
DBGC ( &ecam, "ECAM found no MCFG table\n" );
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get length of table */
|
|
||||||
copy_from_user ( &length, mcfg,
|
|
||||||
offsetof ( struct ecam_table, acpi.length ),
|
|
||||||
sizeof ( length ) );
|
|
||||||
|
|
||||||
/* Iterate over allocations */
|
/* Iterate over allocations */
|
||||||
for ( offset = offsetof ( struct ecam_table, alloc ) ;
|
for ( i = 0 ; ( offsetof ( typeof ( *mcfg ), alloc[ i + 1 ] ) <=
|
||||||
( offset + sizeof ( tmp ) ) <= le32_to_cpu ( length ) ;
|
le32_to_cpu ( mcfg->acpi.length ) ) ; i++ ) {
|
||||||
offset += sizeof ( tmp ) ) {
|
|
||||||
|
|
||||||
/* Read allocation */
|
/* Read allocation */
|
||||||
copy_from_user ( &tmp, mcfg, offset, sizeof ( tmp ) );
|
tmp = &mcfg->alloc[i];
|
||||||
DBGC2 ( &ecam, "ECAM %04x:[%02x-%02x] has base %08llx\n",
|
DBGC2 ( &ecam, "ECAM %04x:[%02x-%02x] has base %08llx\n",
|
||||||
le16_to_cpu ( tmp.segment ), tmp.start, tmp.end,
|
le16_to_cpu ( tmp->segment ), tmp->start, tmp->end,
|
||||||
( ( unsigned long long ) le64_to_cpu ( tmp.base ) ) );
|
( ( unsigned long long ) le64_to_cpu ( tmp->base ) ) );
|
||||||
start = PCI_BUSDEVFN ( le16_to_cpu ( tmp.segment ),
|
start = PCI_BUSDEVFN ( le16_to_cpu ( tmp->segment ),
|
||||||
tmp.start, 0, 0 );
|
tmp->start, 0, 0 );
|
||||||
count = PCI_BUSDEVFN ( 0, ( tmp.end - tmp.start + 1 ), 0, 0 );
|
count = PCI_BUSDEVFN ( 0, ( tmp->end - tmp->start + 1 ), 0, 0 );
|
||||||
|
|
||||||
/* Check for a matching or new closest allocation */
|
/* Check for a matching or new closest allocation */
|
||||||
index = ( busdevfn - start );
|
index = ( busdevfn - start );
|
||||||
if ( ( index < count ) || ( index > best ) ) {
|
if ( ( index < count ) || ( index > best ) ) {
|
||||||
if ( alloc )
|
if ( alloc )
|
||||||
memcpy ( alloc, &tmp, sizeof ( *alloc ) );
|
memcpy ( alloc, tmp, sizeof ( *alloc ) );
|
||||||
range->start = start;
|
range->start = start;
|
||||||
range->count = count;
|
range->count = count;
|
||||||
best = index;
|
best = index;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <ipxe/refcnt.h>
|
#include <ipxe/refcnt.h>
|
||||||
#include <ipxe/list.h>
|
#include <ipxe/list.h>
|
||||||
#include <ipxe/interface.h>
|
#include <ipxe/interface.h>
|
||||||
#include <ipxe/uaccess.h>
|
|
||||||
#include <ipxe/tables.h>
|
#include <ipxe/tables.h>
|
||||||
#include <ipxe/api.h>
|
#include <ipxe/api.h>
|
||||||
#include <config/general.h>
|
#include <config/general.h>
|
||||||
@@ -355,7 +354,8 @@ struct acpi_model {
|
|||||||
#define PROVIDE_ACPI_INLINE( _subsys, _api_func ) \
|
#define PROVIDE_ACPI_INLINE( _subsys, _api_func ) \
|
||||||
PROVIDE_SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
|
PROVIDE_SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
|
||||||
|
|
||||||
extern userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index );
|
extern const struct acpi_header * acpi_find_via_rsdt ( uint32_t signature,
|
||||||
|
unsigned int index );
|
||||||
|
|
||||||
/* Include all architecture-independent ACPI API headers */
|
/* Include all architecture-independent ACPI API headers */
|
||||||
#include <ipxe/null_acpi.h>
|
#include <ipxe/null_acpi.h>
|
||||||
@@ -368,31 +368,35 @@ extern userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index );
|
|||||||
/**
|
/**
|
||||||
* Locate ACPI root system description table
|
* Locate ACPI root system description table
|
||||||
*
|
*
|
||||||
* @ret rsdt ACPI root system description table, or UNULL
|
* @ret rsdt ACPI root system description table, or NULL
|
||||||
*/
|
*/
|
||||||
userptr_t acpi_find_rsdt ( void );
|
const struct acpi_rsdt * acpi_find_rsdt ( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locate ACPI table
|
* Locate ACPI table
|
||||||
*
|
*
|
||||||
* @v signature Requested table signature
|
* @v signature Requested table signature
|
||||||
* @v index Requested index of table with this signature
|
* @v index Requested index of table with this signature
|
||||||
* @ret table Table, or UNULL if not found
|
* @ret table Table, or NULL if not found
|
||||||
*/
|
*/
|
||||||
userptr_t acpi_find ( uint32_t signature, unsigned int index );
|
const struct acpi_header * acpi_find ( uint32_t signature,
|
||||||
|
unsigned int index );
|
||||||
|
|
||||||
extern struct acpi_descriptor *
|
extern struct acpi_descriptor *
|
||||||
acpi_describe ( struct interface *interface );
|
acpi_describe ( struct interface *interface );
|
||||||
#define acpi_describe_TYPE( object_type ) \
|
#define acpi_describe_TYPE( object_type ) \
|
||||||
typeof ( struct acpi_descriptor * ( object_type ) )
|
typeof ( struct acpi_descriptor * ( object_type ) )
|
||||||
|
|
||||||
extern userptr_t ( * acpi_finder ) ( uint32_t signature, unsigned int index );
|
extern const struct acpi_header * ( * acpi_finder ) ( uint32_t signature,
|
||||||
|
unsigned int index );
|
||||||
|
|
||||||
extern void acpi_fix_checksum ( struct acpi_header *acpi );
|
extern void acpi_fix_checksum ( struct acpi_header *acpi );
|
||||||
extern userptr_t acpi_table ( uint32_t signature, unsigned int index );
|
extern const struct acpi_header * acpi_table ( uint32_t signature,
|
||||||
|
unsigned int index );
|
||||||
extern int acpi_extract ( uint32_t signature, void *data,
|
extern int acpi_extract ( uint32_t signature, void *data,
|
||||||
int ( * extract ) ( userptr_t zsdt, size_t len,
|
int ( * extract ) ( const struct acpi_header *zsdt,
|
||||||
size_t offset, void *data ) );
|
size_t len, size_t offset,
|
||||||
|
void *data ) );
|
||||||
extern void acpi_add ( struct acpi_descriptor *desc );
|
extern void acpi_add ( struct acpi_descriptor *desc );
|
||||||
extern void acpi_del ( struct acpi_descriptor *desc );
|
extern void acpi_del ( struct acpi_descriptor *desc );
|
||||||
extern int acpi_install ( int ( * install ) ( struct acpi_header *acpi ) );
|
extern int acpi_install ( int ( * install ) ( struct acpi_header *acpi ) );
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
*
|
*
|
||||||
* @v signature Requested table signature
|
* @v signature Requested table signature
|
||||||
* @v index Requested index of table with this signature
|
* @v index Requested index of table with this signature
|
||||||
* @ret table Table, or UNULL if not found
|
* @ret table Table, or NULL if not found
|
||||||
*/
|
*/
|
||||||
static inline __attribute__ (( always_inline )) userptr_t
|
static inline __attribute__ (( always_inline )) const struct acpi_header *
|
||||||
ACPI_INLINE ( efi, acpi_find ) ( uint32_t signature, unsigned int index ) {
|
ACPI_INLINE ( efi, acpi_find ) ( uint32_t signature, unsigned int index ) {
|
||||||
|
|
||||||
return acpi_find_via_rsdt ( signature, index );
|
return acpi_find_via_rsdt ( signature, index );
|
||||||
|
|||||||
@@ -9,17 +9,19 @@
|
|||||||
|
|
||||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef ACPI_NULL
|
#ifdef ACPI_NULL
|
||||||
#define ACPI_PREFIX_null
|
#define ACPI_PREFIX_null
|
||||||
#else
|
#else
|
||||||
#define ACPI_PREFIX_null __null_
|
#define ACPI_PREFIX_null __null_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline __attribute__ (( always_inline )) userptr_t
|
static inline __attribute__ (( always_inline )) const struct acpi_header *
|
||||||
ACPI_INLINE ( null, acpi_find ) ( uint32_t signature __unused,
|
ACPI_INLINE ( null, acpi_find ) ( uint32_t signature __unused,
|
||||||
unsigned int index __unused ) {
|
unsigned int index __unused ) {
|
||||||
|
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _IPXE_NULL_ACPI_H */
|
#endif /* _IPXE_NULL_ACPI_H */
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ipxe/acpi.h>
|
#include <ipxe/acpi.h>
|
||||||
|
#include <ipxe/uaccess.h>
|
||||||
#include <ipxe/efi/efi.h>
|
#include <ipxe/efi/efi.h>
|
||||||
#include <ipxe/efi/Guid/Acpi.h>
|
#include <ipxe/efi/Guid/Acpi.h>
|
||||||
#include <ipxe/efi/efi_acpi.h>
|
#include <ipxe/efi/efi_acpi.h>
|
||||||
@@ -42,15 +43,15 @@ EFI_USE_TABLE ( ACPI_10_TABLE, &rsdp, 0 );
|
|||||||
/**
|
/**
|
||||||
* Locate ACPI root system description table
|
* Locate ACPI root system description table
|
||||||
*
|
*
|
||||||
* @ret rsdt ACPI root system description table, or UNULL
|
* @ret rsdt ACPI root system description table, or NULL
|
||||||
*/
|
*/
|
||||||
static userptr_t efi_find_rsdt ( void ) {
|
static const struct acpi_rsdt * efi_find_rsdt ( void ) {
|
||||||
|
|
||||||
/* Locate RSDT via ACPI configuration table, if available */
|
/* Locate RSDT via ACPI configuration table, if available */
|
||||||
if ( rsdp )
|
if ( rsdp )
|
||||||
return phys_to_virt ( rsdp->RsdtAddress );
|
return phys_to_virt ( rsdp->RsdtAddress );
|
||||||
|
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE_ACPI ( efi, acpi_find_rsdt, efi_find_rsdt );
|
PROVIDE_ACPI ( efi, acpi_find_rsdt, efi_find_rsdt );
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ struct linux_acpi_table {
|
|||||||
/** Index */
|
/** Index */
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
/** Cached data */
|
/** Cached data */
|
||||||
userptr_t data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** List of cached ACPI tables */
|
/** List of cached ACPI tables */
|
||||||
@@ -53,9 +53,10 @@ static LIST_HEAD ( linux_acpi_tables );
|
|||||||
*
|
*
|
||||||
* @v signature Requested table signature
|
* @v signature Requested table signature
|
||||||
* @v index Requested index of table with this signature
|
* @v index Requested index of table with this signature
|
||||||
* @ret table Table, or UNULL if not found
|
* @ret table Table, or NULL if not found
|
||||||
*/
|
*/
|
||||||
static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
|
static const struct acpi_header * linux_acpi_find ( uint32_t signature,
|
||||||
|
unsigned int index ) {
|
||||||
struct linux_acpi_table *table;
|
struct linux_acpi_table *table;
|
||||||
struct acpi_header *header;
|
struct acpi_header *header;
|
||||||
union {
|
union {
|
||||||
@@ -121,7 +122,7 @@ static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
|
|||||||
err_read:
|
err_read:
|
||||||
free ( table );
|
free ( table );
|
||||||
err_alloc:
|
err_alloc:
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
/* Forcibly enable assertions */
|
/* Forcibly enable assertions */
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <ipxe/acpi.h>
|
#include <ipxe/acpi.h>
|
||||||
#include <ipxe/acpimac.h>
|
#include <ipxe/acpimac.h>
|
||||||
#include <ipxe/if_ether.h>
|
#include <ipxe/if_ether.h>
|
||||||
@@ -185,26 +186,27 @@ static struct acpi_test_tables *acpi_test_tables;
|
|||||||
*
|
*
|
||||||
* @v signature Requested table signature
|
* @v signature Requested table signature
|
||||||
* @v index Requested index of table with this signature
|
* @v index Requested index of table with this signature
|
||||||
* @ret table Table, or UNULL if not found
|
* @ret table Table, or NULL if not found
|
||||||
*/
|
*/
|
||||||
static userptr_t acpi_test_find ( uint32_t signature, unsigned int index ) {
|
static const struct acpi_header * acpi_test_find ( uint32_t signature,
|
||||||
|
unsigned int index ) {
|
||||||
struct acpi_test_table *table;
|
struct acpi_test_table *table;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Fail if no test tables are installed */
|
/* Fail if no test tables are installed */
|
||||||
if ( ! acpi_test_tables )
|
if ( ! acpi_test_tables )
|
||||||
return UNULL;
|
return NULL;
|
||||||
|
|
||||||
/* Scan through test tables */
|
/* Scan through test tables */
|
||||||
for ( i = 0 ; i < acpi_test_tables->count ; i++ ) {
|
for ( i = 0 ; i < acpi_test_tables->count ; i++ ) {
|
||||||
table = acpi_test_tables->table[i];
|
table = acpi_test_tables->table[i];
|
||||||
if ( ( signature == le32_to_cpu ( table->signature.raw ) ) &&
|
if ( ( signature == le32_to_cpu ( table->signature.raw ) ) &&
|
||||||
( index-- == 0 ) ) {
|
( index-- == 0 ) ) {
|
||||||
return virt_to_user ( table->data );
|
return table->data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return UNULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Override ACPI table finder */
|
/** Override ACPI table finder */
|
||||||
|
|||||||
Reference in New Issue
Block a user