iPXE
acpi_settings.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * ACPI settings
30  *
31  */
32 
33 #include <string.h>
34 #include <errno.h>
35 #include <ipxe/init.h>
36 #include <ipxe/settings.h>
37 #include <ipxe/acpi.h>
38 
39 /** ACPI settings scope */
40 static const struct settings_scope acpi_settings_scope;
41 
42 /**
43  * Check applicability of ACPI setting
44  *
45  * @v settings Settings block
46  * @v setting Setting
47  * @ret applies Setting applies within this settings block
48  */
50  const struct setting *setting ) {
51 
52  return ( setting->scope == &acpi_settings_scope );
53 }
54 
55 /**
56  * Fetch value of ACPI setting
57  *
58  * @v settings Settings block
59  * @v setting Setting to fetch
60  * @v data Buffer to fill with setting data
61  * @v len Length of buffer
62  * @ret len Length of setting data, or negative error
63  */
64 static int acpi_settings_fetch ( struct settings *settings,
65  struct setting *setting,
66  void *data, size_t len ) {
67  const struct acpi_header *acpi;
68  const uint8_t *src;
69  uint8_t *dst;
70  uint32_t tag_high;
71  uint32_t tag_low;
72  uint32_t tag_signature;
73  unsigned int tag_index;
74  size_t tag_offset;
75  size_t tag_len;
76  size_t offset;
77  size_t max_len;
78  int delta;
79  unsigned int i;
80 
81  /* Parse settings tag */
82  tag_high = ( setting->tag >> 32 );
83  tag_low = setting->tag;
84  tag_signature = bswap_32 ( tag_high );
85  tag_index = ( ( tag_low >> 24 ) & 0xff );
86  tag_offset = ( ( tag_low >> 8 ) & 0xffff );
87  tag_len = ( ( tag_low >> 0 ) & 0xff );
88  DBGC ( settings, "ACPI %s.%d offset %#zx length %#zx\n",
89  acpi_name ( tag_signature ), tag_index, tag_offset, tag_len );
90 
91  /* Locate ACPI table */
92  acpi = acpi_table ( tag_signature, tag_index );
93  if ( ! acpi )
94  return -ENOENT;
95 
96  /* Calculate starting offset and maximum available length */
97  max_len = le32_to_cpu ( acpi->length );
98  if ( tag_offset > max_len )
99  return -ENOENT;
100  offset = tag_offset;
101  max_len -= offset;
102 
103  /* Restrict to requested length, if specified */
104  if ( tag_len && ( tag_len < max_len ) )
105  max_len = tag_len;
106 
107  /* Invert endianness for numeric settings */
108  if ( setting->type && setting->type->numerate ) {
109  offset += ( max_len - 1 );
110  delta = -1;
111  } else {
112  delta = +1;
113  }
114 
115  /* Read data */
116  src = ( ( ( const void * ) acpi ) + offset );
117  dst = data;
118  for ( i = 0 ; ( ( i < max_len ) && ( i < len ) ) ; i++ ) {
119  *(dst++) = *src;
120  src += delta;
121  }
122 
123  /* Set type if not already specified */
124  if ( ! setting->type )
125  setting->type = &setting_type_hexraw;
126 
127  return max_len;
128 }
129 
130 /** ACPI settings operations */
133  .fetch = acpi_settings_fetch,
134 };
135 
136 /** ACPI settings */
137 static struct settings acpi_settings = {
138  .refcnt = NULL,
139  .siblings = LIST_HEAD_INIT ( acpi_settings.siblings ),
140  .children = LIST_HEAD_INIT ( acpi_settings.children ),
142  .default_scope = &acpi_settings_scope,
143 };
144 
145 /** Initialise ACPI settings */
146 static void acpi_settings_init ( void ) {
147  int rc;
148 
149  if ( ( rc = register_settings ( &acpi_settings, NULL,
150  "acpi" ) ) != 0 ) {
151  DBG ( "ACPI could not register settings: %s\n",
152  strerror ( rc ) );
153  return;
154  }
155 }
156 
157 /** ACPI settings initialiser */
158 struct init_fn acpi_settings_init_fn __init_fn ( INIT_NORMAL ) = {
159  .name = "acpi",
160  .initialise = acpi_settings_init,
161 };
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct init_fn acpi_settings_init_fn __init_fn(INIT_NORMAL)
ACPI settings initialiser.
#define le32_to_cpu(value)
Definition: byteswap.h:113
Error codes.
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
const struct acpi_header * acpi_table(uint32_t signature, unsigned int index)
Locate ACPI table.
Definition: acpi.c:92
static struct settings_operations acpi_settings_operations
ACPI settings operations.
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:31
An initialisation function.
Definition: init.h:14
static const void * src
Definition: string.h:47
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:66
ring len
Length.
Definition: dwmac.h:231
const char * name
Definition: init.h:15
const struct setting_type * type
Setting type.
Definition: settings.h:36
#define bswap_32(value)
Definition: byteswap.h:70
Configuration settings.
int(* numerate)(const struct setting_type *type, const void *raw, size_t raw_len, unsigned long *value)
Convert setting value to number.
Definition: settings.h:237
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
ACPI data structures.
static void acpi_settings_init(void)
Initialise ACPI settings.
Settings block operations.
Definition: settings.h:85
A settings block.
Definition: settings.h:132
unsigned char uint8_t
Definition: stdint.h:10
A setting scope.
Definition: settings.h:176
An ACPI description header.
Definition: acpi.h:179
unsigned int uint32_t
Definition: stdint.h:12
struct list_head siblings
Sibling settings blocks.
Definition: settings.h:140
A setting.
Definition: settings.h:23
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:206
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static int acpi_settings_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of ACPI setting.
Definition: acpi_settings.c:64
static int acpi_settings_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of ACPI setting.
Definition: acpi_settings.c:49
int(* applies)(struct settings *settings, const struct setting *setting)
Check applicability of setting.
Definition: settings.h:98
struct list_head children
Child settings blocks.
Definition: settings.h:142
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static const struct settings_scope acpi_settings_scope
ACPI settings scope.
Definition: acpi_settings.c:40
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:49
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
struct refcnt * refcnt
Reference counter.
Definition: settings.h:134
static struct settings acpi_settings
ACPI settings.