]>
Commit | Line | Data |
---|---|---|
95857638 | 1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
99575102 LZ |
2 | /******************************************************************************* |
3 | * | |
4 | * Module Name: dbconvert - debugger miscellaneous conversion routines | |
5 | * | |
6 | ******************************************************************************/ | |
7 | ||
99575102 LZ |
8 | #include <acpi/acpi.h> |
9 | #include "accommon.h" | |
10 | #include "acdebug.h" | |
11 | ||
12 | #define _COMPONENT ACPI_CA_DEBUGGER | |
13 | ACPI_MODULE_NAME("dbconvert") | |
14 | ||
15 | #define DB_DEFAULT_PKG_ELEMENTS 33 | |
16 | /******************************************************************************* | |
17 | * | |
18 | * FUNCTION: acpi_db_hex_char_to_value | |
19 | * | |
20 | * PARAMETERS: hex_char - Ascii Hex digit, 0-9|a-f|A-F | |
21 | * return_value - Where the converted value is returned | |
22 | * | |
23 | * RETURN: Status | |
24 | * | |
25 | * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16). | |
26 | * | |
27 | ******************************************************************************/ | |
28 | acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value) | |
29 | { | |
30 | u8 value; | |
31 | ||
32 | /* Digit must be ascii [0-9a-fA-F] */ | |
33 | ||
34 | if (!isxdigit(hex_char)) { | |
35 | return (AE_BAD_HEX_CONSTANT); | |
36 | } | |
37 | ||
38 | if (hex_char <= 0x39) { | |
39 | value = (u8)(hex_char - 0x30); | |
40 | } else { | |
41 | value = (u8)(toupper(hex_char) - 0x37); | |
42 | } | |
43 | ||
44 | *return_value = value; | |
45 | return (AE_OK); | |
46 | } | |
47 | ||
48 | /******************************************************************************* | |
49 | * | |
50 | * FUNCTION: acpi_db_hex_byte_to_binary | |
51 | * | |
52 | * PARAMETERS: hex_byte - Double hex digit (0x00 - 0xFF) in format: | |
53 | * hi_byte then lo_byte. | |
54 | * return_value - Where the converted value is returned | |
55 | * | |
56 | * RETURN: Status | |
57 | * | |
58 | * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255). | |
59 | * | |
60 | ******************************************************************************/ | |
61 | ||
62 | static acpi_status acpi_db_hex_byte_to_binary(char *hex_byte, u8 *return_value) | |
63 | { | |
64 | u8 local0; | |
65 | u8 local1; | |
66 | acpi_status status; | |
67 | ||
68 | /* High byte */ | |
69 | ||
70 | status = acpi_db_hex_char_to_value(hex_byte[0], &local0); | |
71 | if (ACPI_FAILURE(status)) { | |
72 | return (status); | |
73 | } | |
74 | ||
75 | /* Low byte */ | |
76 | ||
77 | status = acpi_db_hex_char_to_value(hex_byte[1], &local1); | |
78 | if (ACPI_FAILURE(status)) { | |
79 | return (status); | |
80 | } | |
81 | ||
82 | *return_value = (u8)((local0 << 4) | local1); | |
83 | return (AE_OK); | |
84 | } | |
85 | ||
86 | /******************************************************************************* | |
87 | * | |
88 | * FUNCTION: acpi_db_convert_to_buffer | |
89 | * | |
90 | * PARAMETERS: string - Input string to be converted | |
91 | * object - Where the buffer object is returned | |
92 | * | |
93 | * RETURN: Status | |
94 | * | |
95 | * DESCRIPTION: Convert a string to a buffer object. String is treated a list | |
96 | * of buffer elements, each separated by a space or comma. | |
97 | * | |
98 | ******************************************************************************/ | |
99 | ||
100 | static acpi_status | |
101 | acpi_db_convert_to_buffer(char *string, union acpi_object *object) | |
102 | { | |
103 | u32 i; | |
104 | u32 j; | |
105 | u32 length; | |
106 | u8 *buffer; | |
107 | acpi_status status; | |
108 | ||
109 | /* Generate the final buffer length */ | |
110 | ||
111 | for (i = 0, length = 0; string[i];) { | |
112 | i += 2; | |
113 | length++; | |
114 | ||
115 | while (string[i] && ((string[i] == ',') || (string[i] == ' '))) { | |
116 | i++; | |
117 | } | |
118 | } | |
119 | ||
120 | buffer = ACPI_ALLOCATE(length); | |
121 | if (!buffer) { | |
122 | return (AE_NO_MEMORY); | |
123 | } | |
124 | ||
125 | /* Convert the command line bytes to the buffer */ | |
126 | ||
127 | for (i = 0, j = 0; string[i];) { | |
128 | status = acpi_db_hex_byte_to_binary(&string[i], &buffer[j]); | |
129 | if (ACPI_FAILURE(status)) { | |
130 | ACPI_FREE(buffer); | |
131 | return (status); | |
132 | } | |
133 | ||
134 | j++; | |
135 | i += 2; | |
136 | while (string[i] && ((string[i] == ',') || (string[i] == ' '))) { | |
137 | i++; | |
138 | } | |
139 | } | |
140 | ||
141 | object->type = ACPI_TYPE_BUFFER; | |
142 | object->buffer.pointer = buffer; | |
143 | object->buffer.length = length; | |
144 | return (AE_OK); | |
145 | } | |
146 | ||
147 | /******************************************************************************* | |
148 | * | |
149 | * FUNCTION: acpi_db_convert_to_package | |
150 | * | |
151 | * PARAMETERS: string - Input string to be converted | |
152 | * object - Where the package object is returned | |
153 | * | |
154 | * RETURN: Status | |
155 | * | |
156 | * DESCRIPTION: Convert a string to a package object. Handles nested packages | |
157 | * via recursion with acpi_db_convert_to_object. | |
158 | * | |
159 | ******************************************************************************/ | |
160 | ||
f5c1e1c5 | 161 | acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object) |
99575102 LZ |
162 | { |
163 | char *this; | |
164 | char *next; | |
165 | u32 i; | |
166 | acpi_object_type type; | |
167 | union acpi_object *elements; | |
168 | acpi_status status; | |
169 | ||
170 | elements = | |
171 | ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS * | |
172 | sizeof(union acpi_object)); | |
173 | ||
174 | this = string; | |
175 | for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) { | |
176 | this = acpi_db_get_next_token(this, &next, &type); | |
177 | if (!this) { | |
178 | break; | |
179 | } | |
180 | ||
181 | /* Recursive call to convert each package element */ | |
182 | ||
183 | status = acpi_db_convert_to_object(type, this, &elements[i]); | |
184 | if (ACPI_FAILURE(status)) { | |
185 | acpi_db_delete_objects(i + 1, elements); | |
186 | ACPI_FREE(elements); | |
187 | return (status); | |
188 | } | |
189 | ||
190 | this = next; | |
191 | } | |
192 | ||
193 | object->type = ACPI_TYPE_PACKAGE; | |
194 | object->package.count = i; | |
195 | object->package.elements = elements; | |
196 | return (AE_OK); | |
197 | } | |
198 | ||
199 | /******************************************************************************* | |
200 | * | |
201 | * FUNCTION: acpi_db_convert_to_object | |
202 | * | |
203 | * PARAMETERS: type - Object type as determined by parser | |
204 | * string - Input string to be converted | |
205 | * object - Where the new object is returned | |
206 | * | |
207 | * RETURN: Status | |
208 | * | |
03440c4e | 209 | * DESCRIPTION: Convert a typed and tokenized string to a union acpi_object. Typing: |
99575102 LZ |
210 | * 1) String objects were surrounded by quotes. |
211 | * 2) Buffer objects were surrounded by parentheses. | |
212 | * 3) Package objects were surrounded by brackets "[]". | |
213 | * 4) All standalone tokens are treated as integers. | |
214 | * | |
215 | ******************************************************************************/ | |
216 | ||
217 | acpi_status | |
218 | acpi_db_convert_to_object(acpi_object_type type, | |
f5c1e1c5 | 219 | char *string, union acpi_object *object) |
99575102 LZ |
220 | { |
221 | acpi_status status = AE_OK; | |
222 | ||
223 | switch (type) { | |
224 | case ACPI_TYPE_STRING: | |
225 | ||
226 | object->type = ACPI_TYPE_STRING; | |
227 | object->string.pointer = string; | |
228 | object->string.length = (u32)strlen(string); | |
229 | break; | |
230 | ||
231 | case ACPI_TYPE_BUFFER: | |
232 | ||
233 | status = acpi_db_convert_to_buffer(string, object); | |
234 | break; | |
235 | ||
236 | case ACPI_TYPE_PACKAGE: | |
237 | ||
238 | status = acpi_db_convert_to_package(string, object); | |
239 | break; | |
240 | ||
241 | default: | |
242 | ||
243 | object->type = ACPI_TYPE_INTEGER; | |
fe97d287 | 244 | status = acpi_ut_strtoul64(string, &object->integer.value); |
99575102 LZ |
245 | break; |
246 | } | |
247 | ||
248 | return (status); | |
249 | } | |
250 | ||
251 | /******************************************************************************* | |
252 | * | |
253 | * FUNCTION: acpi_db_encode_pld_buffer | |
254 | * | |
255 | * PARAMETERS: pld_info - _PLD buffer struct (Using local struct) | |
256 | * | |
257 | * RETURN: Encode _PLD buffer suitable for return value from _PLD | |
258 | * | |
259 | * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros | |
260 | * | |
261 | ******************************************************************************/ | |
262 | ||
263 | u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info) | |
264 | { | |
265 | u32 *buffer; | |
266 | u32 dword; | |
267 | ||
268 | buffer = ACPI_ALLOCATE_ZEROED(ACPI_PLD_BUFFER_SIZE); | |
269 | if (!buffer) { | |
270 | return (NULL); | |
271 | } | |
272 | ||
273 | /* First 32 bits */ | |
274 | ||
275 | dword = 0; | |
276 | ACPI_PLD_SET_REVISION(&dword, pld_info->revision); | |
277 | ACPI_PLD_SET_IGNORE_COLOR(&dword, pld_info->ignore_color); | |
278 | ACPI_PLD_SET_RED(&dword, pld_info->red); | |
279 | ACPI_PLD_SET_GREEN(&dword, pld_info->green); | |
280 | ACPI_PLD_SET_BLUE(&dword, pld_info->blue); | |
281 | ACPI_MOVE_32_TO_32(&buffer[0], &dword); | |
282 | ||
283 | /* Second 32 bits */ | |
284 | ||
285 | dword = 0; | |
286 | ACPI_PLD_SET_WIDTH(&dword, pld_info->width); | |
287 | ACPI_PLD_SET_HEIGHT(&dword, pld_info->height); | |
288 | ACPI_MOVE_32_TO_32(&buffer[1], &dword); | |
289 | ||
290 | /* Third 32 bits */ | |
291 | ||
292 | dword = 0; | |
293 | ACPI_PLD_SET_USER_VISIBLE(&dword, pld_info->user_visible); | |
294 | ACPI_PLD_SET_DOCK(&dword, pld_info->dock); | |
295 | ACPI_PLD_SET_LID(&dword, pld_info->lid); | |
296 | ACPI_PLD_SET_PANEL(&dword, pld_info->panel); | |
297 | ACPI_PLD_SET_VERTICAL(&dword, pld_info->vertical_position); | |
298 | ACPI_PLD_SET_HORIZONTAL(&dword, pld_info->horizontal_position); | |
299 | ACPI_PLD_SET_SHAPE(&dword, pld_info->shape); | |
300 | ACPI_PLD_SET_ORIENTATION(&dword, pld_info->group_orientation); | |
301 | ACPI_PLD_SET_TOKEN(&dword, pld_info->group_token); | |
302 | ACPI_PLD_SET_POSITION(&dword, pld_info->group_position); | |
303 | ACPI_PLD_SET_BAY(&dword, pld_info->bay); | |
304 | ACPI_MOVE_32_TO_32(&buffer[2], &dword); | |
305 | ||
306 | /* Fourth 32 bits */ | |
307 | ||
308 | dword = 0; | |
309 | ACPI_PLD_SET_EJECTABLE(&dword, pld_info->ejectable); | |
310 | ACPI_PLD_SET_OSPM_EJECT(&dword, pld_info->ospm_eject_required); | |
311 | ACPI_PLD_SET_CABINET(&dword, pld_info->cabinet_number); | |
312 | ACPI_PLD_SET_CARD_CAGE(&dword, pld_info->card_cage_number); | |
313 | ACPI_PLD_SET_REFERENCE(&dword, pld_info->reference); | |
314 | ACPI_PLD_SET_ROTATION(&dword, pld_info->rotation); | |
315 | ACPI_PLD_SET_ORDER(&dword, pld_info->order); | |
316 | ACPI_MOVE_32_TO_32(&buffer[3], &dword); | |
317 | ||
318 | if (pld_info->revision >= 2) { | |
319 | ||
320 | /* Fifth 32 bits */ | |
321 | ||
322 | dword = 0; | |
323 | ACPI_PLD_SET_VERT_OFFSET(&dword, pld_info->vertical_offset); | |
324 | ACPI_PLD_SET_HORIZ_OFFSET(&dword, pld_info->horizontal_offset); | |
325 | ACPI_MOVE_32_TO_32(&buffer[4], &dword); | |
326 | } | |
327 | ||
328 | return (ACPI_CAST_PTR(u8, buffer)); | |
329 | } | |
330 | ||
331 | /******************************************************************************* | |
332 | * | |
333 | * FUNCTION: acpi_db_dump_pld_buffer | |
334 | * | |
335 | * PARAMETERS: obj_desc - Object returned from _PLD method | |
336 | * | |
337 | * RETURN: None. | |
338 | * | |
339 | * DESCRIPTION: Dumps formatted contents of a _PLD return buffer. | |
340 | * | |
341 | ******************************************************************************/ | |
342 | ||
343 | #define ACPI_PLD_OUTPUT "%20s : %-6X\n" | |
344 | ||
345 | void acpi_db_dump_pld_buffer(union acpi_object *obj_desc) | |
346 | { | |
347 | union acpi_object *buffer_desc; | |
348 | struct acpi_pld_info *pld_info; | |
349 | u8 *new_buffer; | |
350 | acpi_status status; | |
351 | ||
352 | /* Object must be of type Package with at least one Buffer element */ | |
353 | ||
354 | if (obj_desc->type != ACPI_TYPE_PACKAGE) { | |
355 | return; | |
356 | } | |
357 | ||
358 | buffer_desc = &obj_desc->package.elements[0]; | |
359 | if (buffer_desc->type != ACPI_TYPE_BUFFER) { | |
360 | return; | |
361 | } | |
362 | ||
363 | /* Convert _PLD buffer to local _PLD struct */ | |
364 | ||
365 | status = acpi_decode_pld_buffer(buffer_desc->buffer.pointer, | |
366 | buffer_desc->buffer.length, &pld_info); | |
367 | if (ACPI_FAILURE(status)) { | |
368 | return; | |
369 | } | |
370 | ||
371 | /* Encode local _PLD struct back to a _PLD buffer */ | |
372 | ||
373 | new_buffer = acpi_db_encode_pld_buffer(pld_info); | |
374 | if (!new_buffer) { | |
c340e5f0 | 375 | goto exit; |
99575102 LZ |
376 | } |
377 | ||
378 | /* The two bit-packed buffers should match */ | |
379 | ||
380 | if (memcmp(new_buffer, buffer_desc->buffer.pointer, | |
381 | buffer_desc->buffer.length)) { | |
382 | acpi_os_printf | |
383 | ("Converted _PLD buffer does not compare. New:\n"); | |
384 | ||
385 | acpi_ut_dump_buffer(new_buffer, | |
386 | buffer_desc->buffer.length, DB_BYTE_DISPLAY, | |
387 | 0); | |
388 | } | |
389 | ||
390 | /* First 32-bit dword */ | |
391 | ||
392 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Revision", pld_info->revision); | |
393 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_IgnoreColor", | |
394 | pld_info->ignore_color); | |
395 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Red", pld_info->red); | |
396 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Green", pld_info->green); | |
397 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Blue", pld_info->blue); | |
398 | ||
399 | /* Second 32-bit dword */ | |
400 | ||
401 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Width", pld_info->width); | |
402 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Height", pld_info->height); | |
403 | ||
404 | /* Third 32-bit dword */ | |
405 | ||
406 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_UserVisible", | |
407 | pld_info->user_visible); | |
408 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Dock", pld_info->dock); | |
409 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Lid", pld_info->lid); | |
410 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Panel", pld_info->panel); | |
411 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalPosition", | |
412 | pld_info->vertical_position); | |
413 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalPosition", | |
414 | pld_info->horizontal_position); | |
415 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Shape", pld_info->shape); | |
416 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupOrientation", | |
417 | pld_info->group_orientation); | |
418 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupToken", | |
419 | pld_info->group_token); | |
420 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupPosition", | |
421 | pld_info->group_position); | |
422 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Bay", pld_info->bay); | |
423 | ||
424 | /* Fourth 32-bit dword */ | |
425 | ||
426 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Ejectable", pld_info->ejectable); | |
427 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_EjectRequired", | |
428 | pld_info->ospm_eject_required); | |
429 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CabinetNumber", | |
430 | pld_info->cabinet_number); | |
431 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CardCageNumber", | |
432 | pld_info->card_cage_number); | |
433 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Reference", pld_info->reference); | |
434 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Rotation", pld_info->rotation); | |
435 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Order", pld_info->order); | |
436 | ||
437 | /* Fifth 32-bit dword */ | |
438 | ||
439 | if (buffer_desc->buffer.length > 16) { | |
440 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalOffset", | |
441 | pld_info->vertical_offset); | |
442 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalOffset", | |
443 | pld_info->horizontal_offset); | |
444 | } | |
445 | ||
99575102 | 446 | ACPI_FREE(new_buffer); |
c340e5f0 CIK |
447 | exit: |
448 | ACPI_FREE(pld_info); | |
99575102 | 449 | } |