1 #ifndef _IPXE_ACPI_H
2 #define _IPXE_ACPI_H
3
4 /** @file
5 *
6 * ACPI data structures
7 *
8 */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <stdint.h>
13 #include <byteswap.h>
14 #include <ipxe/refcnt.h>
15 #include <ipxe/list.h>
16 #include <ipxe/interface.h>
17 #include <ipxe/uaccess.h>
18 #include <ipxe/tables.h>
19 #include <ipxe/api.h>
20 #include <config/general.h>
21
22 /**
23 * An ACPI description header
24 *
25 * This is the structure common to the start of all ACPI system
26 * description tables.
27 */
28 struct acpi_header {
29 /** ACPI signature (4 ASCII characters) */
30 uint32_t signature;
31 /** Length of table, in bytes, including header */
32 uint32_t length;
33 /** ACPI Specification minor version number */
34 uint8_t revision;
35 /** To make sum of entire table == 0 */
36 uint8_t checksum;
37 /** OEM identification */
38 char oem_id[6];
39 /** OEM table identification */
40 char oem_table_id[8];
41 /** OEM revision number */
42 uint32_t oem_revision;
43 /** ASL compiler vendor ID */
44 char asl_compiler_id[4];
45 /** ASL compiler revision number */
46 uint32_t asl_compiler_revision;
47 } __attribute__ (( packed ));
48
49 /**
50 * Transcribe ACPI table signature (for debugging)
51 *
52 * @v signature ACPI table signature
53 * @ret name ACPI table signature name
54 */
acpi_name(uint32_t signature)55 static inline const char * acpi_name ( uint32_t signature ) {
56 static union {
57 uint32_t signature;
58 char name[5];
59 } u;
60
61 u.signature = cpu_to_le32 ( signature );
62 return u.name;
63 }
64
65 /**
66 * Build ACPI signature
67 *
68 * @v a First character of ACPI signature
69 * @v b Second character of ACPI signature
70 * @v c Third character of ACPI signature
71 * @v d Fourth character of ACPI signature
72 * @ret signature ACPI signature
73 */
74 #define ACPI_SIGNATURE( a, b, c, d ) \
75 ( ( (a) << 0 ) | ( (b) << 8 ) | ( (c) << 16 ) | ( (d) << 24 ) )
76
77 /** Root System Description Pointer signature */
78 #define RSDP_SIGNATURE { 'R', 'S', 'D', ' ', 'P', 'T', 'R', ' ' }
79
80 /** Root System Description Pointer */
81 struct acpi_rsdp {
82 /** Signature */
83 char signature[8];
84 /** To make sum of entire table == 0 */
85 uint8_t checksum;
86 /** OEM identification */
87 char oem_id[6];
88 /** Revision */
89 uint8_t revision;
90 /** Physical address of RSDT */
91 uint32_t rsdt;
92 } __attribute__ (( packed ));
93
94 /** Root System Description Table (RSDT) signature */
95 #define RSDT_SIGNATURE ACPI_SIGNATURE ( 'R', 'S', 'D', 'T' )
96
97 /** ACPI Root System Description Table (RSDT) */
98 struct acpi_rsdt {
99 /** ACPI header */
100 struct acpi_header acpi;
101 /** ACPI table entries */
102 uint32_t entry[0];
103 } __attribute__ (( packed ));
104
105 /** Fixed ACPI Description Table (FADT) signature */
106 #define FADT_SIGNATURE ACPI_SIGNATURE ( 'F', 'A', 'C', 'P' )
107
108 /** Fixed ACPI Description Table (FADT) */
109 struct acpi_fadt {
110 /** ACPI header */
111 struct acpi_header acpi;
112 /** Physical address of FACS */
113 uint32_t facs;
114 /** Physical address of DSDT */
115 uint32_t dsdt;
116 /** Unused by iPXE */
117 uint8_t unused[20];
118 /** PM1a Control Register Block */
119 uint32_t pm1a_cnt_blk;
120 /** PM1b Control Register Block */
121 uint32_t pm1b_cnt_blk;
122 } __attribute__ (( packed ));
123
124 /** ACPI PM1 Control Register (within PM1a_CNT_BLK or PM1A_CNT_BLK) */
125 #define ACPI_PM1_CNT 0
126 #define ACPI_PM1_CNT_SLP_TYP(x) ( (x) << 10 ) /**< Sleep type */
127 #define ACPI_PM1_CNT_SLP_EN ( 1 << 13 ) /**< Sleep enable */
128
129 /** Differentiated System Description Table (DSDT) signature */
130 #define DSDT_SIGNATURE ACPI_SIGNATURE ( 'D', 'S', 'D', 'T' )
131
132 /** Secondary System Description Table (SSDT) signature */
133 #define SSDT_SIGNATURE ACPI_SIGNATURE ( 'S', 'S', 'D', 'T' )
134
135 /** An ACPI descriptor (used to construct ACPI tables) */
136 struct acpi_descriptor {
137 /** Reference count of containing object */
138 struct refcnt *refcnt;
139 /** Table model */
140 struct acpi_model *model;
141 /** List of ACPI descriptors for this model */
142 struct list_head list;
143 };
144
145 /**
146 * Initialise ACPI descriptor
147 *
148 * @v desc ACPI descriptor
149 * @v model Table model
150 * @v refcnt Reference count
151 */
152 static inline __attribute__ (( always_inline )) void
acpi_init(struct acpi_descriptor * desc,struct acpi_model * model,struct refcnt * refcnt)153 acpi_init ( struct acpi_descriptor *desc, struct acpi_model *model,
154 struct refcnt *refcnt ) {
155
156 desc->refcnt = refcnt;
157 desc->model = model;
158 INIT_LIST_HEAD ( &desc->list );
159 }
160
161 /** An ACPI table model */
162 struct acpi_model {
163 /** List of descriptors */
164 struct list_head descs;
165 /**
166 * Check if ACPI descriptor is complete
167 *
168 * @v desc ACPI descriptor
169 * @ret rc Return status code
170 */
171 int ( * complete ) ( struct acpi_descriptor *desc );
172 /**
173 * Install ACPI tables
174 *
175 * @v install Installation method
176 * @ret rc Return status code
177 */
178 int ( * install ) ( int ( * install ) ( struct acpi_header *acpi ) );
179 };
180
181 /** ACPI models */
182 #define ACPI_MODELS __table ( struct acpi_model, "acpi_models" )
183
184 /** Declare an ACPI model */
185 #define __acpi_model __table_entry ( ACPI_MODELS, 01 )
186
187 /**
188 * Calculate static inline ACPI API function name
189 *
190 * @v _prefix Subsystem prefix
191 * @v _api_func API function
192 * @ret _subsys_func Subsystem API function
193 */
194 #define ACPI_INLINE( _subsys, _api_func ) \
195 SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
196
197 /**
198 * Provide an ACPI API implementation
199 *
200 * @v _prefix Subsystem prefix
201 * @v _api_func API function
202 * @v _func Implementing function
203 */
204 #define PROVIDE_ACPI( _subsys, _api_func, _func ) \
205 PROVIDE_SINGLE_API ( ACPI_PREFIX_ ## _subsys, _api_func, _func )
206
207 /**
208 * Provide a static inline ACPI API implementation
209 *
210 * @v _prefix Subsystem prefix
211 * @v _api_func API function
212 */
213 #define PROVIDE_ACPI_INLINE( _subsys, _api_func ) \
214 PROVIDE_SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
215
216 /* Include all architecture-independent ACPI API headers */
217 #include <ipxe/null_acpi.h>
218 #include <ipxe/efi/efi_acpi.h>
219
220 /* Include all architecture-dependent ACPI API headers */
221 #include <bits/acpi.h>
222
223 /**
224 * Locate ACPI root system description table
225 *
226 * @ret rsdt ACPI root system description table, or UNULL
227 */
228 userptr_t acpi_find_rsdt ( void );
229
230 extern struct acpi_descriptor *
231 acpi_describe ( struct interface *interface );
232 #define acpi_describe_TYPE( object_type ) \
233 typeof ( struct acpi_descriptor * ( object_type ) )
234
235 extern void acpi_fix_checksum ( struct acpi_header *acpi );
236 extern userptr_t acpi_find ( uint32_t signature, unsigned int index );
237 extern int acpi_sx ( uint32_t signature );
238 extern void acpi_add ( struct acpi_descriptor *desc );
239 extern void acpi_del ( struct acpi_descriptor *desc );
240 extern int acpi_install ( int ( * install ) ( struct acpi_header *acpi ) );
241
242 #endif /* _IPXE_ACPI_H */
243