OLD | NEW |
1 /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 */ | 4 */ |
5 | 5 |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "host_common.h" | 9 #include "host_common.h" |
10 | 10 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 #define BINF0_RECOVERY_TPM_ERROR 11 | 56 #define BINF0_RECOVERY_TPM_ERROR 11 |
57 | 57 |
58 /* Base name for ACPI files */ | 58 /* Base name for ACPI files */ |
59 #define ACPI_BASE_PATH "/sys/devices/platform/chromeos_acpi" | 59 #define ACPI_BASE_PATH "/sys/devices/platform/chromeos_acpi" |
60 /* Paths for frequently used ACPI files */ | 60 /* Paths for frequently used ACPI files */ |
61 #define ACPI_BINF_PATH ACPI_BASE_PATH "/BINF" | 61 #define ACPI_BINF_PATH ACPI_BASE_PATH "/BINF" |
62 #define ACPI_CHNV_PATH ACPI_BASE_PATH "/CHNV" | 62 #define ACPI_CHNV_PATH ACPI_BASE_PATH "/CHNV" |
63 #define ACPI_CHSW_PATH ACPI_BASE_PATH "/CHSW" | 63 #define ACPI_CHSW_PATH ACPI_BASE_PATH "/CHSW" |
64 #define ACPI_FMAP_PATH ACPI_BASE_PATH "/FMAP" | 64 #define ACPI_FMAP_PATH ACPI_BASE_PATH "/FMAP" |
65 #define ACPI_GPIO_PATH ACPI_BASE_PATH "/GPIO" | 65 #define ACPI_GPIO_PATH ACPI_BASE_PATH "/GPIO" |
| 66 #define ACPI_VBNV_PATH ACPI_BASE_PATH "/VBNV" |
66 | 67 |
67 /* Base name for GPIO files */ | 68 /* Base name for GPIO files */ |
68 #define GPIO_BASE_PATH "/sys/class/gpio" | 69 #define GPIO_BASE_PATH "/sys/class/gpio" |
69 #define GPIO_EXPORT_PATH GPIO_BASE_PATH "/export" | 70 #define GPIO_EXPORT_PATH GPIO_BASE_PATH "/export" |
70 | 71 |
71 /* Base name for NVRAM file */ | 72 /* Base name for NVRAM file */ |
72 #define NVRAM_PATH "/dev/nvram" | 73 #define NVRAM_PATH "/dev/nvram" |
73 | 74 |
74 | 75 |
75 /* Copy up to dest_size-1 characters from src to dest, ensuring null | 76 /* Copy up to dest_size-1 characters from src to dest, ensuring null |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 if (0 != fseek(f, chnv, SEEK_SET) || EOF == (fputc(nvbyte, f))) { | 270 if (0 != fseek(f, chnv, SEEK_SET) || EOF == (fputc(nvbyte, f))) { |
270 fclose(f); | 271 fclose(f); |
271 return -1; | 272 return -1; |
272 } | 273 } |
273 | 274 |
274 /* Success */ | 275 /* Success */ |
275 fclose(f); | 276 fclose(f); |
276 return 0; | 277 return 0; |
277 } | 278 } |
278 | 279 |
| 280 |
| 281 /* Read an integer property from VbNvStorage. |
| 282 * |
| 283 * Returns the parameter value, or -1 if error. */ |
| 284 int VbGetNvStorage(VbNvParam param) { |
| 285 FILE* f; |
| 286 VbNvContext vnc; |
| 287 int offs; |
| 288 uint32_t value; |
| 289 int retval; |
| 290 |
| 291 /* Get the byte offset from VBNV */ |
| 292 offs = ReadFileInt(ACPI_VBNV_PATH ".0"); |
| 293 if (offs == -1) |
| 294 return -1; |
| 295 if (VBNV_BLOCK_SIZE > ReadFileInt(ACPI_VBNV_PATH ".1")) |
| 296 return -1; /* NV storage block is too small */ |
| 297 |
| 298 /* TODO: locking around NV access */ |
| 299 f = fopen(NVRAM_PATH, "rb"); |
| 300 if (!f) |
| 301 return -1; |
| 302 |
| 303 if (0 != fseek(f, offs, SEEK_SET) || |
| 304 1 != fread(vnc.raw, VBNV_BLOCK_SIZE, 1, f)) { |
| 305 fclose(f); |
| 306 return -1; |
| 307 } |
| 308 |
| 309 fclose(f); |
| 310 |
| 311 if (0 != VbNvSetup(&vnc)) |
| 312 return -1; |
| 313 retval = VbNvGet(&vnc, param, &value); |
| 314 if (0 != VbNvTeardown(&vnc)) |
| 315 return -1; |
| 316 if (0 != retval) |
| 317 return -1; |
| 318 |
| 319 /* TODO: If vnc.raw_changed, attempt to reopen NVRAM for write and |
| 320 * save the new defaults. If we're able to, log. */ |
| 321 /* TODO: release lock */ |
| 322 |
| 323 return (int)value; |
| 324 } |
| 325 |
| 326 |
| 327 /* Write an integer property to VbNvStorage. |
| 328 * |
| 329 * Returns 0 if success, -1 if error. */ |
| 330 int VbSetNvStorage(VbNvParam param, int value) { |
| 331 FILE* f; |
| 332 VbNvContext vnc; |
| 333 int offs; |
| 334 int retval = -1; |
| 335 int i; |
| 336 |
| 337 /* Get the byte offset from VBNV */ |
| 338 offs = ReadFileInt(ACPI_VBNV_PATH ".0"); |
| 339 if (offs == -1) |
| 340 return -1; |
| 341 if (VBNV_BLOCK_SIZE > ReadFileInt(ACPI_VBNV_PATH ".1")) |
| 342 return -1; /* NV storage block is too small */ |
| 343 |
| 344 /* TODO: locking around NV access */ |
| 345 f = fopen(NVRAM_PATH, "w+b"); |
| 346 if (!f) |
| 347 return -1; |
| 348 |
| 349 if (0 != fseek(f, offs, SEEK_SET) || |
| 350 1 != fread(vnc.raw, VBNV_BLOCK_SIZE, 1, f)) { |
| 351 goto VbSetNvCleanup; |
| 352 } |
| 353 |
| 354 if (0 != VbNvSetup(&vnc)) |
| 355 goto VbSetNvCleanup; |
| 356 i = VbNvSet(&vnc, param, (uint32_t)value); |
| 357 if (0 != VbNvTeardown(&vnc)) |
| 358 goto VbSetNvCleanup; |
| 359 if (0 != i) |
| 360 goto VbSetNvCleanup; |
| 361 |
| 362 if (vnc.raw_changed) { |
| 363 if (0 != fseek(f, offs, SEEK_SET) || |
| 364 1 != fwrite(vnc.raw, VBNV_BLOCK_SIZE, 1, f)) |
| 365 goto VbSetNvCleanup; |
| 366 } |
| 367 |
| 368 /* Success */ |
| 369 retval = 0; |
| 370 |
| 371 VbSetNvCleanup: |
| 372 fclose(f); |
| 373 /* TODO: release lock */ |
| 374 return retval; |
| 375 } |
| 376 |
| 377 |
279 /* Read the recovery reason. Returns the reason code or -1 if error. */ | 378 /* Read the recovery reason. Returns the reason code or -1 if error. */ |
280 int VbGetRecoveryReason(void) { | 379 int VbGetRecoveryReason(void) { |
281 int value; | 380 int value; |
282 | 381 |
283 /* Try reading type from BINF.4 */ | 382 /* Try reading type from BINF.4 */ |
284 value = ReadFileInt(ACPI_BINF_PATH ".4"); | 383 value = ReadFileInt(ACPI_BINF_PATH ".4"); |
285 if (-1 != value) | 384 if (-1 != value) |
286 return value; | 385 return value; |
287 | 386 |
288 /* Fall back to BINF.0 for legacy systems like Mario. */ | 387 /* Fall back to BINF.0 for legacy systems like Mario. */ |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 if (-1 != value && FwidStartsWith("Mario.")) | 477 if (-1 != value && FwidStartsWith("Mario.")) |
379 value = 1 - value; /* Mario reports this backwards */ | 478 value = 1 - value; /* Mario reports this backwards */ |
380 } | 479 } |
381 /* Saved memory is at a fixed location for all H2C BIOS. If the CHSW | 480 /* Saved memory is at a fixed location for all H2C BIOS. If the CHSW |
382 * path exists in sysfs, it's a H2C BIOS. */ | 481 * path exists in sysfs, it's a H2C BIOS. */ |
383 else if (!strcasecmp(name,"savedmem_base")) { | 482 else if (!strcasecmp(name,"savedmem_base")) { |
384 return (-1 == ReadFileInt(ACPI_CHSW_PATH) ? -1 : 0x00F00000); | 483 return (-1 == ReadFileInt(ACPI_CHSW_PATH) ? -1 : 0x00F00000); |
385 } else if (!strcasecmp(name,"savedmem_size")) { | 484 } else if (!strcasecmp(name,"savedmem_size")) { |
386 return (-1 == ReadFileInt(ACPI_CHSW_PATH) ? -1 : 0x00100000); | 485 return (-1 == ReadFileInt(ACPI_CHSW_PATH) ? -1 : 0x00100000); |
387 } | 486 } |
388 /* NV storage values for older H2C BIOS */ | 487 /* NV storage values. If unable to get from NV storage, fall back to the |
| 488 * CMOS reboot field used by older BIOS. */ |
389 else if (!strcasecmp(name,"recovery_request")) { | 489 else if (!strcasecmp(name,"recovery_request")) { |
390 value = VbGetCmosRebootField(CMOSRF_RECOVERY); | 490 value = VbGetNvStorage(VBNV_RECOVERY_REQUEST); |
| 491 if (-1 == value) |
| 492 value = VbGetCmosRebootField(CMOSRF_RECOVERY); |
391 } else if (!strcasecmp(name,"dbg_reset")) { | 493 } else if (!strcasecmp(name,"dbg_reset")) { |
392 value = VbGetCmosRebootField(CMOSRF_DEBUG_RESET); | 494 value = VbGetNvStorage(VBNV_DEBUG_RESET_MODE); |
| 495 if (-1 == value) |
| 496 value = VbGetCmosRebootField(CMOSRF_DEBUG_RESET); |
393 } else if (!strcasecmp(name,"fwb_tries")) { | 497 } else if (!strcasecmp(name,"fwb_tries")) { |
394 value = VbGetCmosRebootField(CMOSRF_TRY_B); | 498 value = VbGetNvStorage(VBNV_TRY_B_COUNT); |
| 499 if (-1 == value) |
| 500 value = VbGetCmosRebootField(CMOSRF_TRY_B); |
395 } | 501 } |
396 /* Other parameters */ | 502 /* Other parameters */ |
397 else if (!strcasecmp(name,"recovery_reason")) { | 503 else if (!strcasecmp(name,"recovery_reason")) { |
398 return VbGetRecoveryReason(); | 504 return VbGetRecoveryReason(); |
399 } else if (!strcasecmp(name,"fmap_base")) { | 505 } else if (!strcasecmp(name,"fmap_base")) { |
400 value = ReadFileInt(ACPI_FMAP_PATH); | 506 value = ReadFileInt(ACPI_FMAP_PATH); |
401 } | 507 } |
402 | 508 |
403 /* TODO: implement the following properties: | 509 /* TODO: implement the following properties: |
404 * nvram_cleared | 510 * nvram_cleared |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 } else | 551 } else |
446 return NULL; | 552 return NULL; |
447 } | 553 } |
448 | 554 |
449 | 555 |
450 /* Set a system property integer. | 556 /* Set a system property integer. |
451 * | 557 * |
452 * Returns 0 if success, -1 if error. */ | 558 * Returns 0 if success, -1 if error. */ |
453 int VbSetSystemPropertyInt(const char* name, int value) { | 559 int VbSetSystemPropertyInt(const char* name, int value) { |
454 | 560 |
455 /* NV storage values for older H2C BIOS */ | 561 /* NV storage values. If unable to get from NV storage, fall back to the |
| 562 * CMOS reboot field used by older BIOS. */ |
456 if (!strcasecmp(name,"recovery_request")) { | 563 if (!strcasecmp(name,"recovery_request")) { |
| 564 if (0 == VbSetNvStorage(VBNV_RECOVERY_REQUEST, value)) |
| 565 return 0; |
457 return VbSetCmosRebootField(CMOSRF_RECOVERY, value); | 566 return VbSetCmosRebootField(CMOSRF_RECOVERY, value); |
458 } else if (!strcasecmp(name,"dbg_reset")) { | 567 } else if (!strcasecmp(name,"dbg_reset")) { |
459 return VbSetCmosRebootField(CMOSRF_DEBUG_RESET, value); | 568 if (0 == VbSetNvStorage(VBNV_DEBUG_RESET_MODE, value)) |
| 569 return 0; |
| 570 return VbSetCmosRebootField(CMOSRF_DEBUG_RESET, value); |
460 } else if (!strcasecmp(name,"fwb_tries")) { | 571 } else if (!strcasecmp(name,"fwb_tries")) { |
| 572 if (0 == VbSetNvStorage(VBNV_TRY_B_COUNT, value)) |
| 573 return 0; |
461 return VbSetCmosRebootField(CMOSRF_TRY_B, value); | 574 return VbSetCmosRebootField(CMOSRF_TRY_B, value); |
462 } | 575 } |
463 | 576 |
464 /* TODO: implement the following: | 577 /* TODO: implement the following: |
465 * nvram_cleared | 578 * nvram_cleared |
466 */ | 579 */ |
467 | 580 |
468 return -1; | 581 return -1; |
469 } | 582 } |
470 | 583 |
471 | 584 |
472 /* Set a system property string. | 585 /* Set a system property string. |
473 * | 586 * |
474 * Returns 0 if success, -1 if error. */ | 587 * Returns 0 if success, -1 if error. */ |
475 int VbSetSystemPropertyString(const char* name, const char* value) { | 588 int VbSetSystemPropertyString(const char* name, const char* value) { |
476 | 589 |
477 /* TODO: support setting */ | 590 /* TODO: support setting */ |
478 return -1; | 591 return -1; |
479 } | 592 } |
OLD | NEW |