| 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 |