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