iPXE
Macros | Functions
acpi.c File Reference

ACPI support functions. More...

#include <errno.h>
#include <byteswap.h>
#include <ipxe/uaccess.h>
#include <ipxe/acpi.h>
#include <ipxe/interface.h>

Go to the source code of this file.

Macros

#define colour   FADT_SIGNATURE
 Colour for debug messages. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 typeof (acpi_finder=acpi_find)
 ACPI table finder. More...
 
void acpi_fix_checksum (struct acpi_header *acpi)
 Fix up ACPI table checksum. More...
 
userptr_t acpi_table (uint32_t signature, unsigned int index)
 Locate ACPI table. More...
 
userptr_t acpi_find_via_rsdt (uint32_t signature, unsigned int index)
 Locate ACPI table via RSDT. More...
 
static int acpi_zsdt (userptr_t zsdt, uint32_t signature, void *data, int(*extract)(userptr_t zsdt, size_t len, size_t offset, void *data))
 Extract value from DSDT/SSDT. More...
 
int acpi_extract (uint32_t signature, void *data, int(*extract)(userptr_t zsdt, size_t len, size_t offset, void *data))
 Extract value from DSDT/SSDT. More...
 
void acpi_add (struct acpi_descriptor *desc)
 Add ACPI descriptor. More...
 
void acpi_del (struct acpi_descriptor *desc)
 Remove ACPI descriptor. More...
 
struct acpi_descriptoracpi_describe (struct interface *intf)
 Get object's ACPI descriptor. More...
 
int acpi_install (int(*install)(struct acpi_header *acpi))
 Install ACPI tables. More...
 

Detailed Description

ACPI support functions.

Definition in file acpi.c.

Macro Definition Documentation

◆ colour

#define colour   FADT_SIGNATURE

Colour for debug messages.

Definition at line 39 of file acpi.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ typeof()

typeof ( acpi_finder acpi_find)

ACPI table finder.

May be overridden at link time to inject tables for testing.Compute ACPI table checksum

Parameters
tableAny ACPI table
Return values
checksum0 if checksum is good

Definition at line 45 of file acpi.c.

60  {
61  struct acpi_header acpi;
62  uint8_t sum = 0;
63  uint8_t data = 0;
64  unsigned int i;
65 
66  /* Read table length */
67  copy_from_user ( &acpi.length, table,
68  offsetof ( typeof ( acpi ), length ),
69  sizeof ( acpi.length ) );
70 
71  /* Compute checksum */
72  for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
73  copy_from_user ( &data, table, i, sizeof ( data ) );
74  sum += data;
75  }
76 
77  return sum;
78 }
u16 length
Definition: sky2.h:9
#define le32_to_cpu(value)
Definition: byteswap.h:113
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:65
unsigned char uint8_t
Definition: stdint.h:10
An ACPI description header.
Definition: acpi.h:163
uint8_t data[48]
Additional event data.
Definition: ena.h:22
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45

References acpi, copy_from_user(), data, le32_to_cpu, length, and offsetof.

Referenced by acpi_find_via_rsdt(), aes_entry_column(), ar9002_hw_proc_txdesc(), ar9003_hw_proc_txdesc(), arbel_create_recv_wq(), arbel_fill_mlx_send_wqe(), arbel_fill_rc_send_wqe(), arbel_fill_ud_send_wqe(), asn1_bit_string(), asn1_built(), dhcpv6_iaaddr(), dhcpv6_rx(), dns_question(), dns_resolv(), dns_xfer_deliver(), draw_setting_row(), efi_ifr_string(), efi_nullify_pxe(), efi_nullify_snp(), efi_path_uri(), efi_pxe_ip_filter(), efi_pxe_ip_sockaddr(), exanic_poll_rx(), exanic_transmit(), fc_fill_sockaddr(), fcoe_deliver(), fcoe_fip_rx_els_response(), gve_poll_rx(), hash_df(), hermon_fill_eth_send_wqe(), hermon_fill_mlx_send_wqe(), hermon_fill_rc_send_wqe(), hermon_fill_ud_send_wqe(), hv_wait_for_message(), ib_sbft_install(), ibft_install(), int13_extended_rw(), int13_get_extended_parameters(), int13_load_eltorito(), interrupt_dump(), ipv6conf_rx_router_advertisement(), jme_poll(), list_test_exec(), md4_final(), md5_final(), meme820(), natsemi_create_ring(), ncm_in_complete(), ncm_out_transmit(), ndp_rx_neighbour(), ndp_rx_neighbour_advertisement_ll_target(), ndp_rx_neighbour_solicitation_ll_source(), ndp_rx_router_advertisement(), ndp_rx_router_advertisement_ll_source(), ntlm_response(), peerblk_parse_block(), peerblk_parse_useless(), peerblk_retrieval_open(), peerdist_info_v1_block(), pxebs_list(), select_setting_row(), sha1_final(), sha256_final(), sha512_final(), tls_client_hello(), tls_send_certificate(), tls_send_client_key_exchange_dhe(), usb_describe(), and usb_get_mtu().

◆ acpi_fix_checksum()

void acpi_fix_checksum ( struct acpi_header acpi)

Fix up ACPI table checksum.

Parameters
acpiACPI table header

Definition at line 85 of file acpi.c.

85  {
86 
87  /* Update checksum */
88  acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
89 }
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:65
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.

References acpi, and virt_to_user().

Referenced by efi_block_install(), and int13_install().

◆ acpi_table()

userptr_t acpi_table ( uint32_t  signature,
unsigned int  index 
)

Locate ACPI table.

Parameters
signatureRequested table signature
indexRequested index of table with this signature
Return values
tableTable, or UNULL if not found

Definition at line 98 of file acpi.c.

98  {
99 
100  return ( *acpi_finder ) ( signature, index );
101 }
long index
Definition: bigint.h:61
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
userptr_t(* acpi_finder)(uint32_t signature, unsigned int index)

References acpi_finder, index, and signature.

Referenced by acpi_extract(), acpi_poweroff(), acpi_settings_fetch(), acpi_timer_probe(), and ecam_find().

◆ acpi_find_via_rsdt()

userptr_t acpi_find_via_rsdt ( uint32_t  signature,
unsigned int  index 
)

Locate ACPI table via RSDT.

Parameters
signatureRequested table signature
indexRequested index of table with this signature
Return values
tableTable, or UNULL if not found

Definition at line 110 of file acpi.c.

110  {
111  struct acpi_header acpi;
112  struct acpi_rsdt *rsdtab;
113  typeof ( rsdtab->entry[0] ) entry;
114  userptr_t rsdt;
115  userptr_t table;
116  size_t len;
117  unsigned int count;
118  unsigned int i;
119 
120  /* Locate RSDT */
121  rsdt = acpi_find_rsdt();
122  if ( ! rsdt ) {
123  DBG ( "RSDT not found\n" );
124  return UNULL;
125  }
126 
127  /* Read RSDT header */
128  copy_from_user ( &acpi, rsdt, 0, sizeof ( acpi ) );
129  if ( acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) {
130  DBGC ( colour, "RSDT %#08lx has invalid signature:\n",
131  user_to_phys ( rsdt, 0 ) );
132  DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi,
133  sizeof ( acpi ) );
134  return UNULL;
135  }
136  len = le32_to_cpu ( acpi.length );
137  if ( len < sizeof ( rsdtab->acpi ) ) {
138  DBGC ( colour, "RSDT %#08lx has invalid length:\n",
139  user_to_phys ( rsdt, 0 ) );
140  DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi,
141  sizeof ( acpi ) );
142  return UNULL;
143  }
144 
145  /* Calculate number of entries */
146  count = ( ( len - sizeof ( rsdtab->acpi ) ) / sizeof ( entry ) );
147 
148  /* Search through entries */
149  for ( i = 0 ; i < count ; i++ ) {
150 
151  /* Get table address */
152  copy_from_user ( &entry, rsdt,
153  offsetof ( typeof ( *rsdtab ), entry[i] ),
154  sizeof ( entry ) );
155 
156  /* Read table header */
157  table = phys_to_user ( entry );
158  copy_from_user ( &acpi.signature, table, 0,
159  sizeof ( acpi.signature ) );
160 
161  /* Check table signature */
162  if ( acpi.signature != cpu_to_le32 ( signature ) )
163  continue;
164 
165  /* Check index */
166  if ( index-- )
167  continue;
168 
169  /* Check table integrity */
170  if ( acpi_checksum ( table ) != 0 ) {
171  DBGC ( colour, "RSDT %#08lx found %s with bad "
172  "checksum at %08lx\n", user_to_phys ( rsdt, 0 ),
173  acpi_name ( signature ),
174  user_to_phys ( table, 0 ) );
175  break;
176  }
177 
178  DBGC ( colour, "RSDT %#08lx found %s at %08lx\n",
179  user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
180  user_to_phys ( table, 0 ) );
181  return table;
182  }
183 
184  DBGC ( colour, "RSDT %#08lx could not find %s\n",
185  user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
186  return UNULL;
187 }
#define RSDT_SIGNATURE
Root System Description Table (RSDT) signature.
Definition: acpi.h:230
#define le32_to_cpu(value)
Definition: byteswap.h:113
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
unsigned long user_to_phys(userptr_t userptr, off_t offset)
Convert user pointer to physical address.
#define DBGC(...)
Definition: compiler.h:505
long index
Definition: bigint.h:61
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
ACPI Root System Description Table (RSDT)
Definition: acpi.h:233
uint32_t userptr_t
A pointer to a user buffer.
Definition: libkir.h:159
#define colour
Colour for debug messages.
Definition: acpi.c:39
#define DBGC_HDA(...)
Definition: compiler.h:506
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:65
uint32_t entry[0]
ACPI table entries.
Definition: acpi.h:237
uint16_t count
Number of entries.
Definition: ena.h:22
#define cpu_to_le32(value)
Definition: byteswap.h:107
userptr_t acpi_find_rsdt(void)
Locate ACPI root system description table.
An ACPI description header.
Definition: acpi.h:163
struct acpi_header acpi
ACPI header.
Definition: acpi.h:235
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:190
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
uint32_t len
Length.
Definition: ena.h:14
if(natsemi->flags &NATSEMI_64BIT) return 1

References acpi, acpi_rsdt::acpi, acpi_find_rsdt(), acpi_name(), colour, copy_from_user(), count, cpu_to_le32, DBG, DBGC, DBGC_HDA, acpi_rsdt::entry, index, le32_to_cpu, len, offsetof, phys_to_user(), RSDT_SIGNATURE, signature, typeof(), UNULL, and user_to_phys().

Referenced by acpi_find().

◆ acpi_zsdt()

static int acpi_zsdt ( userptr_t  zsdt,
uint32_t  signature,
void *  data,
int(*)(userptr_t zsdt, size_t len, size_t offset, void *data extract 
)
static

Extract value from DSDT/SSDT.

Parameters
zsdtDSDT or SSDT
signatureSignature (e.g. "_S5_")
dataData buffer
extractExtraction method
Return values
rcReturn status code

Definition at line 198 of file acpi.c.

200  {
201  struct acpi_header acpi;
202  uint32_t buf;
203  size_t offset;
204  size_t len;
205  int rc;
206 
207  /* Read table header */
208  copy_from_user ( &acpi, zsdt, 0, sizeof ( acpi ) );
209  len = le32_to_cpu ( acpi.length );
210 
211  /* Locate signature */
212  for ( offset = sizeof ( acpi ) ;
213  ( ( offset + sizeof ( buf ) /* signature */ ) < len ) ;
214  offset++ ) {
215 
216  /* Check signature */
217  copy_from_user ( &buf, zsdt, offset, sizeof ( buf ) );
218  if ( buf != cpu_to_le32 ( signature ) )
219  continue;
220  DBGC ( zsdt, "DSDT/SSDT %#08lx found %s at offset %#zx\n",
221  user_to_phys ( zsdt, 0 ), acpi_name ( signature ),
222  offset );
223 
224  /* Attempt to extract data */
225  if ( ( rc = extract ( zsdt, len, offset, data ) ) == 0 )
226  return 0;
227  }
228 
229  return -ENOENT;
230 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define le32_to_cpu(value)
Definition: byteswap.h:113
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
unsigned long user_to_phys(userptr_t userptr, off_t offset)
Convert user pointer to physical address.
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:65
#define cpu_to_le32(value)
Definition: byteswap.h:107
An ACPI description header.
Definition: acpi.h:163
unsigned int uint32_t
Definition: stdint.h:12
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:190
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
uint32_t len
Length.
Definition: ena.h:14

References acpi, acpi_name(), copy_from_user(), cpu_to_le32, data, DBGC, ENOENT, le32_to_cpu, len, offset, rc, signature, and user_to_phys().

Referenced by acpi_extract().

◆ acpi_extract()

int acpi_extract ( uint32_t  signature,
void *  data,
int(*)(userptr_t zsdt, size_t len, size_t offset, void *data extract 
)

Extract value from DSDT/SSDT.

Parameters
signatureSignature (e.g. "_S5_")
dataData buffer
extractExtraction method
Return values
rcReturn status code

Definition at line 240 of file acpi.c.

242  {
243  struct acpi_fadt fadtab;
244  userptr_t fadt;
245  userptr_t dsdt;
246  userptr_t ssdt;
247  unsigned int i;
248  int rc;
249 
250  /* Try DSDT first */
251  fadt = acpi_table ( FADT_SIGNATURE, 0 );
252  if ( fadt ) {
253  copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
254  dsdt = phys_to_user ( fadtab.dsdt );
255  if ( ( rc = acpi_zsdt ( dsdt, signature, data,
256  extract ) ) == 0 )
257  return 0;
258  }
259 
260  /* Try all SSDTs */
261  for ( i = 0 ; ; i++ ) {
262  ssdt = acpi_table ( SSDT_SIGNATURE, i );
263  if ( ! ssdt )
264  break;
265  if ( ( rc = acpi_zsdt ( ssdt, signature, data,
266  extract ) ) == 0 )
267  return 0;
268  }
269 
270  DBGC ( colour, "ACPI could not find \"%s\"\n",
271  acpi_name ( signature ) );
272  return -ENOENT;
273 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
#define SSDT_SIGNATURE
Secondary System Description Table (SSDT) signature.
Definition: acpi.h:275
userptr_t acpi_table(uint32_t signature, unsigned int index)
Locate ACPI table.
Definition: acpi.c:98
#define ENOENT
No such file or directory.
Definition: errno.h:514
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
uint32_t userptr_t
A pointer to a user buffer.
Definition: libkir.h:159
#define colour
Colour for debug messages.
Definition: acpi.c:39
Fixed ACPI Description Table (FADT)
Definition: acpi.h:244
#define FADT_SIGNATURE
Fixed ACPI Description Table (FADT) signature.
Definition: acpi.h:241
uint32_t dsdt
Physical address of DSDT.
Definition: acpi.h:250
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:190
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static int acpi_zsdt(userptr_t zsdt, uint32_t signature, void *data, int(*extract)(userptr_t zsdt, size_t len, size_t offset, void *data))
Extract value from DSDT/SSDT.
Definition: acpi.c:198
u8 signature
CPU signature.
Definition: CIB_PRM.h:35

References acpi_name(), acpi_table(), acpi_zsdt(), colour, copy_from_user(), data, DBGC, acpi_fadt::dsdt, ENOENT, FADT_SIGNATURE, phys_to_user(), rc, signature, and SSDT_SIGNATURE.

Referenced by acpi_mac(), and acpi_poweroff().

◆ acpi_add()

void acpi_add ( struct acpi_descriptor desc)

Add ACPI descriptor.

Parameters
descACPI descriptor

Definition at line 287 of file acpi.c.

287  {
288 
289  /* Add to list of descriptors */
290  ref_get ( desc->refcnt );
291  list_add_tail ( &desc->list, &desc->model->descs );
292 }
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92

References desc, list_add_tail, and ref_get.

Referenced by sanpath_open().

◆ acpi_del()

void acpi_del ( struct acpi_descriptor desc)

Remove ACPI descriptor.

Parameters
descACPI descriptor

Definition at line 299 of file acpi.c.

299  {
300 
301  /* Remove from list of descriptors */
302  list_check_contains_entry ( desc, &desc->model->descs, list );
303  list_del ( &desc->list );
304  ref_put ( desc->refcnt );
305 }
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition: list.h:549
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References desc, list_check_contains_entry, list_del, and ref_put.

Referenced by sandev_undescribe(), and sanpath_open().

◆ acpi_describe()

struct acpi_descriptor* acpi_describe ( struct interface intf)

Get object's ACPI descriptor.

Parameters
intfInterface
Return values
descACPI descriptor, or NULL

Definition at line 313 of file acpi.c.

313  {
314  struct interface *dest;
315  acpi_describe_TYPE ( void * ) *op =
317  void *object = intf_object ( dest );
318  struct acpi_descriptor *desc;
319 
320  if ( op ) {
321  desc = op ( object );
322  } else {
323  desc = NULL;
324  }
325 
326  intf_put ( dest );
327  return desc;
328 }
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
void * intf_object(struct interface *intf)
Get pointer to object containing object interface.
Definition: interface.c:159
struct interface * intf
Original interface.
Definition: interface.h:158
An object interface.
Definition: interface.h:124
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:313
#define acpi_describe_TYPE(object_type)
Definition: acpi.h:386
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
An ACPI descriptor (used to construct ACPI tables)
Definition: acpi.h:278
void intf_put(struct interface *intf)
Decrement reference count on an object interface.
Definition: interface.c:149
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
Definition: string.h:150
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define intf_get_dest_op(intf, type, dest)
Get object interface destination and operation method.
Definition: interface.h:269

References acpi_describe(), acpi_describe_TYPE, desc, dest, interface::intf, intf_get_dest_op, intf_object(), intf_put(), NULL, and op.

Referenced by acpi_describe(), and sanpath_open().

◆ acpi_install()

int acpi_install ( int(*)(struct acpi_header *acpi install)

Install ACPI tables.

Parameters
installTable installation method
Return values
rcReturn status code

Definition at line 336 of file acpi.c.

336  {
337  struct acpi_model *model;
338  int rc;
339 
340  for_each_table_entry ( model, ACPI_MODELS ) {
341  if ( ( rc = model->install ( install ) ) != 0 )
342  return rc;
343  }
344 
345  return 0;
346 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int(* install)(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition: acpi.h:320
An ACPI table model.
Definition: acpi.h:304
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define ACPI_MODELS
ACPI models.
Definition: acpi.h:324

References ACPI_MODELS, for_each_table_entry, acpi_model::install, and rc.

Referenced by dummy_san_describe(), efi_block_describe(), and int13_describe().