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