1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /*******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: rsutils - Utilities for the resource manager
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun ******************************************************************************/
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <acpi/acpi.h>
9*4882a593Smuzhiyun #include "accommon.h"
10*4882a593Smuzhiyun #include "acnamesp.h"
11*4882a593Smuzhiyun #include "acresrc.h"
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define _COMPONENT ACPI_RESOURCES
14*4882a593Smuzhiyun ACPI_MODULE_NAME("rsutils")
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun /*******************************************************************************
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * FUNCTION: acpi_rs_decode_bitmask
19*4882a593Smuzhiyun *
20*4882a593Smuzhiyun * PARAMETERS: mask - Bitmask to decode
21*4882a593Smuzhiyun * list - Where the converted list is returned
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * RETURN: Count of bits set (length of list)
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * DESCRIPTION: Convert a bit mask into a list of values
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun ******************************************************************************/
acpi_rs_decode_bitmask(u16 mask,u8 * list)28*4882a593Smuzhiyun u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun u8 i;
31*4882a593Smuzhiyun u8 bit_count;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /* Decode the mask bits */
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun for (i = 0, bit_count = 0; mask; i++) {
38*4882a593Smuzhiyun if (mask & 0x0001) {
39*4882a593Smuzhiyun list[bit_count] = i;
40*4882a593Smuzhiyun bit_count++;
41*4882a593Smuzhiyun }
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun mask >>= 1;
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun return (bit_count);
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun /*******************************************************************************
50*4882a593Smuzhiyun *
51*4882a593Smuzhiyun * FUNCTION: acpi_rs_encode_bitmask
52*4882a593Smuzhiyun *
53*4882a593Smuzhiyun * PARAMETERS: list - List of values to encode
54*4882a593Smuzhiyun * count - Length of list
55*4882a593Smuzhiyun *
56*4882a593Smuzhiyun * RETURN: Encoded bitmask
57*4882a593Smuzhiyun *
58*4882a593Smuzhiyun * DESCRIPTION: Convert a list of values to an encoded bitmask
59*4882a593Smuzhiyun *
60*4882a593Smuzhiyun ******************************************************************************/
61*4882a593Smuzhiyun
acpi_rs_encode_bitmask(u8 * list,u8 count)62*4882a593Smuzhiyun u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun u32 i;
65*4882a593Smuzhiyun u16 mask;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /* Encode the list into a single bitmask */
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun for (i = 0, mask = 0; i < count; i++) {
72*4882a593Smuzhiyun mask |= (0x1 << list[i]);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun return (mask);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /*******************************************************************************
79*4882a593Smuzhiyun *
80*4882a593Smuzhiyun * FUNCTION: acpi_rs_move_data
81*4882a593Smuzhiyun *
82*4882a593Smuzhiyun * PARAMETERS: destination - Pointer to the destination descriptor
83*4882a593Smuzhiyun * source - Pointer to the source descriptor
84*4882a593Smuzhiyun * item_count - How many items to move
85*4882a593Smuzhiyun * move_type - Byte width
86*4882a593Smuzhiyun *
87*4882a593Smuzhiyun * RETURN: None
88*4882a593Smuzhiyun *
89*4882a593Smuzhiyun * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
90*4882a593Smuzhiyun * alignment issues and endian issues if necessary, as configured
91*4882a593Smuzhiyun * via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
92*4882a593Smuzhiyun *
93*4882a593Smuzhiyun ******************************************************************************/
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun void
acpi_rs_move_data(void * destination,void * source,u16 item_count,u8 move_type)96*4882a593Smuzhiyun acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun u32 i;
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /* One move per item */
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun for (i = 0; i < item_count; i++) {
105*4882a593Smuzhiyun switch (move_type) {
106*4882a593Smuzhiyun /*
107*4882a593Smuzhiyun * For the 8-bit case, we can perform the move all at once
108*4882a593Smuzhiyun * since there are no alignment or endian issues
109*4882a593Smuzhiyun */
110*4882a593Smuzhiyun case ACPI_RSC_MOVE8:
111*4882a593Smuzhiyun case ACPI_RSC_MOVE_GPIO_RES:
112*4882a593Smuzhiyun case ACPI_RSC_MOVE_SERIAL_VEN:
113*4882a593Smuzhiyun case ACPI_RSC_MOVE_SERIAL_RES:
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun memcpy(destination, source, item_count);
116*4882a593Smuzhiyun return;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /*
119*4882a593Smuzhiyun * 16-, 32-, and 64-bit cases must use the move macros that perform
120*4882a593Smuzhiyun * endian conversion and/or accommodate hardware that cannot perform
121*4882a593Smuzhiyun * misaligned memory transfers
122*4882a593Smuzhiyun */
123*4882a593Smuzhiyun case ACPI_RSC_MOVE16:
124*4882a593Smuzhiyun case ACPI_RSC_MOVE_GPIO_PIN:
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
127*4882a593Smuzhiyun &ACPI_CAST_PTR(u16, source)[i]);
128*4882a593Smuzhiyun break;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun case ACPI_RSC_MOVE32:
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
133*4882a593Smuzhiyun &ACPI_CAST_PTR(u32, source)[i]);
134*4882a593Smuzhiyun break;
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun case ACPI_RSC_MOVE64:
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
139*4882a593Smuzhiyun &ACPI_CAST_PTR(u64, source)[i]);
140*4882a593Smuzhiyun break;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun default:
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun return;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /*******************************************************************************
150*4882a593Smuzhiyun *
151*4882a593Smuzhiyun * FUNCTION: acpi_rs_set_resource_length
152*4882a593Smuzhiyun *
153*4882a593Smuzhiyun * PARAMETERS: total_length - Length of the AML descriptor, including
154*4882a593Smuzhiyun * the header and length fields.
155*4882a593Smuzhiyun * aml - Pointer to the raw AML descriptor
156*4882a593Smuzhiyun *
157*4882a593Smuzhiyun * RETURN: None
158*4882a593Smuzhiyun *
159*4882a593Smuzhiyun * DESCRIPTION: Set the resource_length field of an AML
160*4882a593Smuzhiyun * resource descriptor, both Large and Small descriptors are
161*4882a593Smuzhiyun * supported automatically. Note: Descriptor Type field must
162*4882a593Smuzhiyun * be valid.
163*4882a593Smuzhiyun *
164*4882a593Smuzhiyun ******************************************************************************/
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun void
acpi_rs_set_resource_length(acpi_rsdesc_size total_length,union aml_resource * aml)167*4882a593Smuzhiyun acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
168*4882a593Smuzhiyun union aml_resource *aml)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun acpi_rs_length resource_length;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /* Length is the total descriptor length minus the header length */
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun resource_length = (acpi_rs_length)
177*4882a593Smuzhiyun (total_length - acpi_ut_get_resource_header_length(aml));
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /* Length is stored differently for large and small descriptors */
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /* Large descriptor -- bytes 1-2 contain the 16-bit length */
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
186*4882a593Smuzhiyun &resource_length);
187*4882a593Smuzhiyun } else {
188*4882a593Smuzhiyun /*
189*4882a593Smuzhiyun * Small descriptor -- bits 2:0 of byte 0 contain the length
190*4882a593Smuzhiyun * Clear any existing length, preserving descriptor type bits
191*4882a593Smuzhiyun */
192*4882a593Smuzhiyun aml->small_header.descriptor_type = (u8)
193*4882a593Smuzhiyun ((aml->small_header.descriptor_type &
194*4882a593Smuzhiyun ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
195*4882a593Smuzhiyun | resource_length);
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun /*******************************************************************************
200*4882a593Smuzhiyun *
201*4882a593Smuzhiyun * FUNCTION: acpi_rs_set_resource_header
202*4882a593Smuzhiyun *
203*4882a593Smuzhiyun * PARAMETERS: descriptor_type - Byte to be inserted as the type
204*4882a593Smuzhiyun * total_length - Length of the AML descriptor, including
205*4882a593Smuzhiyun * the header and length fields.
206*4882a593Smuzhiyun * aml - Pointer to the raw AML descriptor
207*4882a593Smuzhiyun *
208*4882a593Smuzhiyun * RETURN: None
209*4882a593Smuzhiyun *
210*4882a593Smuzhiyun * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
211*4882a593Smuzhiyun * resource descriptor, both Large and Small descriptors are
212*4882a593Smuzhiyun * supported automatically
213*4882a593Smuzhiyun *
214*4882a593Smuzhiyun ******************************************************************************/
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun void
acpi_rs_set_resource_header(u8 descriptor_type,acpi_rsdesc_size total_length,union aml_resource * aml)217*4882a593Smuzhiyun acpi_rs_set_resource_header(u8 descriptor_type,
218*4882a593Smuzhiyun acpi_rsdesc_size total_length,
219*4882a593Smuzhiyun union aml_resource *aml)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun /* Set the Resource Type */
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun aml->small_header.descriptor_type = descriptor_type;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun /* Set the Resource Length */
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun acpi_rs_set_resource_length(total_length, aml);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun /*******************************************************************************
233*4882a593Smuzhiyun *
234*4882a593Smuzhiyun * FUNCTION: acpi_rs_strcpy
235*4882a593Smuzhiyun *
236*4882a593Smuzhiyun * PARAMETERS: destination - Pointer to the destination string
237*4882a593Smuzhiyun * source - Pointer to the source string
238*4882a593Smuzhiyun *
239*4882a593Smuzhiyun * RETURN: String length, including NULL terminator
240*4882a593Smuzhiyun *
241*4882a593Smuzhiyun * DESCRIPTION: Local string copy that returns the string length, saving a
242*4882a593Smuzhiyun * strcpy followed by a strlen.
243*4882a593Smuzhiyun *
244*4882a593Smuzhiyun ******************************************************************************/
245*4882a593Smuzhiyun
acpi_rs_strcpy(char * destination,char * source)246*4882a593Smuzhiyun static u16 acpi_rs_strcpy(char *destination, char *source)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun u16 i;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun for (i = 0; source[i]; i++) {
253*4882a593Smuzhiyun destination[i] = source[i];
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun destination[i] = 0;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /* Return string length including the NULL terminator */
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun return ((u16) (i + 1));
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun /*******************************************************************************
264*4882a593Smuzhiyun *
265*4882a593Smuzhiyun * FUNCTION: acpi_rs_get_resource_source
266*4882a593Smuzhiyun *
267*4882a593Smuzhiyun * PARAMETERS: resource_length - Length field of the descriptor
268*4882a593Smuzhiyun * minimum_length - Minimum length of the descriptor (minus
269*4882a593Smuzhiyun * any optional fields)
270*4882a593Smuzhiyun * resource_source - Where the resource_source is returned
271*4882a593Smuzhiyun * aml - Pointer to the raw AML descriptor
272*4882a593Smuzhiyun * string_ptr - (optional) where to store the actual
273*4882a593Smuzhiyun * resource_source string
274*4882a593Smuzhiyun *
275*4882a593Smuzhiyun * RETURN: Length of the string plus NULL terminator, rounded up to native
276*4882a593Smuzhiyun * word boundary
277*4882a593Smuzhiyun *
278*4882a593Smuzhiyun * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
279*4882a593Smuzhiyun * to an internal resource descriptor
280*4882a593Smuzhiyun *
281*4882a593Smuzhiyun ******************************************************************************/
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun acpi_rs_length
acpi_rs_get_resource_source(acpi_rs_length resource_length,acpi_rs_length minimum_length,struct acpi_resource_source * resource_source,union aml_resource * aml,char * string_ptr)284*4882a593Smuzhiyun acpi_rs_get_resource_source(acpi_rs_length resource_length,
285*4882a593Smuzhiyun acpi_rs_length minimum_length,
286*4882a593Smuzhiyun struct acpi_resource_source * resource_source,
287*4882a593Smuzhiyun union aml_resource * aml, char *string_ptr)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun acpi_rsdesc_size total_length;
290*4882a593Smuzhiyun u8 *aml_resource_source;
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun total_length =
295*4882a593Smuzhiyun resource_length + sizeof(struct aml_resource_large_header);
296*4882a593Smuzhiyun aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun /*
299*4882a593Smuzhiyun * resource_source is present if the length of the descriptor is longer
300*4882a593Smuzhiyun * than the minimum length.
301*4882a593Smuzhiyun *
302*4882a593Smuzhiyun * Note: Some resource descriptors will have an additional null, so
303*4882a593Smuzhiyun * we add 1 to the minimum length.
304*4882a593Smuzhiyun */
305*4882a593Smuzhiyun if (total_length > (acpi_rsdesc_size)(minimum_length + 1)) {
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun /* Get the resource_source_index */
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun resource_source->index = aml_resource_source[0];
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun resource_source->string_ptr = string_ptr;
312*4882a593Smuzhiyun if (!string_ptr) {
313*4882a593Smuzhiyun /*
314*4882a593Smuzhiyun * String destination pointer is not specified; Set the String
315*4882a593Smuzhiyun * pointer to the end of the current resource_source structure.
316*4882a593Smuzhiyun */
317*4882a593Smuzhiyun resource_source->string_ptr =
318*4882a593Smuzhiyun ACPI_ADD_PTR(char, resource_source,
319*4882a593Smuzhiyun sizeof(struct acpi_resource_source));
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun /*
323*4882a593Smuzhiyun * In order for the Resource length to be a multiple of the native
324*4882a593Smuzhiyun * word, calculate the length of the string (+1 for NULL terminator)
325*4882a593Smuzhiyun * and expand to the next word multiple.
326*4882a593Smuzhiyun *
327*4882a593Smuzhiyun * Zero the entire area of the buffer.
328*4882a593Smuzhiyun */
329*4882a593Smuzhiyun total_length =
330*4882a593Smuzhiyun (u32)strlen(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
331*4882a593Smuzhiyun 1;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun total_length = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun memset(resource_source->string_ptr, 0, total_length);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun /* Copy the resource_source string to the destination */
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun resource_source->string_length =
340*4882a593Smuzhiyun acpi_rs_strcpy(resource_source->string_ptr,
341*4882a593Smuzhiyun ACPI_CAST_PTR(char,
342*4882a593Smuzhiyun &aml_resource_source[1]));
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun return ((acpi_rs_length)total_length);
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun /* resource_source is not present */
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun resource_source->index = 0;
350*4882a593Smuzhiyun resource_source->string_length = 0;
351*4882a593Smuzhiyun resource_source->string_ptr = NULL;
352*4882a593Smuzhiyun return (0);
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun /*******************************************************************************
356*4882a593Smuzhiyun *
357*4882a593Smuzhiyun * FUNCTION: acpi_rs_set_resource_source
358*4882a593Smuzhiyun *
359*4882a593Smuzhiyun * PARAMETERS: aml - Pointer to the raw AML descriptor
360*4882a593Smuzhiyun * minimum_length - Minimum length of the descriptor (minus
361*4882a593Smuzhiyun * any optional fields)
362*4882a593Smuzhiyun * resource_source - Internal resource_source
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun *
365*4882a593Smuzhiyun * RETURN: Total length of the AML descriptor
366*4882a593Smuzhiyun *
367*4882a593Smuzhiyun * DESCRIPTION: Convert an optional resource_source from internal format to a
368*4882a593Smuzhiyun * raw AML resource descriptor
369*4882a593Smuzhiyun *
370*4882a593Smuzhiyun ******************************************************************************/
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun acpi_rsdesc_size
acpi_rs_set_resource_source(union aml_resource * aml,acpi_rs_length minimum_length,struct acpi_resource_source * resource_source)373*4882a593Smuzhiyun acpi_rs_set_resource_source(union aml_resource *aml,
374*4882a593Smuzhiyun acpi_rs_length minimum_length,
375*4882a593Smuzhiyun struct acpi_resource_source *resource_source)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun u8 *aml_resource_source;
378*4882a593Smuzhiyun acpi_rsdesc_size descriptor_length;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun descriptor_length = minimum_length;
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* Non-zero string length indicates presence of a resource_source */
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun if (resource_source->string_length) {
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun /* Point to the end of the AML descriptor */
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* Copy the resource_source_index */
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun aml_resource_source[0] = (u8) resource_source->index;
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun /* Copy the resource_source string */
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun strcpy(ACPI_CAST_PTR(char, &aml_resource_source[1]),
399*4882a593Smuzhiyun resource_source->string_ptr);
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun /*
402*4882a593Smuzhiyun * Add the length of the string (+ 1 for null terminator) to the
403*4882a593Smuzhiyun * final descriptor length
404*4882a593Smuzhiyun */
405*4882a593Smuzhiyun descriptor_length += ((acpi_rsdesc_size)
406*4882a593Smuzhiyun resource_source->string_length + 1);
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun /* Return the new total length of the AML descriptor */
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun return (descriptor_length);
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun /*******************************************************************************
415*4882a593Smuzhiyun *
416*4882a593Smuzhiyun * FUNCTION: acpi_rs_get_prt_method_data
417*4882a593Smuzhiyun *
418*4882a593Smuzhiyun * PARAMETERS: node - Device node
419*4882a593Smuzhiyun * ret_buffer - Pointer to a buffer structure for the
420*4882a593Smuzhiyun * results
421*4882a593Smuzhiyun *
422*4882a593Smuzhiyun * RETURN: Status
423*4882a593Smuzhiyun *
424*4882a593Smuzhiyun * DESCRIPTION: This function is called to get the _PRT value of an object
425*4882a593Smuzhiyun * contained in an object specified by the handle passed in
426*4882a593Smuzhiyun *
427*4882a593Smuzhiyun * If the function fails an appropriate status will be returned
428*4882a593Smuzhiyun * and the contents of the callers buffer is undefined.
429*4882a593Smuzhiyun *
430*4882a593Smuzhiyun ******************************************************************************/
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun acpi_status
acpi_rs_get_prt_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)433*4882a593Smuzhiyun acpi_rs_get_prt_method_data(struct acpi_namespace_node *node,
434*4882a593Smuzhiyun struct acpi_buffer *ret_buffer)
435*4882a593Smuzhiyun {
436*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
437*4882a593Smuzhiyun acpi_status status;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(rs_get_prt_method_data);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun /* Parameters guaranteed valid by caller */
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun /* Execute the method, no parameters */
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun status =
446*4882a593Smuzhiyun acpi_ut_evaluate_object(node, METHOD_NAME__PRT, ACPI_BTYPE_PACKAGE,
447*4882a593Smuzhiyun &obj_desc);
448*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
449*4882a593Smuzhiyun return_ACPI_STATUS(status);
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun /*
453*4882a593Smuzhiyun * Create a resource linked list from the byte stream buffer that comes
454*4882a593Smuzhiyun * back from the _CRS method execution.
455*4882a593Smuzhiyun */
456*4882a593Smuzhiyun status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun /* On exit, we must delete the object returned by evaluate_object */
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
461*4882a593Smuzhiyun return_ACPI_STATUS(status);
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun /*******************************************************************************
465*4882a593Smuzhiyun *
466*4882a593Smuzhiyun * FUNCTION: acpi_rs_get_crs_method_data
467*4882a593Smuzhiyun *
468*4882a593Smuzhiyun * PARAMETERS: node - Device node
469*4882a593Smuzhiyun * ret_buffer - Pointer to a buffer structure for the
470*4882a593Smuzhiyun * results
471*4882a593Smuzhiyun *
472*4882a593Smuzhiyun * RETURN: Status
473*4882a593Smuzhiyun *
474*4882a593Smuzhiyun * DESCRIPTION: This function is called to get the _CRS value of an object
475*4882a593Smuzhiyun * contained in an object specified by the handle passed in
476*4882a593Smuzhiyun *
477*4882a593Smuzhiyun * If the function fails an appropriate status will be returned
478*4882a593Smuzhiyun * and the contents of the callers buffer is undefined.
479*4882a593Smuzhiyun *
480*4882a593Smuzhiyun ******************************************************************************/
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun acpi_status
acpi_rs_get_crs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)483*4882a593Smuzhiyun acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
484*4882a593Smuzhiyun struct acpi_buffer *ret_buffer)
485*4882a593Smuzhiyun {
486*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
487*4882a593Smuzhiyun acpi_status status;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(rs_get_crs_method_data);
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun /* Parameters guaranteed valid by caller */
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun /* Execute the method, no parameters */
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun status =
496*4882a593Smuzhiyun acpi_ut_evaluate_object(node, METHOD_NAME__CRS, ACPI_BTYPE_BUFFER,
497*4882a593Smuzhiyun &obj_desc);
498*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
499*4882a593Smuzhiyun return_ACPI_STATUS(status);
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun /*
503*4882a593Smuzhiyun * Make the call to create a resource linked list from the
504*4882a593Smuzhiyun * byte stream buffer that comes back from the _CRS method
505*4882a593Smuzhiyun * execution.
506*4882a593Smuzhiyun */
507*4882a593Smuzhiyun status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun /* On exit, we must delete the object returned by evaluateObject */
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
512*4882a593Smuzhiyun return_ACPI_STATUS(status);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun /*******************************************************************************
516*4882a593Smuzhiyun *
517*4882a593Smuzhiyun * FUNCTION: acpi_rs_get_prs_method_data
518*4882a593Smuzhiyun *
519*4882a593Smuzhiyun * PARAMETERS: node - Device node
520*4882a593Smuzhiyun * ret_buffer - Pointer to a buffer structure for the
521*4882a593Smuzhiyun * results
522*4882a593Smuzhiyun *
523*4882a593Smuzhiyun * RETURN: Status
524*4882a593Smuzhiyun *
525*4882a593Smuzhiyun * DESCRIPTION: This function is called to get the _PRS value of an object
526*4882a593Smuzhiyun * contained in an object specified by the handle passed in
527*4882a593Smuzhiyun *
528*4882a593Smuzhiyun * If the function fails an appropriate status will be returned
529*4882a593Smuzhiyun * and the contents of the callers buffer is undefined.
530*4882a593Smuzhiyun *
531*4882a593Smuzhiyun ******************************************************************************/
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun acpi_status
acpi_rs_get_prs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)534*4882a593Smuzhiyun acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
535*4882a593Smuzhiyun struct acpi_buffer *ret_buffer)
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
538*4882a593Smuzhiyun acpi_status status;
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(rs_get_prs_method_data);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun /* Parameters guaranteed valid by caller */
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun /* Execute the method, no parameters */
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun status =
547*4882a593Smuzhiyun acpi_ut_evaluate_object(node, METHOD_NAME__PRS, ACPI_BTYPE_BUFFER,
548*4882a593Smuzhiyun &obj_desc);
549*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
550*4882a593Smuzhiyun return_ACPI_STATUS(status);
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun /*
554*4882a593Smuzhiyun * Make the call to create a resource linked list from the
555*4882a593Smuzhiyun * byte stream buffer that comes back from the _CRS method
556*4882a593Smuzhiyun * execution.
557*4882a593Smuzhiyun */
558*4882a593Smuzhiyun status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun /* On exit, we must delete the object returned by evaluateObject */
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
563*4882a593Smuzhiyun return_ACPI_STATUS(status);
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun /*******************************************************************************
567*4882a593Smuzhiyun *
568*4882a593Smuzhiyun * FUNCTION: acpi_rs_get_aei_method_data
569*4882a593Smuzhiyun *
570*4882a593Smuzhiyun * PARAMETERS: node - Device node
571*4882a593Smuzhiyun * ret_buffer - Pointer to a buffer structure for the
572*4882a593Smuzhiyun * results
573*4882a593Smuzhiyun *
574*4882a593Smuzhiyun * RETURN: Status
575*4882a593Smuzhiyun *
576*4882a593Smuzhiyun * DESCRIPTION: This function is called to get the _AEI value of an object
577*4882a593Smuzhiyun * contained in an object specified by the handle passed in
578*4882a593Smuzhiyun *
579*4882a593Smuzhiyun * If the function fails an appropriate status will be returned
580*4882a593Smuzhiyun * and the contents of the callers buffer is undefined.
581*4882a593Smuzhiyun *
582*4882a593Smuzhiyun ******************************************************************************/
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun acpi_status
acpi_rs_get_aei_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)585*4882a593Smuzhiyun acpi_rs_get_aei_method_data(struct acpi_namespace_node *node,
586*4882a593Smuzhiyun struct acpi_buffer *ret_buffer)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
589*4882a593Smuzhiyun acpi_status status;
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(rs_get_aei_method_data);
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun /* Parameters guaranteed valid by caller */
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun /* Execute the method, no parameters */
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun status =
598*4882a593Smuzhiyun acpi_ut_evaluate_object(node, METHOD_NAME__AEI, ACPI_BTYPE_BUFFER,
599*4882a593Smuzhiyun &obj_desc);
600*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
601*4882a593Smuzhiyun return_ACPI_STATUS(status);
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun /*
605*4882a593Smuzhiyun * Make the call to create a resource linked list from the
606*4882a593Smuzhiyun * byte stream buffer that comes back from the _CRS method
607*4882a593Smuzhiyun * execution.
608*4882a593Smuzhiyun */
609*4882a593Smuzhiyun status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun /* On exit, we must delete the object returned by evaluateObject */
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
614*4882a593Smuzhiyun return_ACPI_STATUS(status);
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun /*******************************************************************************
618*4882a593Smuzhiyun *
619*4882a593Smuzhiyun * FUNCTION: acpi_rs_get_method_data
620*4882a593Smuzhiyun *
621*4882a593Smuzhiyun * PARAMETERS: handle - Handle to the containing object
622*4882a593Smuzhiyun * path - Path to method, relative to Handle
623*4882a593Smuzhiyun * ret_buffer - Pointer to a buffer structure for the
624*4882a593Smuzhiyun * results
625*4882a593Smuzhiyun *
626*4882a593Smuzhiyun * RETURN: Status
627*4882a593Smuzhiyun *
628*4882a593Smuzhiyun * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
629*4882a593Smuzhiyun * object contained in an object specified by the handle passed in
630*4882a593Smuzhiyun *
631*4882a593Smuzhiyun * If the function fails an appropriate status will be returned
632*4882a593Smuzhiyun * and the contents of the callers buffer is undefined.
633*4882a593Smuzhiyun *
634*4882a593Smuzhiyun ******************************************************************************/
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun acpi_status
acpi_rs_get_method_data(acpi_handle handle,const char * path,struct acpi_buffer * ret_buffer)637*4882a593Smuzhiyun acpi_rs_get_method_data(acpi_handle handle,
638*4882a593Smuzhiyun const char *path, struct acpi_buffer *ret_buffer)
639*4882a593Smuzhiyun {
640*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
641*4882a593Smuzhiyun acpi_status status;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(rs_get_method_data);
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun /* Parameters guaranteed valid by caller */
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun /* Execute the method, no parameters */
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun status =
650*4882a593Smuzhiyun acpi_ut_evaluate_object(ACPI_CAST_PTR
651*4882a593Smuzhiyun (struct acpi_namespace_node, handle), path,
652*4882a593Smuzhiyun ACPI_BTYPE_BUFFER, &obj_desc);
653*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
654*4882a593Smuzhiyun return_ACPI_STATUS(status);
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun /*
658*4882a593Smuzhiyun * Make the call to create a resource linked list from the
659*4882a593Smuzhiyun * byte stream buffer that comes back from the method
660*4882a593Smuzhiyun * execution.
661*4882a593Smuzhiyun */
662*4882a593Smuzhiyun status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun /* On exit, we must delete the object returned by evaluate_object */
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
667*4882a593Smuzhiyun return_ACPI_STATUS(status);
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun /*******************************************************************************
671*4882a593Smuzhiyun *
672*4882a593Smuzhiyun * FUNCTION: acpi_rs_set_srs_method_data
673*4882a593Smuzhiyun *
674*4882a593Smuzhiyun * PARAMETERS: node - Device node
675*4882a593Smuzhiyun * in_buffer - Pointer to a buffer structure of the
676*4882a593Smuzhiyun * parameter
677*4882a593Smuzhiyun *
678*4882a593Smuzhiyun * RETURN: Status
679*4882a593Smuzhiyun *
680*4882a593Smuzhiyun * DESCRIPTION: This function is called to set the _SRS of an object contained
681*4882a593Smuzhiyun * in an object specified by the handle passed in
682*4882a593Smuzhiyun *
683*4882a593Smuzhiyun * If the function fails an appropriate status will be returned
684*4882a593Smuzhiyun * and the contents of the callers buffer is undefined.
685*4882a593Smuzhiyun *
686*4882a593Smuzhiyun * Note: Parameters guaranteed valid by caller
687*4882a593Smuzhiyun *
688*4882a593Smuzhiyun ******************************************************************************/
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun acpi_status
acpi_rs_set_srs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * in_buffer)691*4882a593Smuzhiyun acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
692*4882a593Smuzhiyun struct acpi_buffer *in_buffer)
693*4882a593Smuzhiyun {
694*4882a593Smuzhiyun struct acpi_evaluate_info *info;
695*4882a593Smuzhiyun union acpi_operand_object *args[2];
696*4882a593Smuzhiyun acpi_status status;
697*4882a593Smuzhiyun struct acpi_buffer buffer;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(rs_set_srs_method_data);
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun /* Allocate and initialize the evaluation information block */
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
704*4882a593Smuzhiyun if (!info) {
705*4882a593Smuzhiyun return_ACPI_STATUS(AE_NO_MEMORY);
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun info->prefix_node = node;
709*4882a593Smuzhiyun info->relative_pathname = METHOD_NAME__SRS;
710*4882a593Smuzhiyun info->parameters = args;
711*4882a593Smuzhiyun info->flags = ACPI_IGNORE_RETURN_VALUE;
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun /*
714*4882a593Smuzhiyun * The in_buffer parameter will point to a linked list of
715*4882a593Smuzhiyun * resource parameters. It needs to be formatted into a
716*4882a593Smuzhiyun * byte stream to be sent in as an input parameter to _SRS
717*4882a593Smuzhiyun *
718*4882a593Smuzhiyun * Convert the linked list into a byte stream
719*4882a593Smuzhiyun */
720*4882a593Smuzhiyun buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
721*4882a593Smuzhiyun status = acpi_rs_create_aml_resources(in_buffer, &buffer);
722*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
723*4882a593Smuzhiyun goto cleanup;
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun /* Create and initialize the method parameter object */
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
729*4882a593Smuzhiyun if (!args[0]) {
730*4882a593Smuzhiyun /*
731*4882a593Smuzhiyun * Must free the buffer allocated above (otherwise it is freed
732*4882a593Smuzhiyun * later)
733*4882a593Smuzhiyun */
734*4882a593Smuzhiyun ACPI_FREE(buffer.pointer);
735*4882a593Smuzhiyun status = AE_NO_MEMORY;
736*4882a593Smuzhiyun goto cleanup;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun args[0]->buffer.length = (u32) buffer.length;
740*4882a593Smuzhiyun args[0]->buffer.pointer = buffer.pointer;
741*4882a593Smuzhiyun args[0]->common.flags = AOPOBJ_DATA_VALID;
742*4882a593Smuzhiyun args[1] = NULL;
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun /* Execute the method, no return value is expected */
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun status = acpi_ns_evaluate(info);
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun /* Clean up and return the status from acpi_ns_evaluate */
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun acpi_ut_remove_reference(args[0]);
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun cleanup:
753*4882a593Smuzhiyun ACPI_FREE(info);
754*4882a593Smuzhiyun return_ACPI_STATUS(status);
755*4882a593Smuzhiyun }
756