Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

smbios_settings.c 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (C) 2008 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <stdint.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <gpxe/settings.h>
  22. #include <gpxe/init.h>
  23. #include <gpxe/uuid.h>
  24. #include <smbios.h>
  25. /**
  26. * Construct SMBIOS raw-data tag
  27. *
  28. * @v _type SMBIOS structure type number
  29. * @v _structure SMBIOS structure data type
  30. * @v _field Field within SMBIOS structure data type
  31. * @ret tag SMBIOS setting tag
  32. */
  33. #define SMBIOS_RAW_TAG( _type, _structure, _field ) \
  34. ( ( (_type) << 16 ) | \
  35. ( offsetof ( _structure, _field ) << 8 ) | \
  36. ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
  37. /**
  38. * Construct SMBIOS string tag
  39. *
  40. * @v _type SMBIOS structure type number
  41. * @v _structure SMBIOS structure data type
  42. * @v _field Field within SMBIOS structure data type
  43. * @ret tag SMBIOS setting tag
  44. */
  45. #define SMBIOS_STRING_TAG( _type, _structure, _field ) \
  46. ( ( (_type) << 16 ) | \
  47. ( offsetof ( _structure, _field ) << 8 ) )
  48. /**
  49. * Store value of SMBIOS setting
  50. *
  51. * @v settings Settings block
  52. * @v setting Setting to store
  53. * @v data Setting data, or NULL to clear setting
  54. * @v len Length of setting data
  55. * @ret rc Return status code
  56. */
  57. static int smbios_store ( struct settings *settings __unused,
  58. struct setting *setting __unused,
  59. const void *data __unused, size_t len __unused ) {
  60. /* Cannot write data into SMBIOS */
  61. return -ENOTSUP;
  62. }
  63. /**
  64. * Fetch value of SMBIOS setting
  65. *
  66. * @v settings Settings block, or NULL to search all blocks
  67. * @v setting Setting to fetch
  68. * @v data Buffer to fill with setting data
  69. * @v len Length of buffer
  70. * @ret len Length of setting data, or negative error
  71. */
  72. static int smbios_fetch ( struct settings *settings __unused,
  73. struct setting *setting,
  74. void *data, size_t len ) {
  75. struct smbios_structure structure;
  76. unsigned int tag_type;
  77. unsigned int tag_offset;
  78. unsigned int tag_len;
  79. int rc;
  80. /* Split tag into type, offset and length */
  81. tag_type = ( setting->tag >> 16 );
  82. tag_offset = ( ( setting->tag >> 8 ) & 0xff );
  83. tag_len = ( setting->tag & 0xff );
  84. if ( ! tag_type )
  85. return -ENOENT;
  86. /* Find SMBIOS structure */
  87. if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 )
  88. return rc;
  89. {
  90. uint8_t buf[structure.header.len];
  91. /* Read SMBIOS structure */
  92. if ( ( rc = read_smbios_structure ( &structure, buf,
  93. sizeof ( buf ) ) ) != 0 )
  94. return rc;
  95. if ( tag_len == 0 ) {
  96. /* String */
  97. return read_smbios_string ( &structure,
  98. buf[tag_offset],
  99. data, len );
  100. } else {
  101. /* Raw data */
  102. if ( len > tag_len )
  103. len = tag_len;
  104. memcpy ( data, &buf[tag_offset], len );
  105. return tag_len;
  106. }
  107. }
  108. }
  109. /** SMBIOS settings operations */
  110. static struct settings_operations smbios_settings_operations = {
  111. .store = smbios_store,
  112. .fetch = smbios_fetch,
  113. };
  114. /** SMBIOS settings */
  115. static struct settings smbios_settings = {
  116. .refcnt = NULL,
  117. .name = "smbios",
  118. .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
  119. .children = LIST_HEAD_INIT ( smbios_settings.children ),
  120. .op = &smbios_settings_operations,
  121. };
  122. /** Initialise SMBIOS settings */
  123. static void smbios_init ( void ) {
  124. int rc;
  125. if ( ( rc = register_settings ( &smbios_settings, NULL ) ) != 0 ) {
  126. DBG ( "SMBIOS could not register settings: %s\n",
  127. strerror ( rc ) );
  128. return;
  129. }
  130. }
  131. /** SMBIOS settings initialiser */
  132. struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
  133. .initialise = smbios_init,
  134. };
  135. /** UUID setting obtained via SMBIOS */
  136. struct setting uuid_setting __setting = {
  137. .name = "uuid",
  138. .description = "UUID",
  139. .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
  140. struct smbios_system_information, uuid ),
  141. .type = &setting_type_uuid,
  142. };
  143. /** Other SMBIOS named settings */
  144. struct setting smbios_named_settings[] __setting = {
  145. {
  146. .name = "manufacturer",
  147. .description = "Manufacturer",
  148. .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
  149. struct smbios_system_information,
  150. manufacturer ),
  151. .type = &setting_type_string,
  152. },
  153. {
  154. .name = "product",
  155. .description = "Product name",
  156. .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
  157. struct smbios_system_information,
  158. product ),
  159. .type = &setting_type_string,
  160. },
  161. {
  162. .name = "serial",
  163. .description = "Serial number",
  164. .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
  165. struct smbios_system_information,
  166. serial ),
  167. .type = &setting_type_string,
  168. },
  169. };