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  struct acpi_header acpi;
68  uint32_t tag_high;
69  uint32_t tag_low;
70  uint32_t tag_signature;
71  unsigned int tag_index;
72  size_t tag_offset;
73  size_t tag_len;
74  userptr_t table;
75  size_t offset;
76  size_t max_len;
77  int delta;
78  unsigned int i;
79 
80  /* Parse settings tag */
81  tag_high = ( setting->tag >> 32 );
82  tag_low = setting->tag;
83  tag_signature = bswap_32 ( tag_high );
84  tag_index = ( ( tag_low >> 24 ) & 0xff );
85  tag_offset = ( ( tag_low >> 8 ) & 0xffff );
86  tag_len = ( ( tag_low >> 0 ) & 0xff );
87  DBGC ( settings, "ACPI %s.%d offset %#zx length %#zx\n",
88  acpi_name ( tag_signature ), tag_index, tag_offset, tag_len );
89 
90  /* Locate ACPI table */
91  table = acpi_find ( tag_signature, tag_index );
92  if ( ! table )
93  return -ENOENT;
94 
95  /* Read table header */
96  copy_from_user ( &acpi, table, 0, sizeof ( acpi ) );
97 
98  /* Calculate starting offset and maximum available length */
99  max_len = le32_to_cpu ( acpi.length );
100  if ( tag_offset > max_len )
101  return -ENOENT;
102  offset = tag_offset;
103  max_len -= offset;
104 
105  /* Restrict to requested length, if specified */
106  if ( tag_len && ( tag_len < max_len ) )
107  max_len = tag_len;
108 
109  /* Invert endianness for numeric settings */
110  if ( setting->type && setting->type->numerate ) {
111  offset += ( max_len - 1 );
112  delta = -1;
113  } else {
114  delta = +1;
115  }
116 
117  /* Read data */
118  for ( i = 0 ; ( ( i < max_len ) && ( i < len ) ) ; i++ ) {
119  copy_from_user ( data, table, offset, 1 );
120  data++;
121  offset += delta;
122  }
123 
124  /* Set type if not already specified */
125  if ( ! setting->type )
126  setting->type = &setting_type_hexraw;
127 
128  return max_len;
129 }
130 
131 /** ACPI settings operations */
134  .fetch = acpi_settings_fetch,
135 };
136 
137 /** ACPI settings */
138 static struct settings acpi_settings = {
139  .refcnt = NULL,
140  .siblings = LIST_HEAD_INIT ( acpi_settings.siblings ),
141  .children = LIST_HEAD_INIT ( acpi_settings.children ),
143  .default_scope = &acpi_settings_scope,
144 };
145 
146 /** Initialise ACPI settings */
147 static void acpi_settings_init ( void ) {
148  int rc;
149 
150  if ( ( rc = register_settings ( &acpi_settings, NULL,
151  "acpi" ) ) != 0 ) {
152  DBG ( "ACPI could not register settings: %s\n",
153  strerror ( rc ) );
154  return;
155  }
156 }
157 
158 /** ACPI settings initialiser */
159 struct init_fn acpi_settings_init_fn __init_fn ( INIT_NORMAL ) = {
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.
void(* initialise)(void)
Definition: init.h:15
#define le32_to_cpu(value)
Definition: byteswap.h:113
static void size_t size_t max_len
Definition: entropy.h:153
Error codes.
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 ENOENT
No such file or directory.
Definition: errno.h:514
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:30
An initialisation function.
Definition: init.h:14
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:61
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
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
A setting scope.
Definition: settings.h:176
An ACPI description header.
Definition: acpi.h:28
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
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
uint32_t len
Length.
Definition: ena.h:14
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:55
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
userptr_t acpi_find(uint32_t signature, unsigned int index)
Locate ACPI table.
Definition: acpi.c:89
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:478
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#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:362
String functions.
struct refcnt * refcnt
Reference counter.
Definition: settings.h:134
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
static struct settings acpi_settings
ACPI settings.