PageRenderTime 318ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/firmware/acpi/acpi_build.c

https://bitbucket.org/jacobgorm/xen-evilman
C | 232 lines | 145 code | 26 blank | 61 comment | 1 complexity | 0745c5566e16743ddcf8dd29bfd9a2b1 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause, LGPL-2.0
  1. /*
  2. * Copyright (c) 2004, Intel Corporation.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms and conditions of the GNU General Public License,
  6. * version 2, as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with
  14. * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  15. * Place - Suite 330, Boston, MA 02111-1307 USA.
  16. *
  17. */
  18. #include "acpi2_0.h"
  19. #include "acpi_madt.h"
  20. extern ACPI_2_0_RSDP Rsdp;
  21. extern ACPI_2_0_RSDT Rsdt;
  22. extern ACPI_2_0_XSDT Xsdt;
  23. extern ACPI_2_0_FADT Fadt;
  24. extern ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE Madt;
  25. extern ACPI_2_0_FACS Facs;
  26. extern unsigned char *AmlCode;
  27. extern int DsdtLen;
  28. typedef struct _ACPI_TABLE_ALL{
  29. ACPI_2_0_RSDP *Rsdp;
  30. ACPI_2_0_RSDT *Rsdt;
  31. ACPI_2_0_XSDT *Xsdt;
  32. ACPI_2_0_FADT *Fadt;
  33. ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *Madt;
  34. ACPI_2_0_FACS *Facs;
  35. unsigned char* Dsdt;
  36. uint32_t RsdpOffset;
  37. uint32_t RsdtOffset;
  38. uint32_t XsdtOffset;
  39. uint32_t FadtOffset;
  40. uint32_t MadtOffset;
  41. uint32_t FacsOffset;
  42. uint32_t DsdtOffset;
  43. }ACPI_TABLE_ALL;
  44. static
  45. void
  46. MemCopy(void* src, void* dst, int len){
  47. uint8_t* src0=src;
  48. uint8_t* dst0=dst;
  49. while(len--){
  50. *(dst0++)=*(src0++);
  51. }
  52. }
  53. static
  54. void
  55. SetCheckSum(
  56. void* Table,
  57. uint32_t ChecksumOffset,
  58. uint32_t Length
  59. )
  60. /*
  61. * Routine Description:
  62. * Calculate Checksum and store the result in the checksum
  63. * filed of the table
  64. *
  65. * INPUT:
  66. * Table: Start pointer of table
  67. * ChecksumOffset: Offset of checksum field in the table
  68. * Length: Length of Table
  69. */
  70. {
  71. uint8_t Sum = 0;
  72. uint8_t *Ptr;
  73. Ptr=Table;
  74. Ptr[ChecksumOffset]=0;
  75. while (Length--) {
  76. Sum = (uint8_t)(Sum + (*Ptr++));
  77. }
  78. Ptr = Table;
  79. Ptr[ChecksumOffset] = (uint8_t) (0xff - Sum + 1);
  80. }
  81. //
  82. // FIELD_OFFSET - returns the byte offset to a field within a structure
  83. //
  84. #define FIELD_OFFSET(TYPE,Field) ((uint32_t)(&(((TYPE *) 0)->Field)))
  85. static
  86. void
  87. UpdateTable(
  88. ACPI_TABLE_ALL *table
  89. )
  90. /*
  91. * Update the ACPI table:
  92. * fill in the actuall physical address of RSDT, XSDT, FADT, MADT, FACS
  93. * Caculate the checksum
  94. */
  95. {
  96. // RSDP Update
  97. table->Rsdp->RsdtAddress = (uint32_t)(ACPI_PHYSICAL_ADDRESS+
  98. table->RsdtOffset);
  99. table->Rsdp->XsdtAddress = (uint64_t)(ACPI_PHYSICAL_ADDRESS+
  100. table->XsdtOffset);
  101. SetCheckSum(table->Rsdp,
  102. FIELD_OFFSET(ACPI_1_0_RSDP, Checksum),
  103. sizeof(ACPI_1_0_RSDP)
  104. );
  105. SetCheckSum(table->Rsdp,
  106. FIELD_OFFSET(ACPI_2_0_RSDP,
  107. ExtendedChecksum),
  108. sizeof(ACPI_2_0_RSDP)
  109. );
  110. //RSDT Update
  111. table->Rsdt->Entry[0] = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
  112. table->FadtOffset);
  113. table->Rsdt->Entry[1] = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
  114. table->MadtOffset);
  115. table->Rsdt->Header.Length = sizeof (ACPI_TABLE_HEADER) +
  116. 2*sizeof(uint32_t);
  117. SetCheckSum(table->Rsdt,
  118. FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
  119. table->Rsdt->Header.Length
  120. );
  121. //XSDT Update
  122. table->Xsdt->Entry[0] = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
  123. table->FadtOffset);
  124. table->Xsdt->Entry[1] = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
  125. table->MadtOffset);
  126. table->Xsdt->Header.Length = sizeof (ACPI_TABLE_HEADER) +
  127. 2*sizeof(uint64_t);
  128. SetCheckSum(table->Xsdt,
  129. FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
  130. table->Xsdt->Header.Length
  131. );
  132. // FADT Update
  133. table->Fadt->Dsdt = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
  134. table->DsdtOffset);
  135. table->Fadt->XDsdt = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
  136. table->DsdtOffset);
  137. table->Fadt->FirmwareCtrl = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
  138. table->FacsOffset);
  139. table->Fadt->XFirmwareCtrl = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
  140. table->FacsOffset);
  141. SetCheckSum(table->Fadt,
  142. FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
  143. sizeof(ACPI_2_0_FADT)
  144. );
  145. // MADT update
  146. SetCheckSum(table->Madt,
  147. FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
  148. sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE)
  149. );
  150. }
  151. void
  152. AcpiBuildTable(uint8_t* buf)
  153. /*
  154. * Copy all the ACPI table to buffer
  155. * Buffer Layout:
  156. * FACS
  157. * RSDP
  158. * RSDT
  159. * XSDT
  160. * FADT
  161. * MADT
  162. * DSDT
  163. *
  164. */
  165. {
  166. ACPI_TABLE_ALL table;
  167. int offset=0;
  168. // FACS: should be 64-bit alignment
  169. // so it is put at the start of buffer
  170. // as the buffer is 64 bit alignment
  171. table.FacsOffset = offset;
  172. table.Facs = (ACPI_2_0_FACS*)(&buf[offset]);
  173. MemCopy(&Facs, table.Facs, sizeof(ACPI_2_0_FACS));
  174. offset += sizeof(ACPI_2_0_FACS);
  175. // RSDP
  176. table.RsdpOffset = offset;
  177. table.Rsdp = (ACPI_2_0_RSDP*)(&buf[offset]);
  178. MemCopy(&Rsdp, table.Rsdp, sizeof(ACPI_2_0_RSDP));
  179. offset+=sizeof(ACPI_2_0_RSDP);
  180. // RSDT
  181. table.RsdtOffset = offset;
  182. table.Rsdt = (ACPI_2_0_RSDT*)(&buf[offset]);
  183. MemCopy(&Rsdt, table.Rsdt, sizeof(ACPI_2_0_RSDT));
  184. offset+=sizeof(ACPI_2_0_RSDT);
  185. // XSDT
  186. table.XsdtOffset = offset;
  187. table.Xsdt = (ACPI_2_0_XSDT*)(&buf[offset]);
  188. MemCopy(&Xsdt, table.Xsdt, sizeof(ACPI_2_0_XSDT));
  189. offset+=sizeof(ACPI_2_0_XSDT);
  190. // FADT
  191. table.FadtOffset = offset;
  192. table.Fadt = (ACPI_2_0_FADT*)(&buf[offset]);
  193. MemCopy(&Fadt, table.Fadt, sizeof(ACPI_2_0_FADT));
  194. offset+=sizeof(ACPI_2_0_FADT);
  195. // MADT
  196. table.MadtOffset = offset;
  197. table.Madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE*)(&buf[offset]);
  198. MemCopy(&Madt, table.Madt, sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE));
  199. offset+=sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE);
  200. // DSDT
  201. table.DsdtOffset = offset;
  202. table.Dsdt = (unsigned char*)(&buf[offset]);
  203. MemCopy(&AmlCode, table.Dsdt, DsdtLen);
  204. offset+=DsdtLen;
  205. UpdateTable(&table);
  206. }