You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

acpi.c 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*
  2. * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. #include <errno.h>
  25. #include <byteswap.h>
  26. #include <ipxe/uaccess.h>
  27. #include <ipxe/acpi.h>
  28. #include <ipxe/interface.h>
  29. /** @file
  30. *
  31. * ACPI support functions
  32. *
  33. */
  34. /******************************************************************************
  35. *
  36. * Utility functions
  37. *
  38. ******************************************************************************
  39. */
  40. /**
  41. * Compute ACPI table checksum
  42. *
  43. * @v table Any ACPI table
  44. * @ret checksum 0 if checksum is good
  45. */
  46. static uint8_t acpi_checksum ( userptr_t table ) {
  47. struct acpi_header acpi;
  48. uint8_t sum = 0;
  49. uint8_t data = 0;
  50. unsigned int i;
  51. /* Read table length */
  52. copy_from_user ( &acpi.length, table,
  53. offsetof ( typeof ( acpi ), length ),
  54. sizeof ( acpi.length ) );
  55. /* Compute checksum */
  56. for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
  57. copy_from_user ( &data, table, i, sizeof ( data ) );
  58. sum += data;
  59. }
  60. return sum;
  61. }
  62. /**
  63. * Fix up ACPI table checksum
  64. *
  65. * @v acpi ACPI table header
  66. */
  67. void acpi_fix_checksum ( struct acpi_header *acpi ) {
  68. /* Update checksum */
  69. acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
  70. }
  71. /**
  72. * Locate ACPI table
  73. *
  74. * @v signature Requested table signature
  75. * @v index Requested index of table with this signature
  76. * @ret table Table, or UNULL if not found
  77. */
  78. userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
  79. struct acpi_header acpi;
  80. struct acpi_rsdt *rsdtab;
  81. typeof ( rsdtab->entry[0] ) entry;
  82. userptr_t rsdt;
  83. userptr_t table;
  84. size_t len;
  85. unsigned int count;
  86. unsigned int i;
  87. /* Locate RSDT */
  88. rsdt = acpi_find_rsdt();
  89. if ( ! rsdt ) {
  90. DBG ( "RSDT not found\n" );
  91. return UNULL;
  92. }
  93. /* Read RSDT header */
  94. copy_from_user ( &acpi, rsdt, 0, sizeof ( acpi ) );
  95. if ( acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) {
  96. DBGC ( rsdt, "RSDT %#08lx has invalid signature:\n",
  97. user_to_phys ( rsdt, 0 ) );
  98. DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
  99. sizeof ( acpi ) );
  100. return UNULL;
  101. }
  102. len = le32_to_cpu ( acpi.length );
  103. if ( len < sizeof ( rsdtab->acpi ) ) {
  104. DBGC ( rsdt, "RSDT %#08lx has invalid length:\n",
  105. user_to_phys ( rsdt, 0 ) );
  106. DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
  107. sizeof ( acpi ) );
  108. return UNULL;
  109. }
  110. /* Calculate number of entries */
  111. count = ( ( len - sizeof ( rsdtab->acpi ) ) / sizeof ( entry ) );
  112. /* Search through entries */
  113. for ( i = 0 ; i < count ; i++ ) {
  114. /* Get table address */
  115. copy_from_user ( &entry, rsdt,
  116. offsetof ( typeof ( *rsdtab ), entry[i] ),
  117. sizeof ( entry ) );
  118. /* Read table header */
  119. table = phys_to_user ( entry );
  120. copy_from_user ( &acpi.signature, table, 0,
  121. sizeof ( acpi.signature ) );
  122. /* Check table signature */
  123. if ( acpi.signature != cpu_to_le32 ( signature ) )
  124. continue;
  125. /* Check index */
  126. if ( index-- )
  127. continue;
  128. /* Check table integrity */
  129. if ( acpi_checksum ( table ) != 0 ) {
  130. DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
  131. "at %08lx\n", user_to_phys ( rsdt, 0 ),
  132. acpi_name ( signature ),
  133. user_to_phys ( table, 0 ) );
  134. break;
  135. }
  136. DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
  137. user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
  138. user_to_phys ( table, 0 ) );
  139. return table;
  140. }
  141. DBGC ( rsdt, "RSDT %#08lx could not find %s\n",
  142. user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
  143. return UNULL;
  144. }
  145. /**
  146. * Extract \_Sx value from DSDT/SSDT
  147. *
  148. * @v zsdt DSDT or SSDT
  149. * @v signature Signature (e.g. "_S5_")
  150. * @ret sx \_Sx value, or negative error
  151. *
  152. * In theory, extracting the \_Sx value from the DSDT/SSDT requires a
  153. * full ACPI parser plus some heuristics to work around the various
  154. * broken encodings encountered in real ACPI implementations.
  155. *
  156. * In practice, we can get the same result by scanning through the
  157. * DSDT/SSDT for the signature (e.g. "_S5_"), extracting the first
  158. * four bytes, removing any bytes with bit 3 set, and treating
  159. * whatever is left as a little-endian value. This is one of the
  160. * uglier hacks I have ever implemented, but it's still prettier than
  161. * the ACPI specification itself.
  162. */
  163. static int acpi_sx_zsdt ( userptr_t zsdt, uint32_t signature ) {
  164. struct acpi_header acpi;
  165. union {
  166. uint32_t dword;
  167. uint8_t byte[4];
  168. } buf;
  169. size_t offset;
  170. size_t len;
  171. unsigned int sx;
  172. uint8_t *byte;
  173. /* Read table header */
  174. copy_from_user ( &acpi, zsdt, 0, sizeof ( acpi ) );
  175. len = le32_to_cpu ( acpi.length );
  176. /* Locate signature */
  177. for ( offset = sizeof ( acpi ) ;
  178. ( ( offset + sizeof ( buf ) /* signature */ + 3 /* pkg header */
  179. + sizeof ( buf ) /* value */ ) < len ) ;
  180. offset++ ) {
  181. /* Check signature */
  182. copy_from_user ( &buf, zsdt, offset, sizeof ( buf ) );
  183. if ( buf.dword != cpu_to_le32 ( signature ) )
  184. continue;
  185. DBGC ( zsdt, "DSDT/SSDT %#08lx found %s at offset %#zx\n",
  186. user_to_phys ( zsdt, 0 ), acpi_name ( signature ),
  187. offset );
  188. offset += sizeof ( buf );
  189. /* Read first four bytes of value */
  190. copy_from_user ( &buf, zsdt, ( offset + 3 /* pkg header */ ),
  191. sizeof ( buf ) );
  192. DBGC ( zsdt, "DSDT/SSDT %#08lx found %s containing "
  193. "%02x:%02x:%02x:%02x\n", user_to_phys ( zsdt, 0 ),
  194. acpi_name ( signature ), buf.byte[0], buf.byte[1],
  195. buf.byte[2], buf.byte[3] );
  196. /* Extract \Sx value. There are three potential
  197. * encodings that we might encounter:
  198. *
  199. * - SLP_TYPa, SLP_TYPb, rsvd, rsvd
  200. *
  201. * - <byteprefix>, SLP_TYPa, <byteprefix>, SLP_TYPb, ...
  202. *
  203. * - <dwordprefix>, SLP_TYPa, SLP_TYPb, 0, 0
  204. *
  205. * Since <byteprefix> and <dwordprefix> both have bit
  206. * 3 set, and valid SLP_TYPx must have bit 3 clear
  207. * (since SLP_TYPx is a 3-bit field), we can just skip
  208. * any bytes with bit 3 set.
  209. */
  210. byte = &buf.byte[0];
  211. if ( *byte & 0x08 )
  212. byte++;
  213. sx = *(byte++);
  214. if ( *byte & 0x08 )
  215. byte++;
  216. sx |= ( *byte << 8 );
  217. return sx;
  218. }
  219. return -ENOENT;
  220. }
  221. /**
  222. * Extract \_Sx value from DSDT/SSDT
  223. *
  224. * @v signature Signature (e.g. "_S5_")
  225. * @ret sx \_Sx value, or negative error
  226. */
  227. int acpi_sx ( uint32_t signature ) {
  228. struct acpi_fadt fadtab;
  229. userptr_t rsdt;
  230. userptr_t fadt;
  231. userptr_t dsdt;
  232. userptr_t ssdt;
  233. unsigned int i;
  234. int sx;
  235. /* Locate RSDT */
  236. rsdt = acpi_find_rsdt();
  237. if ( ! rsdt ) {
  238. DBG ( "RSDT not found\n" );
  239. return -ENOENT;
  240. }
  241. /* Try DSDT first */
  242. fadt = acpi_find ( FADT_SIGNATURE, 0 );
  243. if ( fadt ) {
  244. copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
  245. dsdt = phys_to_user ( fadtab.dsdt );
  246. if ( ( sx = acpi_sx_zsdt ( dsdt, signature ) ) >= 0 )
  247. return sx;
  248. }
  249. /* Try all SSDTs */
  250. for ( i = 0 ; ; i++ ) {
  251. ssdt = acpi_find ( SSDT_SIGNATURE, i );
  252. if ( ! ssdt )
  253. break;
  254. if ( ( sx = acpi_sx_zsdt ( ssdt, signature ) ) >= 0 )
  255. return sx;
  256. }
  257. DBGC ( rsdt, "RSDT %#08lx could not find \\_Sx \"%s\"\n",
  258. user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
  259. return -ENOENT;
  260. }
  261. /******************************************************************************
  262. *
  263. * Descriptors
  264. *
  265. ******************************************************************************
  266. */
  267. /**
  268. * Add ACPI descriptor
  269. *
  270. * @v desc ACPI descriptor
  271. */
  272. void acpi_add ( struct acpi_descriptor *desc ) {
  273. /* Add to list of descriptors */
  274. ref_get ( desc->refcnt );
  275. list_add_tail ( &desc->list, &desc->model->descs );
  276. }
  277. /**
  278. * Remove ACPI descriptor
  279. *
  280. * @v desc ACPI descriptor
  281. */
  282. void acpi_del ( struct acpi_descriptor *desc ) {
  283. /* Remove from list of descriptors */
  284. list_check_contains_entry ( desc, &desc->model->descs, list );
  285. list_del ( &desc->list );
  286. ref_put ( desc->refcnt );
  287. }
  288. /**
  289. * Get object's ACPI descriptor
  290. *
  291. * @v intf Interface
  292. * @ret desc ACPI descriptor, or NULL
  293. */
  294. struct acpi_descriptor * acpi_describe ( struct interface *intf ) {
  295. struct interface *dest;
  296. acpi_describe_TYPE ( void * ) *op =
  297. intf_get_dest_op ( intf, acpi_describe, &dest );
  298. void *object = intf_object ( dest );
  299. struct acpi_descriptor *desc;
  300. if ( op ) {
  301. desc = op ( object );
  302. } else {
  303. desc = NULL;
  304. }
  305. intf_put ( dest );
  306. return desc;
  307. }
  308. /**
  309. * Install ACPI tables
  310. *
  311. * @v install Table installation method
  312. * @ret rc Return status code
  313. */
  314. int acpi_install ( int ( * install ) ( struct acpi_header *acpi ) ){
  315. struct acpi_model *model;
  316. int rc;
  317. for_each_table_entry ( model, ACPI_MODELS ) {
  318. if ( ( rc = model->install ( install ) ) != 0 )
  319. return rc;
  320. }
  321. return 0;
  322. }