crossystem.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
  2. * Use of this source code is governed by a BSD-style license that can be
  3. * found in the LICENSE file.
  4. *
  5. * Chrome OS firmware/system interface utility
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "crossystem.h"
  11. /*
  12. * Call arch specific init, if provided, otherwise use the 'weak' stub.
  13. */
  14. int __VbArchInit(void) { return 0; }
  15. int VbArchInit(void) __attribute__((weak, alias("__VbArchInit")));
  16. /* Flags for Param */
  17. #define IS_STRING 0x01 /* String (not present = integer) */
  18. #define CAN_WRITE 0x02 /* Writable (not present = read-only */
  19. #define NO_PRINT_ALL 0x04 /* Don't print contents of parameter when
  20. * doing a print-all */
  21. typedef struct Param {
  22. const char* name; /* Parameter name */
  23. int flags; /* Flags (see above) */
  24. const char* desc; /* Human-readable description */
  25. const char* format; /* Format string, if non-NULL and 0==is_string*/
  26. } Param;
  27. /* List of parameters, terminated with a param with NULL name */
  28. const Param sys_param_list[] = {
  29. {"arch", IS_STRING, "Platform architecture"},
  30. {"backup_nvram_request", CAN_WRITE,
  31. "Backup the nvram somewhere at the next boot. Cleared on success."},
  32. {"battery_cutoff_request", CAN_WRITE,
  33. "Cut off battery and shutdown on next boot."},
  34. {"block_devmode", CAN_WRITE, "Block all use of developer mode"},
  35. {"clear_tpm_owner_request", CAN_WRITE, "Clear TPM owner on next boot"},
  36. {"clear_tpm_owner_done", CAN_WRITE, "Clear TPM owner done"},
  37. {"cros_debug", 0, "OS should allow debug features"},
  38. {"dbg_reset", CAN_WRITE, "Debug reset mode request (writable)"},
  39. {"debug_build", 0, "OS image built for debug features"},
  40. {"dev_boot_usb", CAN_WRITE,
  41. "Enable developer mode boot from USB/SD (writable)"},
  42. {"dev_boot_legacy", CAN_WRITE,
  43. "Enable developer mode boot Legacy OSes (writable)"},
  44. {"dev_boot_signed_only", CAN_WRITE,
  45. "Enable developer mode boot only from official kernels (writable)"},
  46. {"dev_default_boot", IS_STRING|CAN_WRITE,
  47. "default boot from legacy or usb (writable)"},
  48. {"devsw_boot", 0, "Developer switch position at boot"},
  49. {"devsw_cur", 0, "Developer switch current position"},
  50. {"disable_dev_request", CAN_WRITE, "Disable virtual dev-mode on next boot"},
  51. {"ecfw_act", IS_STRING, "Active EC firmware"},
  52. {"fmap_base", 0, "Main firmware flashmap physical address", "0x%08x"},
  53. {"fwb_tries", CAN_WRITE, "Try firmware B count (writable)"},
  54. {"fw_vboot2", 0, "1 if firmware was selected by vboot2 or 0 otherwise"},
  55. {"fwid", IS_STRING, "Active firmware ID"},
  56. {"fwupdate_tries", CAN_WRITE,
  57. "Times to try OS firmware update (writable, inside kern_nv)"},
  58. {"fw_tried", IS_STRING, "Firmware tried this boot (vboot2)"},
  59. {"fw_try_count", CAN_WRITE, "Number of times to try fw_try_next (writable)"},
  60. {"fw_try_next", IS_STRING|CAN_WRITE,
  61. "Firmware to try next (vboot2,writable)"},
  62. {"fw_result", IS_STRING|CAN_WRITE,
  63. "Firmware result this boot (vboot2,writable)"},
  64. {"fw_prev_tried", IS_STRING, "Firmware tried on previous boot (vboot2)"},
  65. {"fw_prev_result", IS_STRING, "Firmware result of previous boot (vboot2)"},
  66. {"hwid", IS_STRING, "Hardware ID"},
  67. {"inside_vm", 0, "Running in a VM?"},
  68. {"kern_nv", 0, "Non-volatile field for kernel use", "0x%08x"},
  69. {"kernkey_vfy", IS_STRING, "Type of verification done on kernel key block"},
  70. {"loc_idx", CAN_WRITE, "Localization index for firmware screens (writable)"},
  71. {"mainfw_act", IS_STRING, "Active main firmware"},
  72. {"mainfw_type", IS_STRING, "Active main firmware type"},
  73. {"nvram_cleared", CAN_WRITE, "Have NV settings been lost? Write 0 to clear"},
  74. {"oprom_needed", CAN_WRITE, "Should we load the VGA Option ROM at boot?"},
  75. {"phase_enforcement", 0,
  76. "Board should have full security settings applied"},
  77. {"recovery_reason", 0, "Recovery mode reason for current boot"},
  78. {"recovery_request", CAN_WRITE, "Recovery mode request (writable)"},
  79. {"recovery_subcode", CAN_WRITE, "Recovery reason subcode (writable)"},
  80. {"recoverysw_boot", 0, "Recovery switch position at boot"},
  81. {"recoverysw_cur", 0, "Recovery switch current position"},
  82. {"recoverysw_ec_boot", 0, "Recovery switch position at EC boot"},
  83. {"ro_fwid", IS_STRING, "Read-only firmware ID"},
  84. {"sw_wpsw_boot", 0,
  85. "Firmware write protect software setting enabled at boot (Baytrail only)"},
  86. {"tpm_attack", CAN_WRITE, "TPM was interrupted since this flag was cleared"},
  87. {"tpm_fwver", 0, "Firmware version stored in TPM", "0x%08x"},
  88. {"tpm_kernver", 0, "Kernel version stored in TPM", "0x%08x"},
  89. {"tpm_rebooted", 0, "TPM requesting repeated reboot (vboot2)"},
  90. {"try_ro_sync", 0, "try read only software sync"},
  91. {"tried_fwb", 0, "Tried firmware B before A this boot"},
  92. {"vdat_flags", 0, "Flags from VbSharedData", "0x%08x"},
  93. {"vdat_lfdebug", IS_STRING|NO_PRINT_ALL,
  94. "LoadFirmware() debug data (not in print-all)"},
  95. {"vdat_lkdebug", IS_STRING|NO_PRINT_ALL,
  96. "LoadKernel() debug data (not in print-all)"},
  97. {"vdat_timers", IS_STRING, "Timer values from VbSharedData"},
  98. {"wipeout_request", CAN_WRITE, "Firmware requested factory reset (wipeout)"},
  99. {"wpsw_boot", 0, "Firmware write protect hardware switch position at boot"},
  100. {"wpsw_cur", 0, "Firmware write protect hardware switch current position"},
  101. /* Terminate with null name */
  102. {NULL, 0, NULL}
  103. };
  104. /* Print help */
  105. void PrintHelp(const char *progname) {
  106. const Param *p;
  107. printf("\nUsage:\n"
  108. " %s [--all]\n"
  109. " Prints all parameters with descriptions and current values.\n"
  110. " If --all is specified, prints even normally hidden fields.\n"
  111. " %s [param1 [param2 [...]]]\n"
  112. " Prints the current value(s) of the parameter(s).\n"
  113. " %s [param1=value1] [param2=value2 [...]]]\n"
  114. " Sets the parameter(s) to the specified value(s).\n"
  115. " %s [param1?value1] [param2?value2 [...]]]\n"
  116. " Checks if the parameter(s) all contain the specified value(s).\n"
  117. "Stops at the first error."
  118. "\n"
  119. "Valid parameters:\n", progname, progname, progname, progname);
  120. for (p = sys_param_list; p->name; p++)
  121. printf(" %-22s %s\n", p->name, p->desc);
  122. }
  123. /* Find the parameter in the list.
  124. *
  125. * Returns the parameter, or NULL if no match. */
  126. const Param* FindParam(const char* name) {
  127. const Param* p;
  128. if (!name)
  129. return NULL;
  130. for (p = sys_param_list; p->name; p++) {
  131. if (!strcasecmp(p->name, name))
  132. return p;
  133. }
  134. return NULL;
  135. }
  136. /* Set the specified parameter.
  137. *
  138. * Returns 0 if success, non-zero if error. */
  139. int SetParam(const Param* p, const char* value) {
  140. if (!(p->flags & CAN_WRITE))
  141. return 1; /* Parameter is read-only */
  142. if (p->flags & IS_STRING) {
  143. return (0 == VbSetSystemPropertyString(p->name, value) ? 0 : 1);
  144. } else {
  145. char* e;
  146. int i = (int)strtol(value, &e, 0);
  147. if (!*value || (e && *e))
  148. return 1;
  149. return (0 == VbSetSystemPropertyInt(p->name, i) ? 0 : 1);
  150. }
  151. }
  152. /* Compares the parameter with the expected value.
  153. *
  154. * Returns 0 if success (match), non-zero if error (mismatch). */
  155. int CheckParam(const Param* p, char* expect) {
  156. if (p->flags & IS_STRING) {
  157. char buf[VB_MAX_STRING_PROPERTY];
  158. const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
  159. if (!v || 0 != strcmp(v, expect))
  160. return 1;
  161. } else {
  162. char* e;
  163. int i = (int)strtol(expect, &e, 0);
  164. int v = VbGetSystemPropertyInt(p->name);
  165. if (!*expect || (e && *e))
  166. return 1;
  167. if (v == -1 || i != v)
  168. return 1;
  169. }
  170. return 0;
  171. }
  172. /* Print the specified parameter.
  173. *
  174. * Returns 0 if success, non-zero if error. */
  175. int PrintParam(const Param* p) {
  176. if (p->flags & IS_STRING) {
  177. char buf[VB_MAX_STRING_PROPERTY];
  178. const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
  179. if (!v)
  180. return 1;
  181. printf("%s", v);
  182. } else {
  183. int v = VbGetSystemPropertyInt(p->name);
  184. if (v == -1)
  185. return 1;
  186. printf(p->format ? p->format : "%d", v);
  187. }
  188. return 0;
  189. }
  190. /* Print all parameters with descriptions. If force_all!=0, prints even
  191. * parameters that specify the NO_PRINT_ALL flag.
  192. *
  193. * Returns 0 if success, non-zero if error. */
  194. int PrintAllParams(int force_all) {
  195. const Param* p;
  196. int retval = 0;
  197. char buf[VB_MAX_STRING_PROPERTY];
  198. const char* value;
  199. for (p = sys_param_list; p->name; p++) {
  200. if (0 == force_all && (p->flags & NO_PRINT_ALL))
  201. continue;
  202. if (p->flags & IS_STRING) {
  203. value = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
  204. } else {
  205. int v = VbGetSystemPropertyInt(p->name);
  206. if (v == -1)
  207. value = NULL;
  208. else {
  209. snprintf(buf, sizeof(buf), p->format ? p->format : "%d", v);
  210. value = buf;
  211. }
  212. }
  213. printf("%-22s = %-30s # %s\n",
  214. p->name, (value ? value : "(error)"), p->desc);
  215. }
  216. return retval;
  217. }
  218. int main(int argc, char* argv[]) {
  219. int retval = 0;
  220. int i;
  221. char* progname = strrchr(argv[0], '/');
  222. if (progname)
  223. progname++;
  224. else
  225. progname = argv[0];
  226. if (VbArchInit()) {
  227. fprintf(stderr, "Failed to initialize\n");
  228. return -1;
  229. }
  230. /* If no args specified, print all params */
  231. if (argc == 1)
  232. return PrintAllParams(0);
  233. /* --all or -a prints all params including normally hidden ones */
  234. if (!strcasecmp(argv[1], "--all") || !strcmp(argv[1], "-a"))
  235. return PrintAllParams(1);
  236. /* Print help if needed */
  237. if (!strcasecmp(argv[1], "-h") || !strcmp(argv[1], "-?")) {
  238. PrintHelp(progname);
  239. return 0;
  240. }
  241. /* Otherwise, loop through params and get/set them */
  242. for (i = 1; i < argc && retval == 0; i++) {
  243. char* has_set = strchr(argv[i], '=');
  244. char* has_expect = strchr(argv[i], '?');
  245. char* name = strtok(argv[i], "=?");
  246. char* value = strtok(NULL, "=?");
  247. const Param* p;
  248. /* Make sure args are well-formed. '' or '=foo' or '?foo' not allowed. */
  249. if (!name || has_set == argv[i] || has_expect == argv[i]) {
  250. fprintf(stderr, "Poorly formed parameter\n");
  251. PrintHelp(progname);
  252. return 1;
  253. }
  254. if (!value)
  255. value=""; /* Allow setting/checking an empty string ('foo=' or 'foo?') */
  256. if (has_set && has_expect) {
  257. fprintf(stderr, "Use either = or ? in a parameter, but not both.\n");
  258. PrintHelp(progname);
  259. return 1;
  260. }
  261. /* Find the parameter */
  262. p = FindParam(name);
  263. if (!p) {
  264. fprintf(stderr, "Invalid parameter name: %s\n", name);
  265. PrintHelp(progname);
  266. return 1;
  267. }
  268. if (i > 1)
  269. printf(" "); /* Output params space-delimited */
  270. if (has_set) {
  271. retval = SetParam(p, value);
  272. if (retval) {
  273. fprintf(stderr, "Parameter %s is read-only\n", name);
  274. }
  275. } else if (has_expect)
  276. retval = CheckParam(p, value);
  277. else
  278. retval = PrintParam(p);
  279. }
  280. return retval;
  281. }