rsaddr.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:30k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: rsaddr - Address resource descriptors (16/32/64)
  4.  *              $Revision: 19 $
  5.  *
  6.  ******************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "acresrc.h"
  26. #define _COMPONENT          ACPI_RESOURCES
  27.  MODULE_NAME         ("rsaddr")
  28. /*******************************************************************************
  29.  *
  30.  * FUNCTION:    Acpi_rs_address16_resource
  31.  *
  32.  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
  33.  *                                        stream
  34.  *              Bytes_consumed          - u32 pointer that is filled with
  35.  *                                        the number of bytes consumed from
  36.  *                                        the Byte_stream_buffer
  37.  *              Output_buffer           - Pointer to the user's return buffer
  38.  *              Structure_size          - u32 pointer that is filled with
  39.  *                                        the number of bytes in the filled
  40.  *                                        in structure
  41.  *
  42.  * RETURN:      Status
  43.  *
  44.  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
  45.  *              structure pointed to by the Output_buffer. Return the
  46.  *              number of bytes consumed from the byte stream.
  47.  *
  48.  ******************************************************************************/
  49. acpi_status
  50. acpi_rs_address16_resource (
  51. u8                      *byte_stream_buffer,
  52. u32                     *bytes_consumed,
  53. u8                      **output_buffer,
  54. u32                     *structure_size)
  55. {
  56. u8                      *buffer = byte_stream_buffer;
  57. acpi_resource           *output_struct = (acpi_resource *) *output_buffer;
  58. NATIVE_CHAR             *temp_ptr;
  59. u32                     struct_size = SIZEOF_RESOURCE (acpi_resource_address16);
  60. u32                     index;
  61. u16                     temp16;
  62. u8                      temp8;
  63. FUNCTION_TRACE ("Rs_address16_resource");
  64. /*
  65.  * Point past the Descriptor to get the number of bytes consumed
  66.  */
  67. buffer += 1;
  68. MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
  69. *bytes_consumed = temp16 + 3;
  70. output_struct->id = ACPI_RSTYPE_ADDRESS16;
  71. /*
  72.  * Get the Resource Type (Byte3)
  73.  */
  74. buffer += 2;
  75. temp8 = *buffer;
  76. /* Values 0-2 are valid */
  77. if (temp8 > 2) {
  78. return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
  79. }
  80. output_struct->data.address16.resource_type = temp8 & 0x03;
  81. /*
  82.  * Get the General Flags (Byte4)
  83.  */
  84. buffer += 1;
  85. temp8 = *buffer;
  86. /*
  87.  * Producer / Consumer
  88.  */
  89. output_struct->data.address16.producer_consumer = temp8 & 0x01;
  90. /*
  91.  * Decode
  92.  */
  93. output_struct->data.address16.decode = (temp8 >> 1) & 0x01;
  94. /*
  95.  * Min Address Fixed
  96.  */
  97. output_struct->data.address16.min_address_fixed = (temp8 >> 2) & 0x01;
  98. /*
  99.  * Max Address Fixed
  100.  */
  101. output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01;
  102. /*
  103.  * Get the Type Specific Flags (Byte5)
  104.  */
  105. buffer += 1;
  106. temp8 = *buffer;
  107. if (MEMORY_RANGE == output_struct->data.address16.resource_type) {
  108. output_struct->data.address16.attribute.memory.read_write_attribute =
  109. (u16) (temp8 & 0x01);
  110. output_struct->data.address16.attribute.memory.cache_attribute =
  111. (u16) ((temp8 >> 1) & 0x0F);
  112. }
  113. else {
  114. if (IO_RANGE == output_struct->data.address16.resource_type) {
  115. output_struct->data.address16.attribute.io.range_attribute =
  116. (u16) (temp8 & 0x03);
  117. }
  118. else {
  119. /* BUS_NUMBER_RANGE == Address16.Data->Resource_type */
  120. /* Nothing needs to be filled in */
  121. }
  122. }
  123. /*
  124.  * Get Granularity (Bytes 6-7)
  125.  */
  126. buffer += 1;
  127. MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.granularity,
  128.  buffer);
  129. /*
  130.  * Get Min_address_range (Bytes 8-9)
  131.  */
  132. buffer += 2;
  133. MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.min_address_range,
  134.  buffer);
  135. /*
  136.  * Get Max_address_range (Bytes 10-11)
  137.  */
  138. buffer += 2;
  139. MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.max_address_range,
  140.  buffer);
  141. /*
  142.  * Get Address_translation_offset (Bytes 12-13)
  143.  */
  144. buffer += 2;
  145. MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.address_translation_offset,
  146.  buffer);
  147. /*
  148.  * Get Address_length (Bytes 14-15)
  149.  */
  150. buffer += 2;
  151. MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.address_length,
  152.  buffer);
  153. /*
  154.  * Resource Source Index (if present)
  155.  */
  156. buffer += 2;
  157. /*
  158.  * This will leave us pointing to the Resource Source Index
  159.  * If it is present, then save it off and calculate the
  160.  * pointer to where the null terminated string goes:
  161.  * Each Interrupt takes 32-bits + the 5 bytes of the
  162.  * stream that are default.
  163.  */
  164. if (*bytes_consumed > 16) {
  165. /* Dereference the Index */
  166. temp8 = *buffer;
  167. output_struct->data.address16.resource_source.index = (u32) temp8;
  168. /* Point to the String */
  169. buffer += 1;
  170. /* Point the String pointer to the end of this structure */
  171. output_struct->data.address16.resource_source.string_ptr =
  172. (NATIVE_CHAR *)((u8 * )output_struct + struct_size);
  173. temp_ptr = output_struct->data.address16.resource_source.string_ptr;
  174. /* Copy the string into the buffer */
  175. index = 0;
  176. while (0x00 != *buffer) {
  177. *temp_ptr = *buffer;
  178. temp_ptr += 1;
  179. buffer += 1;
  180. index += 1;
  181. }
  182. /*
  183.  * Add the terminating null
  184.  */
  185. *temp_ptr = 0x00;
  186. output_struct->data.address16.resource_source.string_length = index + 1;
  187. /*
  188.  * In order for the Struct_size to fall on a 32-bit boundary,
  189.  * calculate the length of the string and expand the
  190.  * Struct_size to the next 32-bit boundary.
  191.  */
  192. temp8 = (u8) (index + 1);
  193. struct_size += ROUND_UP_TO_32_bITS (temp8);
  194. }
  195. else {
  196. output_struct->data.address16.resource_source.index = 0x00;
  197. output_struct->data.address16.resource_source.string_length = 0;
  198. output_struct->data.address16.resource_source.string_ptr = NULL;
  199. }
  200. /*
  201.  * Set the Length parameter
  202.  */
  203. output_struct->length = struct_size;
  204. /*
  205.  * Return the final size of the structure
  206.  */
  207. *structure_size = struct_size;
  208. return_ACPI_STATUS (AE_OK);
  209. }
  210. /*******************************************************************************
  211.  *
  212.  * FUNCTION:    Acpi_rs_address16_stream
  213.  *
  214.  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  215.  *              Output_buffer           - Pointer to the user's return buffer
  216.  *              Bytes_consumed          - u32 pointer that is filled with
  217.  *                                        the number of bytes of the
  218.  *                                        Output_buffer used
  219.  *
  220.  * RETURN:      Status
  221.  *
  222.  * DESCRIPTION: Take the linked list resource structure and fills in the
  223.  *              the appropriate bytes in a byte stream
  224.  *
  225.  ******************************************************************************/
  226. acpi_status
  227. acpi_rs_address16_stream (
  228. acpi_resource           *linked_list,
  229. u8                      **output_buffer,
  230. u32                     *bytes_consumed)
  231. {
  232. u8                      *buffer = *output_buffer;
  233. u8                      *length_field;
  234. u8                      temp8;
  235. NATIVE_CHAR             *temp_pointer = NULL;
  236. u32                     actual_bytes;
  237. FUNCTION_TRACE ("Rs_address16_stream");
  238. /*
  239.  * The descriptor field is static
  240.  */
  241. *buffer = 0x88;
  242. buffer += 1;
  243. /*
  244.  * Save a pointer to the Length field - to be filled in later
  245.  */
  246. length_field = buffer;
  247. buffer += 2;
  248. /*
  249.  * Set the Resource Type (Memory, Io, Bus_number)
  250.  */
  251. temp8 = (u8) (linked_list->data.address16.resource_type & 0x03);
  252. *buffer = temp8;
  253. buffer += 1;
  254. /*
  255.  * Set the general flags
  256.  */
  257. temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01);
  258. temp8 |= (linked_list->data.address16.decode & 0x01) << 1;
  259. temp8 |= (linked_list->data.address16.min_address_fixed & 0x01) << 2;
  260. temp8 |= (linked_list->data.address16.max_address_fixed & 0x01) << 3;
  261. *buffer = temp8;
  262. buffer += 1;
  263. /*
  264.  * Set the type specific flags
  265.  */
  266. temp8 = 0;
  267. if (MEMORY_RANGE == linked_list->data.address16.resource_type) {
  268. temp8 = (u8)
  269. (linked_list->data.address16.attribute.memory.read_write_attribute &
  270.  0x01);
  271. temp8 |=
  272. (linked_list->data.address16.attribute.memory.cache_attribute &
  273.  0x0F) << 1;
  274. }
  275. else if (IO_RANGE == linked_list->data.address16.resource_type) {
  276. temp8 = (u8)
  277. (linked_list->data.address16.attribute.io.range_attribute &
  278.  0x03);
  279. }
  280. *buffer = temp8;
  281. buffer += 1;
  282. /*
  283.  * Set the address space granularity
  284.  */
  285. MOVE_UNALIGNED16_TO_16 (buffer,
  286.    &linked_list->data.address16.granularity);
  287. buffer += 2;
  288. /*
  289.  * Set the address range minimum
  290.  */
  291. MOVE_UNALIGNED16_TO_16 (buffer,
  292.    &linked_list->data.address16.min_address_range);
  293. buffer += 2;
  294. /*
  295.  * Set the address range maximum
  296.  */
  297. MOVE_UNALIGNED16_TO_16 (buffer,
  298.    &linked_list->data.address16.max_address_range);
  299. buffer += 2;
  300. /*
  301.  * Set the address translation offset
  302.  */
  303. MOVE_UNALIGNED16_TO_16 (buffer,
  304.    &linked_list->data.address16.address_translation_offset);
  305. buffer += 2;
  306. /*
  307.  * Set the address length
  308.  */
  309. MOVE_UNALIGNED16_TO_16 (buffer,
  310.    &linked_list->data.address16.address_length);
  311. buffer += 2;
  312. /*
  313.  * Resource Source Index and Resource Source are optional
  314.  */
  315. if (0 != linked_list->data.address16.resource_source.string_length) {
  316. temp8 = (u8) linked_list->data.address16.resource_source.index;
  317. *buffer = temp8;
  318. buffer += 1;
  319. temp_pointer = (NATIVE_CHAR *) buffer;
  320. /*
  321.  * Copy the string
  322.  */
  323. STRCPY (temp_pointer,
  324. linked_list->data.address16.resource_source.string_ptr);
  325. /*
  326.  * Buffer needs to be set to the length of the sting + one for the
  327.  *  terminating null
  328.  */
  329. buffer += (STRLEN (linked_list->data.address16.resource_source.string_ptr)
  330.  + 1);
  331. }
  332. /*
  333.  * Return the number of bytes consumed in this operation
  334.  */
  335. actual_bytes = POINTER_DIFF (buffer, *output_buffer);
  336. *bytes_consumed = actual_bytes;
  337. /*
  338.  * Set the length field to the number of bytes consumed
  339.  * minus the header size (3 bytes)
  340.  */
  341. actual_bytes -= 3;
  342. MOVE_UNALIGNED16_TO_16 (length_field, &actual_bytes);
  343. return_ACPI_STATUS (AE_OK);
  344. }
  345. /*******************************************************************************
  346.  *
  347.  * FUNCTION:    Acpi_rs_address32_resource
  348.  *
  349.  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
  350.  *                                        stream
  351.  *              Bytes_consumed          - u32 pointer that is filled with
  352.  *                                        the number of bytes consumed from
  353.  *                                        the Byte_stream_buffer
  354.  *              Output_buffer           - Pointer to the user's return buffer
  355.  *              Structure_size          - u32 pointer that is filled with
  356.  *                                        the number of bytes in the filled
  357.  *                                        in structure
  358.  *
  359.  * RETURN:      Status
  360.  *
  361.  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
  362.  *              structure pointed to by the Output_buffer. Return the
  363.  *              number of bytes consumed from the byte stream.
  364.  *
  365.  ******************************************************************************/
  366. acpi_status
  367. acpi_rs_address32_resource (
  368. u8                      *byte_stream_buffer,
  369. u32                     *bytes_consumed,
  370. u8                      **output_buffer,
  371. u32                     *structure_size)
  372. {
  373. u8                      *buffer;
  374. acpi_resource           *output_struct;
  375. u16                     temp16;
  376. u8                      temp8;
  377. NATIVE_CHAR             *temp_ptr;
  378. u32                     struct_size;
  379. u32                     index;
  380. FUNCTION_TRACE ("Rs_address32_resource");
  381. buffer = byte_stream_buffer;
  382. output_struct = (acpi_resource *) *output_buffer;
  383. struct_size = SIZEOF_RESOURCE (acpi_resource_address32);
  384. /*
  385.  * Point past the Descriptor to get the number of bytes consumed
  386.  */
  387. buffer += 1;
  388. MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
  389. *bytes_consumed = temp16 + 3;
  390. output_struct->id = ACPI_RSTYPE_ADDRESS32;
  391. /*
  392.  * Get the Resource Type (Byte3)
  393.  */
  394. buffer += 2;
  395. temp8 = *buffer;
  396. /* Values 0-2 are valid */
  397. if(temp8 > 2) {
  398. return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
  399. }
  400. output_struct->data.address32.resource_type = temp8 & 0x03;
  401. /*
  402.  * Get the General Flags (Byte4)
  403.  */
  404. buffer += 1;
  405. temp8 = *buffer;
  406. /*
  407.  * Producer / Consumer
  408.  */
  409. output_struct->data.address32.producer_consumer = temp8 & 0x01;
  410. /*
  411.  * Decode
  412.  */
  413. output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
  414. /*
  415.  * Min Address Fixed
  416.  */
  417. output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
  418. /*
  419.  * Max Address Fixed
  420.  */
  421. output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
  422. /*
  423.  * Get the Type Specific Flags (Byte5)
  424.  */
  425. buffer += 1;
  426. temp8 = *buffer;
  427. if (MEMORY_RANGE == output_struct->data.address32.resource_type) {
  428. output_struct->data.address32.attribute.memory.read_write_attribute =
  429. (u16) (temp8 & 0x01);
  430. output_struct->data.address32.attribute.memory.cache_attribute =
  431. (u16) ((temp8 >> 1) & 0x0F);
  432. }
  433. else {
  434. if (IO_RANGE == output_struct->data.address32.resource_type) {
  435. output_struct->data.address32.attribute.io.range_attribute =
  436. (u16) (temp8 & 0x03);
  437. }
  438. else {
  439. /* BUS_NUMBER_RANGE == Output_struct->Data.Address32.Resource_type */
  440. /* Nothing needs to be filled in */
  441. }
  442. }
  443. /*
  444.  * Get Granularity (Bytes 6-9)
  445.  */
  446. buffer += 1;
  447. MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.granularity,
  448.  buffer);
  449. /*
  450.  * Get Min_address_range (Bytes 10-13)
  451.  */
  452. buffer += 4;
  453. MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.min_address_range,
  454.  buffer);
  455. /*
  456.  * Get Max_address_range (Bytes 14-17)
  457.  */
  458. buffer += 4;
  459. MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.max_address_range,
  460.  buffer);
  461. /*
  462.  * Get Address_translation_offset (Bytes 18-21)
  463.  */
  464. buffer += 4;
  465. MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.address_translation_offset,
  466.  buffer);
  467. /*
  468.  * Get Address_length (Bytes 22-25)
  469.  */
  470. buffer += 4;
  471. MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.address_length,
  472.  buffer);
  473. /*
  474.  * Resource Source Index (if present)
  475.  */
  476. buffer += 4;
  477. /*
  478.  * This will leave us pointing to the Resource Source Index
  479.  * If it is present, then save it off and calculate the
  480.  * pointer to where the null terminated string goes:
  481.  */
  482. if (*bytes_consumed > 26) {
  483. /* Dereference the Index */
  484. temp8 = *buffer;
  485. output_struct->data.address32.resource_source.index =
  486. (u32) temp8;
  487. /* Point to the String */
  488. buffer += 1;
  489. /* Point the String pointer to the end of this structure */
  490. output_struct->data.address32.resource_source.string_ptr =
  491. (NATIVE_CHAR *)((u8 *)output_struct + struct_size);
  492. temp_ptr = output_struct->data.address32.resource_source.string_ptr;
  493. /* Copy the string into the buffer */
  494. index = 0;
  495. while (0x00 != *buffer) {
  496. *temp_ptr = *buffer;
  497. temp_ptr += 1;
  498. buffer += 1;
  499. index += 1;
  500. }
  501. /*
  502.  * Add the terminating null
  503.  */
  504. *temp_ptr = 0x00;
  505. output_struct->data.address32.resource_source.string_length = index + 1;
  506. /*
  507.  * In order for the Struct_size to fall on a 32-bit boundary,
  508.  *  calculate the length of the string and expand the
  509.  *  Struct_size to the next 32-bit boundary.
  510.  */
  511. temp8 = (u8) (index + 1);
  512. struct_size += ROUND_UP_TO_32_bITS (temp8);
  513. }
  514. else {
  515. output_struct->data.address32.resource_source.index = 0x00;
  516. output_struct->data.address32.resource_source.string_length = 0;
  517. output_struct->data.address32.resource_source.string_ptr = NULL;
  518. }
  519. /*
  520.  * Set the Length parameter
  521.  */
  522. output_struct->length = struct_size;
  523. /*
  524.  * Return the final size of the structure
  525.  */
  526. *structure_size = struct_size;
  527. return_ACPI_STATUS (AE_OK);
  528. }
  529. /*******************************************************************************
  530.  *
  531.  * FUNCTION:    Acpi_rs_address32_stream
  532.  *
  533.  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  534.  *              Output_buffer           - Pointer to the user's return buffer
  535.  *              Bytes_consumed          - u32 pointer that is filled with
  536.  *                                        the number of bytes of the
  537.  *                                        Output_buffer used
  538.  *
  539.  * RETURN:      Status
  540.  *
  541.  * DESCRIPTION: Take the linked list resource structure and fills in the
  542.  *              the appropriate bytes in a byte stream
  543.  *
  544.  ******************************************************************************/
  545. acpi_status
  546. acpi_rs_address32_stream (
  547. acpi_resource           *linked_list,
  548. u8                      **output_buffer,
  549. u32                     *bytes_consumed)
  550. {
  551. u8                      *buffer;
  552. u16                     *length_field;
  553. u8                      temp8;
  554. NATIVE_CHAR             *temp_pointer;
  555. FUNCTION_TRACE ("Rs_address32_stream");
  556. buffer = *output_buffer;
  557. /*
  558.  * The descriptor field is static
  559.  */
  560. *buffer = 0x87;
  561. buffer += 1;
  562. /*
  563.  * Set a pointer to the Length field - to be filled in later
  564.  */
  565. length_field = (u16 *) buffer;
  566. buffer += 2;
  567. /*
  568.  * Set the Resource Type (Memory, Io, Bus_number)
  569.  */
  570. temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
  571. *buffer = temp8;
  572. buffer += 1;
  573. /*
  574.  * Set the general flags
  575.  */
  576. temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
  577. temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
  578. temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
  579. temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3;
  580. *buffer = temp8;
  581. buffer += 1;
  582. /*
  583.  * Set the type specific flags
  584.  */
  585. temp8 = 0;
  586. if(MEMORY_RANGE == linked_list->data.address32.resource_type) {
  587. temp8 = (u8)
  588. (linked_list->data.address32.attribute.memory.read_write_attribute &
  589. 0x01);
  590. temp8 |=
  591. (linked_list->data.address32.attribute.memory.cache_attribute &
  592.  0x0F) << 1;
  593. }
  594. else if (IO_RANGE == linked_list->data.address32.resource_type) {
  595. temp8 = (u8)
  596. (linked_list->data.address32.attribute.io.range_attribute &
  597.  0x03);
  598. }
  599. *buffer = temp8;
  600. buffer += 1;
  601. /*
  602.  * Set the address space granularity
  603.  */
  604. MOVE_UNALIGNED32_TO_32 (buffer,
  605.   &linked_list->data.address32.granularity);
  606. buffer += 4;
  607. /*
  608.  * Set the address range minimum
  609.  */
  610. MOVE_UNALIGNED32_TO_32 (buffer,
  611.   &linked_list->data.address32.min_address_range);
  612. buffer += 4;
  613. /*
  614.  * Set the address range maximum
  615.  */
  616. MOVE_UNALIGNED32_TO_32 (buffer,
  617.   &linked_list->data.address32.max_address_range);
  618. buffer += 4;
  619. /*
  620.  * Set the address translation offset
  621.  */
  622. MOVE_UNALIGNED32_TO_32 (buffer,
  623.   &linked_list->data.address32.address_translation_offset);
  624. buffer += 4;
  625. /*
  626.  * Set the address length
  627.  */
  628. MOVE_UNALIGNED32_TO_32 (buffer,
  629.   &linked_list->data.address32.address_length);
  630. buffer += 4;
  631. /*
  632.  * Resource Source Index and Resource Source are optional
  633.  */
  634. if (0 != linked_list->data.address32.resource_source.string_length) {
  635. temp8 = (u8) linked_list->data.address32.resource_source.index;
  636. *buffer = temp8;
  637. buffer += 1;
  638. temp_pointer = (NATIVE_CHAR *) buffer;
  639. /*
  640.  * Copy the string
  641.  */
  642. STRCPY (temp_pointer,
  643. linked_list->data.address32.resource_source.string_ptr);
  644. /*
  645.  * Buffer needs to be set to the length of the sting + one for the
  646.  *  terminating null
  647.  */
  648. buffer += (STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1);
  649. }
  650. /*
  651.  * Return the number of bytes consumed in this operation
  652.  */
  653. *bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
  654. /*
  655.  * Set the length field to the number of bytes consumed
  656.  *  minus the header size (3 bytes)
  657.  */
  658. *length_field = (u16) (*bytes_consumed - 3);
  659. return_ACPI_STATUS (AE_OK);
  660. }
  661. /*******************************************************************************
  662.  *
  663.  * FUNCTION:    Acpi_rs_address64_resource
  664.  *
  665.  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
  666.  *                                        stream
  667.  *              Bytes_consumed          - u32 pointer that is filled with
  668.  *                                        the number of bytes consumed from
  669.  *                                        the Byte_stream_buffer
  670.  *              Output_buffer           - Pointer to the user's return buffer
  671.  *              Structure_size          - u32 pointer that is filled with
  672.  *                                        the number of bytes in the filled
  673.  *                                        in structure
  674.  *
  675.  * RETURN:      Status
  676.  *
  677.  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
  678.  *              structure pointed to by the Output_buffer. Return the
  679.  *              number of bytes consumed from the byte stream.
  680.  *
  681.  ******************************************************************************/
  682. acpi_status
  683. acpi_rs_address64_resource (
  684. u8                      *byte_stream_buffer,
  685. u32                     *bytes_consumed,
  686. u8                      **output_buffer,
  687. u32                     *structure_size)
  688. {
  689. u8                      *buffer;
  690. acpi_resource           *output_struct;
  691. u16                     temp16;
  692. u8                      temp8;
  693. NATIVE_CHAR             *temp_ptr;
  694. u32                     struct_size;
  695. u32                     index;
  696. FUNCTION_TRACE ("Rs_address64_resource");
  697. buffer = byte_stream_buffer;
  698. output_struct = (acpi_resource *) *output_buffer;
  699. struct_size = SIZEOF_RESOURCE (acpi_resource_address64);
  700. /*
  701.  * Point past the Descriptor to get the number of bytes consumed
  702.  */
  703. buffer += 1;
  704. MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
  705. *bytes_consumed = temp16 + 3;
  706. output_struct->id = ACPI_RSTYPE_ADDRESS64;
  707. /*
  708.  * Get the Resource Type (Byte3)
  709.  */
  710. buffer += 2;
  711. temp8 = *buffer;
  712. /* Values 0-2 are valid */
  713. if(temp8 > 2) {
  714. return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
  715. }
  716. output_struct->data.address64.resource_type = temp8 & 0x03;
  717. /*
  718.  * Get the General Flags (Byte4)
  719.  */
  720. buffer += 1;
  721. temp8 = *buffer;
  722. /*
  723.  * Producer / Consumer
  724.  */
  725. output_struct->data.address64.producer_consumer = temp8 & 0x01;
  726. /*
  727.  * Decode
  728.  */
  729. output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
  730. /*
  731.  * Min Address Fixed
  732.  */
  733. output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
  734. /*
  735.  * Max Address Fixed
  736.  */
  737. output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
  738. /*
  739.  * Get the Type Specific Flags (Byte5)
  740.  */
  741. buffer += 1;
  742. temp8 = *buffer;
  743. if (MEMORY_RANGE == output_struct->data.address64.resource_type) {
  744. output_struct->data.address64.attribute.memory.read_write_attribute =
  745. (u16) (temp8 & 0x01);
  746. output_struct->data.address64.attribute.memory.cache_attribute =
  747. (u16) ((temp8 >> 1) & 0x0F);
  748. }
  749. else {
  750. if (IO_RANGE == output_struct->data.address64.resource_type) {
  751. output_struct->data.address64.attribute.io.range_attribute =
  752. (u16) (temp8 & 0x03);
  753. }
  754. else {
  755. /* BUS_NUMBER_RANGE == Output_struct->Data.Address64.Resource_type */
  756. /* Nothing needs to be filled in */
  757. }
  758. }
  759. /*
  760.  * Get Granularity (Bytes 6-13)
  761.  */
  762. buffer += 1;
  763. MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.granularity,
  764.  buffer);
  765. /*
  766.  * Get Min_address_range (Bytes 14-21)
  767.  */
  768. buffer += 8;
  769. MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.min_address_range,
  770.  buffer);
  771. /*
  772.  * Get Max_address_range (Bytes 22-29)
  773.  */
  774. buffer += 8;
  775. MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.max_address_range,
  776.  buffer);
  777. /*
  778.  * Get Address_translation_offset (Bytes 30-37)
  779.  */
  780. buffer += 8;
  781. MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.address_translation_offset,
  782.  buffer);
  783. /*
  784.  * Get Address_length (Bytes 38-45)
  785.  */
  786. buffer += 8;
  787. MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.address_length,
  788.  buffer);
  789. /*
  790.  * Resource Source Index (if present)
  791.  */
  792. buffer += 8;
  793. /*
  794.  * This will leave us pointing to the Resource Source Index
  795.  * If it is present, then save it off and calculate the
  796.  * pointer to where the null terminated string goes:
  797.  * Each Interrupt takes 32-bits + the 5 bytes of the
  798.  * stream that are default.
  799.  */
  800. if (*bytes_consumed > 46) {
  801. /* Dereference the Index */
  802. temp8 = *buffer;
  803. output_struct->data.address64.resource_source.index =
  804. (u32) temp8;
  805. /* Point to the String */
  806. buffer += 1;
  807. /* Point the String pointer to the end of this structure */
  808. output_struct->data.address64.resource_source.string_ptr =
  809. (NATIVE_CHAR *)((u8 *)output_struct + struct_size);
  810. temp_ptr = output_struct->data.address64.resource_source.string_ptr;
  811. /* Copy the string into the buffer */
  812. index = 0;
  813. while (0x00 != *buffer) {
  814. *temp_ptr = *buffer;
  815. temp_ptr += 1;
  816. buffer += 1;
  817. index += 1;
  818. }
  819. /*
  820.  * Add the terminating null
  821.  */
  822. *temp_ptr = 0x00;
  823. output_struct->data.address64.resource_source.string_length = index + 1;
  824. /*
  825.  * In order for the Struct_size to fall on a 32-bit boundary,
  826.  * calculate the length of the string and expand the
  827.  * Struct_size to the next 32-bit boundary.
  828.  */
  829. temp8 = (u8) (index + 1);
  830. struct_size += ROUND_UP_TO_32_bITS (temp8);
  831. }
  832. else {
  833. output_struct->data.address64.resource_source.index = 0x00;
  834. output_struct->data.address64.resource_source.string_length = 0;
  835. output_struct->data.address64.resource_source.string_ptr = NULL;
  836. }
  837. /*
  838.  * Set the Length parameter
  839.  */
  840. output_struct->length = struct_size;
  841. /*
  842.  * Return the final size of the structure
  843.  */
  844. *structure_size = struct_size;
  845. return_ACPI_STATUS (AE_OK);
  846. }
  847. /*******************************************************************************
  848.  *
  849.  * FUNCTION:    Acpi_rs_address64_stream
  850.  *
  851.  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  852.  *              Output_buffer           - Pointer to the user's return buffer
  853.  *              Bytes_consumed          - u32 pointer that is filled with
  854.  *                                        the number of bytes of the
  855.  *                                        Output_buffer used
  856.  *
  857.  * RETURN:      Status
  858.  *
  859.  * DESCRIPTION: Take the linked list resource structure and fills in the
  860.  *              the appropriate bytes in a byte stream
  861.  *
  862.  ******************************************************************************/
  863. acpi_status
  864. acpi_rs_address64_stream (
  865. acpi_resource           *linked_list,
  866. u8                      **output_buffer,
  867. u32                     *bytes_consumed)
  868. {
  869. u8                      *buffer;
  870. u16                     *length_field;
  871. u8                      temp8;
  872. NATIVE_CHAR             *temp_pointer;
  873. FUNCTION_TRACE ("Rs_address64_stream");
  874. buffer = *output_buffer;
  875. /*
  876.  * The descriptor field is static
  877.  */
  878. *buffer = 0x8A;
  879. buffer += 1;
  880. /*
  881.  * Set a pointer to the Length field - to be filled in later
  882.  */
  883. length_field = (u16 *)buffer;
  884. buffer += 2;
  885. /*
  886.  * Set the Resource Type (Memory, Io, Bus_number)
  887.  */
  888. temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
  889. *buffer = temp8;
  890. buffer += 1;
  891. /*
  892.  * Set the general flags
  893.  */
  894. temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
  895. temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
  896. temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
  897. temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3;
  898. *buffer = temp8;
  899. buffer += 1;
  900. /*
  901.  * Set the type specific flags
  902.  */
  903. temp8 = 0;
  904. if(MEMORY_RANGE == linked_list->data.address64.resource_type) {
  905. temp8 = (u8)
  906. (linked_list->data.address64.attribute.memory.read_write_attribute &
  907. 0x01);
  908. temp8 |=
  909. (linked_list->data.address64.attribute.memory.cache_attribute &
  910.  0x0F) << 1;
  911. }
  912. else if (IO_RANGE == linked_list->data.address64.resource_type) {
  913. temp8 = (u8)
  914. (linked_list->data.address64.attribute.io.range_attribute &
  915.  0x03);
  916. }
  917. *buffer = temp8;
  918. buffer += 1;
  919. /*
  920.  * Set the address space granularity
  921.  */
  922. MOVE_UNALIGNED64_TO_64 (buffer,
  923.    &linked_list->data.address64.granularity);
  924. buffer += 8;
  925. /*
  926.  * Set the address range minimum
  927.  */
  928. MOVE_UNALIGNED64_TO_64 (buffer,
  929.    &linked_list->data.address64.min_address_range);
  930. buffer += 8;
  931. /*
  932.  * Set the address range maximum
  933.  */
  934. MOVE_UNALIGNED64_TO_64 (buffer,
  935.    &linked_list->data.address64.max_address_range);
  936. buffer += 8;
  937. /*
  938.  * Set the address translation offset
  939.  */
  940. MOVE_UNALIGNED64_TO_64 (buffer,
  941.    &linked_list->data.address64.address_translation_offset);
  942. buffer += 8;
  943. /*
  944.  * Set the address length
  945.  */
  946. MOVE_UNALIGNED64_TO_64 (buffer,
  947.    &linked_list->data.address64.address_length);
  948. buffer += 8;
  949. /*
  950.  * Resource Source Index and Resource Source are optional
  951.  */
  952. if (0 != linked_list->data.address64.resource_source.string_length) {
  953. temp8 = (u8) linked_list->data.address64.resource_source.index;
  954. *buffer = temp8;
  955. buffer += 1;
  956. temp_pointer = (NATIVE_CHAR *) buffer;
  957. /*
  958.  * Copy the string
  959.  */
  960. STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr);
  961. /*
  962.  * Buffer needs to be set to the length of the sting + one for the
  963.  *  terminating null
  964.  */
  965. buffer += (STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1);
  966. }
  967. /*
  968.  * Return the number of bytes consumed in this operation
  969.  */
  970. *bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
  971. /*
  972.  * Set the length field to the number of bytes consumed
  973.  * minus the header size (3 bytes)
  974.  */
  975. *length_field = (u16) (*bytes_consumed - 3);
  976. return_ACPI_STATUS (AE_OK);
  977. }