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 /** PM2 Control Register Block */
123 uint32_t pm2_cnt_blk;
124 /** PM Timer Control Register Block */
125 uint32_t pm_tmr_blk;
126 } __attribute__ (( packed ));
127
128 /** ACPI PM1 Control Register (within PM1a_CNT_BLK or PM1A_CNT_BLK) */
129 #define ACPI_PM1_CNT 0
130 #define ACPI_PM1_CNT_SLP_TYP(x) ( (x) << 10 ) /**< Sleep type */
131 #define ACPI_PM1_CNT_SLP_EN ( 1 << 13 ) /**< Sleep enable */
132
133 /** ACPI PM Timer Register (within PM_TMR_BLK) */
134 #define ACPI_PM_TMR 0
135
136 /** Differentiated System Description Table (DSDT) signature */
137 #define DSDT_SIGNATURE ACPI_SIGNATURE ( 'D', 'S', 'D', 'T' )
138
139 /** Secondary System Description Table (SSDT) signature */
140 #define SSDT_SIGNATURE ACPI_SIGNATURE ( 'S', 'S', 'D', 'T' )
141
142 /** An ACPI descriptor (used to construct ACPI tables) */
143 struct acpi_descriptor {
144 /** Reference count of containing object */
145 struct refcnt *refcnt;
146 /** Table model */
147 struct acpi_model *model;
148 /** List of ACPI descriptors for this model */
149 struct list_head list;
150 };
151
152 /**
153 * Initialise ACPI descriptor
154 *
155 * @v desc ACPI descriptor
156 * @v model Table model
157 * @v refcnt Reference count
158 */
159 static inline __attribute__ (( always_inline )) void
acpi_init(struct acpi_descriptor * desc,struct acpi_model * model,struct refcnt * refcnt)160 acpi_init ( struct acpi_descriptor *desc, struct acpi_model *model,
161 struct refcnt *refcnt ) {
162
163 desc->refcnt = refcnt;
164 desc->model = model;
165 INIT_LIST_HEAD ( &desc->list );
166 }
167
168 /** An ACPI table model */
169 struct acpi_model {
170 /** List of descriptors */
171 struct list_head descs;
172 /**
173 * Check if ACPI descriptor is complete
174 *
175 * @v desc ACPI descriptor
176 * @ret rc Return status code
177 */
178 int ( * complete ) ( struct acpi_descriptor *desc );
179 /**
180 * Install ACPI tables
181 *
182 * @v install Installation method
183 * @ret rc Return status code
184 */
185 int ( * install ) ( int ( * install ) ( struct acpi_header *acpi ) );
186 };
187
188 /** ACPI models */
189 #define ACPI_MODELS __table ( struct acpi_model, "acpi_models" )
190
191 /** Declare an ACPI model */
192 #define __acpi_model __table_entry ( ACPI_MODELS, 01 )
193
194 /**
195 * Calculate static inline ACPI API function name
196 *
197 * @v _prefix Subsystem prefix
198 * @v _api_func API function
199 * @ret _subsys_func Subsystem API function
200 */
201 #define ACPI_INLINE( _subsys, _api_func ) \
202 SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
203
204 /**
205 * Provide an ACPI API implementation
206 *
207 * @v _prefix Subsystem prefix
208 * @v _api_func API function
209 * @v _func Implementing function
210 */
211 #define PROVIDE_ACPI( _subsys, _api_func, _func ) \
212 PROVIDE_SINGLE_API ( ACPI_PREFIX_ ## _subsys, _api_func, _func )
213
214 /**
215 * Provide a static inline ACPI API implementation
216 *
217 * @v _prefix Subsystem prefix
218 * @v _api_func API function
219 */
220 #define PROVIDE_ACPI_INLINE( _subsys, _api_func ) \
221 PROVIDE_SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
222
223 /* Include all architecture-independent ACPI API headers */
224 #include <ipxe/null_acpi.h>
225 #include <ipxe/efi/efi_acpi.h>
226
227 /* Include all architecture-dependent ACPI API headers */
228 #include <bits/acpi.h>
229
230 /**
231 * Locate ACPI root system description table
232 *
233 * @ret rsdt ACPI root system description table, or UNULL
234 */
235 userptr_t acpi_find_rsdt ( void );
236
237 extern struct acpi_descriptor *
238 acpi_describe ( struct interface *interface );
239 #define acpi_describe_TYPE( object_type ) \
240 typeof ( struct acpi_descriptor * ( object_type ) )
241
242 extern void acpi_fix_checksum ( struct acpi_header *acpi );
243 extern userptr_t acpi_find ( uint32_t signature, unsigned int index );
244 extern int acpi_sx ( uint32_t signature );
245 extern void acpi_add ( struct acpi_descriptor *desc );
246 extern void acpi_del ( struct acpi_descriptor *desc );
247 extern int acpi_install ( int ( * install ) ( struct acpi_header *acpi ) );
248
249 #endif /* _IPXE_ACPI_H */
250