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 #include <sys/types.h> |
| 9 #include <sys/stat.h> |
| 10 #include <unistd.h> |
| 11 #include <ctype.h> |
8 | 12 |
9 #include "host_common.h" | 13 #include "host_common.h" |
10 | 14 |
11 #include "crossystem.h" | 15 #include "crossystem.h" |
12 #include "utility.h" | 16 #include "utility.h" |
13 #include "vboot_common.h" | 17 #include "vboot_common.h" |
14 #include "vboot_nvstorage.h" | 18 #include "vboot_nvstorage.h" |
15 | 19 |
16 /* ACPI constants from Chrome OS Main Processor Firmware Spec */ | 20 /* ACPI constants from Chrome OS Main Processor Firmware Spec */ |
17 /* GPIO signal types */ | 21 /* GPIO signal types */ |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 65 |
62 /* Base name for ACPI files */ | 66 /* Base name for ACPI files */ |
63 #define ACPI_BASE_PATH "/sys/devices/platform/chromeos_acpi" | 67 #define ACPI_BASE_PATH "/sys/devices/platform/chromeos_acpi" |
64 /* Paths for frequently used ACPI files */ | 68 /* Paths for frequently used ACPI files */ |
65 #define ACPI_BINF_PATH ACPI_BASE_PATH "/BINF" | 69 #define ACPI_BINF_PATH ACPI_BASE_PATH "/BINF" |
66 #define ACPI_CHNV_PATH ACPI_BASE_PATH "/CHNV" | 70 #define ACPI_CHNV_PATH ACPI_BASE_PATH "/CHNV" |
67 #define ACPI_CHSW_PATH ACPI_BASE_PATH "/CHSW" | 71 #define ACPI_CHSW_PATH ACPI_BASE_PATH "/CHSW" |
68 #define ACPI_FMAP_PATH ACPI_BASE_PATH "/FMAP" | 72 #define ACPI_FMAP_PATH ACPI_BASE_PATH "/FMAP" |
69 #define ACPI_GPIO_PATH ACPI_BASE_PATH "/GPIO" | 73 #define ACPI_GPIO_PATH ACPI_BASE_PATH "/GPIO" |
70 #define ACPI_VBNV_PATH ACPI_BASE_PATH "/VBNV" | 74 #define ACPI_VBNV_PATH ACPI_BASE_PATH "/VBNV" |
| 75 #define ACPI_VDAT_PATH ACPI_BASE_PATH "/VDAT" |
71 | 76 |
72 /* Base name for GPIO files */ | 77 /* Base name for GPIO files */ |
73 #define GPIO_BASE_PATH "/sys/class/gpio" | 78 #define GPIO_BASE_PATH "/sys/class/gpio" |
74 #define GPIO_EXPORT_PATH GPIO_BASE_PATH "/export" | 79 #define GPIO_EXPORT_PATH GPIO_BASE_PATH "/export" |
75 | 80 |
76 /* Filename for NVRAM file */ | 81 /* Filename for NVRAM file */ |
77 #define NVRAM_PATH "/dev/nvram" | 82 #define NVRAM_PATH "/dev/nvram" |
78 | 83 |
79 /* Filename for kernel command line */ | 84 /* Filename for kernel command line */ |
80 #define KERNEL_CMDLINE_PATH "/proc/cmdline" | 85 #define KERNEL_CMDLINE_PATH "/proc/cmdline" |
81 | 86 |
| 87 /* A structure to contain buffer data retrieved from the ACPI. */ |
| 88 typedef struct { |
| 89 int buffer_size; |
| 90 void* buffer; |
| 91 } AcpiBuffer; |
| 92 |
82 | 93 |
83 /* Copy up to dest_size-1 characters from src to dest, ensuring null | 94 /* Copy up to dest_size-1 characters from src to dest, ensuring null |
84 termination (which strncpy() doesn't do). Returns the destination | 95 termination (which strncpy() doesn't do). Returns the destination |
85 string. */ | 96 string. */ |
86 char* StrCopy(char* dest, const char* src, int dest_size) { | 97 char* StrCopy(char* dest, const char* src, int dest_size) { |
87 strncpy(dest, src, dest_size); | 98 strncpy(dest, src, dest_size); |
88 dest[dest_size - 1] = '\0'; | 99 dest[dest_size - 1] = '\0'; |
89 return dest; | 100 return dest; |
90 } | 101 } |
91 | 102 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 if (0 != fseek(f, chnv, SEEK_SET) || EOF == (fputc(nvbyte, f))) { | 288 if (0 != fseek(f, chnv, SEEK_SET) || EOF == (fputc(nvbyte, f))) { |
278 fclose(f); | 289 fclose(f); |
279 return -1; | 290 return -1; |
280 } | 291 } |
281 | 292 |
282 /* Success */ | 293 /* Success */ |
283 fclose(f); | 294 fclose(f); |
284 return 0; | 295 return 0; |
285 } | 296 } |
286 | 297 |
| 298 /* |
| 299 * Get buffer data from ACPI. |
| 300 * |
| 301 * Buffer data is expected to be represented by a file which is a text dump of |
| 302 * the buffer, representing each byte by two hex numbers, space and newline |
| 303 * separated. |
| 304 * |
| 305 * Input - ACPI file name to get data from. |
| 306 * |
| 307 * Output: a pointer to AcpiBuffer structure containing the binary |
| 308 * representation of the data. The caller is responsible for |
| 309 * deallocating the pointer, this will take care of both the structure |
| 310 * and the buffer. Null in case of error. |
| 311 */ |
| 312 |
| 313 AcpiBuffer* VbGetBuffer(const char* filename) |
| 314 { |
| 315 FILE* f = NULL; |
| 316 char* file_buffer = NULL; |
| 317 AcpiBuffer* acpi_buffer = NULL; |
| 318 AcpiBuffer* return_value = NULL; |
| 319 |
| 320 do { |
| 321 struct stat fs; |
| 322 unsigned char* output_ptr; |
| 323 int rv, i, real_size; |
| 324 |
| 325 rv = stat(filename, &fs); |
| 326 if (rv || !S_ISREG(fs.st_mode)) |
| 327 break; |
| 328 |
| 329 f = fopen(filename, "r"); |
| 330 if (!f) |
| 331 break; |
| 332 |
| 333 file_buffer = Malloc(fs.st_size + 1); |
| 334 if (!file_buffer) |
| 335 break; |
| 336 |
| 337 |
| 338 real_size = fread(file_buffer, 1, fs.st_size, f); |
| 339 if (!real_size) |
| 340 break; |
| 341 |
| 342 /* each byte in the output will replace two characters and a space in the |
| 343 * input, so the output size does not exceed input side/3 (a little less |
| 344 * if account for newline characters). |
| 345 */ |
| 346 acpi_buffer = Malloc(sizeof(AcpiBuffer) + real_size/3); |
| 347 |
| 348 if (!acpi_buffer) |
| 349 break; |
| 350 |
| 351 file_buffer[real_size] = '\0'; |
| 352 |
| 353 acpi_buffer->buffer = acpi_buffer + 1; |
| 354 acpi_buffer->buffer_size = 0; |
| 355 output_ptr = acpi_buffer->buffer; |
| 356 |
| 357 /* process the file contents */ |
| 358 for (i = 0; i < real_size; i++) { |
| 359 char* base, *end; |
| 360 |
| 361 base = file_buffer + i; |
| 362 |
| 363 if (!isxdigit(*base)) |
| 364 continue; |
| 365 |
| 366 output_ptr[acpi_buffer->buffer_size++] = strtol(base, &end, 16) & 0xff; |
| 367 |
| 368 if ((end - base) != 2) |
| 369 /* Input file format error */ |
| 370 break; |
| 371 |
| 372 i += 2; /* skip the second character and the following space */ |
| 373 } |
| 374 |
| 375 if (i == real_size) { |
| 376 /* all is well */ |
| 377 return_value = acpi_buffer; |
| 378 acpi_buffer = NULL; /* prevent it from deallocating */ |
| 379 } |
| 380 } while(0); |
| 381 |
| 382 /* wrap up */ |
| 383 if (f) |
| 384 fclose(f); |
| 385 |
| 386 if (file_buffer) |
| 387 Free(file_buffer); |
| 388 |
| 389 if (acpi_buffer) |
| 390 Free(acpi_buffer); |
| 391 |
| 392 return return_value; |
| 393 } |
287 | 394 |
288 /* Read an integer property from VbNvStorage. | 395 /* Read an integer property from VbNvStorage. |
289 * | 396 * |
290 * Returns the parameter value, or -1 if error. */ | 397 * Returns the parameter value, or -1 if error. */ |
291 int VbGetNvStorage(VbNvParam param) { | 398 int VbGetNvStorage(VbNvParam param) { |
292 FILE* f; | 399 FILE* f; |
293 VbNvContext vnc; | 400 VbNvContext vnc; |
294 int offs; | 401 int offs; |
295 uint32_t value; | 402 uint32_t value; |
296 int retval; | 403 int retval; |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 return VbGetRecoveryReason(); | 665 return VbGetRecoveryReason(); |
559 } else if (!strcasecmp(name,"fmap_base")) { | 666 } else if (!strcasecmp(name,"fmap_base")) { |
560 value = ReadFileInt(ACPI_FMAP_PATH); | 667 value = ReadFileInt(ACPI_FMAP_PATH); |
561 } else if (!strcasecmp(name,"cros_debug")) { | 668 } else if (!strcasecmp(name,"cros_debug")) { |
562 value = VbGetCrosDebug(); | 669 value = VbGetCrosDebug(); |
563 } | 670 } |
564 | 671 |
565 return value; | 672 return value; |
566 } | 673 } |
567 | 674 |
| 675 /* This function is just an example illustrating the use of VbGetBuffer(). It |
| 676 * converts the binary contents of the buffer into a space delimetered hex |
| 677 * string. It is expected to be replaced with a function which has knowledge |
| 678 * of the buffer data structure. |
| 679 */ |
| 680 char* GetVdatBuffer(void) |
| 681 { |
| 682 char* buffer, *src, *p; |
| 683 int i; |
| 684 |
| 685 AcpiBuffer* ab = VbGetBuffer(ACPI_VDAT_PATH); |
| 686 if (!ab) |
| 687 return NULL; |
| 688 |
| 689 buffer = Malloc(ab->buffer_size * 3 + 2); |
| 690 p = buffer; |
| 691 src = ab->buffer; |
| 692 for (i = 0; i < ab->buffer_size; i++) { |
| 693 snprintf(p, 4, " %2.2x", *src++); |
| 694 p += 3; |
| 695 } |
| 696 *p = '\0'; |
| 697 Free(ab); |
| 698 return buffer; |
| 699 } |
568 | 700 |
569 /* Read a system property string into a destination buffer of the specified | 701 /* Read a system property string into a destination buffer of the specified |
570 * size. | 702 * size. |
571 * | 703 * |
572 * Returns the passed buffer, or NULL if error. */ | 704 * Returns the passed buffer, or NULL if error. */ |
573 const char* VbGetSystemPropertyString(const char* name, char* dest, int size) { | 705 const char* VbGetSystemPropertyString(const char* name, char* dest, int size) { |
574 | 706 |
575 if (!strcasecmp(name,"hwid")) { | 707 if (!strcasecmp(name,"hwid")) { |
576 return ReadFileString(dest, size, ACPI_BASE_PATH "/HWID"); | 708 return ReadFileString(dest, size, ACPI_BASE_PATH "/HWID"); |
577 } else if (!strcasecmp(name,"fwid")) { | 709 } else if (!strcasecmp(name,"fwid")) { |
(...skipping 24 matching lines...) Expand all Loading... |
602 } | 734 } |
603 } else if (!strcasecmp(name,"kernkey_vfy")) { | 735 } else if (!strcasecmp(name,"kernkey_vfy")) { |
604 switch(VbGetNvStorage(VBNV_FW_VERIFIED_KERNEL_KEY)) { | 736 switch(VbGetNvStorage(VBNV_FW_VERIFIED_KERNEL_KEY)) { |
605 case 0: | 737 case 0: |
606 return "hash"; | 738 return "hash"; |
607 case 1: | 739 case 1: |
608 return "sig"; | 740 return "sig"; |
609 default: | 741 default: |
610 return NULL; | 742 return NULL; |
611 } | 743 } |
| 744 } else if (!strcasecmp(name, "vdat")) { |
| 745 return GetVdatBuffer(); |
612 } else | 746 } else |
613 return NULL; | 747 return NULL; |
614 } | 748 } |
615 | 749 |
616 | 750 |
617 /* Set a system property integer. | 751 /* Set a system property integer. |
618 * | 752 * |
619 * Returns 0 if success, -1 if error. */ | 753 * Returns 0 if success, -1 if error. */ |
620 int VbSetSystemPropertyInt(const char* name, int value) { | 754 int VbSetSystemPropertyInt(const char* name, int value) { |
621 | 755 |
(...skipping 25 matching lines...) Expand all Loading... |
647 | 781 |
648 | 782 |
649 /* Set a system property string. | 783 /* Set a system property string. |
650 * | 784 * |
651 * Returns 0 if success, -1 if error. */ | 785 * Returns 0 if success, -1 if error. */ |
652 int VbSetSystemPropertyString(const char* name, const char* value) { | 786 int VbSetSystemPropertyString(const char* name, const char* value) { |
653 | 787 |
654 /* TODO: support setting */ | 788 /* TODO: support setting */ |
655 return -1; | 789 return -1; |
656 } | 790 } |
OLD | NEW |