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