mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-25 10:45:02 +00:00
Print LoadKernel() debug data from VbSharedData
Change-Id: I60cf9c4dd07e83b1ed1a5bac8a3ce8c2a54df45b R=reinauer@chromium.org BUG=chrome-os-partner:2748 TEST=manually check output of 'crossystem vdat_lkdebug' Review URL: http://codereview.chromium.org/6685097
This commit is contained in:
@@ -203,6 +203,7 @@ typedef struct VbSharedDataKernelPart {
|
||||
uint8_t gpt_index; /* Index of partition in GPT */
|
||||
uint8_t check_result; /* Check result; see VBSD_LKP_CHECK_* */
|
||||
uint8_t flags; /* Flags (see VBSD_LKP_FLAG_* */
|
||||
uint8_t reserved0; /* Reserved for padding */
|
||||
} VbSharedDataKernelPart;
|
||||
|
||||
/* Number of kernel partitions to track per call. Must be power of 2. */
|
||||
@@ -234,6 +235,7 @@ typedef struct VbSharedDataKernelCall {
|
||||
uint8_t test_error_num; /* Test error number, if non-zero */
|
||||
uint8_t return_code; /* Return code from LoadKernel() */
|
||||
uint8_t kernel_parts_found; /* Number of kernel partitions found */
|
||||
uint8_t reserved0[7]; /* Reserved for padding */
|
||||
VbSharedDataKernelPart parts[VBSD_MAX_KERNEL_PARTS]; /* Data on kernels */
|
||||
} VbSharedDataKernelCall;
|
||||
|
||||
@@ -261,6 +263,7 @@ typedef struct VbSharedDataHeader {
|
||||
uint64_t data_size; /* Size of shared data buffer in bytes */
|
||||
uint64_t data_used; /* Amount of shared data used so far */
|
||||
uint32_t flags; /* Flags */
|
||||
uint32_t reserved0; /* Reserved for padding */
|
||||
|
||||
VbPublicKey kernel_subkey; /* Kernel subkey, from firmware */
|
||||
uint64_t kernel_subkey_data_offset; /* Offset of kernel subkey data from
|
||||
@@ -286,6 +289,7 @@ typedef struct VbSharedDataHeader {
|
||||
uint8_t check_fw_b_result; /* Result of checking RW firmware B */
|
||||
uint8_t firmware_index; /* Firmware index returned by
|
||||
* LoadFirmware() or 0xFF if failure */
|
||||
uint8_t reserved1; /* Reserved for padding */
|
||||
uint32_t fw_version_tpm_start; /* Firmware TPM version at start of
|
||||
* LoadFirmware() */
|
||||
uint32_t fw_version_lowest; /* Firmware lowest version found */
|
||||
|
||||
@@ -95,7 +95,8 @@ typedef struct {
|
||||
/* Fields that GetVdatString() can get */
|
||||
typedef enum VdatStringField {
|
||||
VDAT_STRING_TIMERS = 0, /* Timer values */
|
||||
VDAT_STRING_LOAD_FIRMWARE_DEBUG /* LoadFirmware() debug information */
|
||||
VDAT_STRING_LOAD_FIRMWARE_DEBUG, /* LoadFirmware() debug information */
|
||||
VDAT_STRING_LOAD_KERNEL_DEBUG /* LoadKernel() debug information */
|
||||
} VdatStringField;
|
||||
|
||||
|
||||
@@ -618,10 +619,123 @@ int VbGetCrosDebug(void) {
|
||||
}
|
||||
|
||||
|
||||
char* GetVdatLoadFirmwareDebug(char* dest, int size,
|
||||
const VbSharedDataHeader* sh) {
|
||||
snprintf(dest, size,
|
||||
"Check A result=%d\n"
|
||||
"Check B result=%d\n"
|
||||
"Firmware index booted=0x%02x\n"
|
||||
"TPM combined version at start=0x%08x\n"
|
||||
"Lowest combined version from firmware=0x%08x\n",
|
||||
sh->check_fw_a_result,
|
||||
sh->check_fw_b_result,
|
||||
sh->firmware_index,
|
||||
sh->fw_version_tpm_start,
|
||||
sh->fw_version_lowest);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
#define TRUNCATED "\n(truncated)\n"
|
||||
|
||||
char* GetVdatLoadKernelDebug(char* dest, int size,
|
||||
const VbSharedDataHeader* sh) {
|
||||
int used = 0;
|
||||
int first_call_tracked = 0;
|
||||
int call;
|
||||
|
||||
/* Make sure we have space for truncation warning */
|
||||
if (size < strlen(TRUNCATED) + 1)
|
||||
return NULL;
|
||||
size -= strlen(TRUNCATED) + 1;
|
||||
|
||||
used += snprintf(
|
||||
dest + used, size - used,
|
||||
"Calls to LoadKernel()=%d\n",
|
||||
sh->lk_call_count);
|
||||
if (used > size)
|
||||
goto LoadKernelDebugExit;
|
||||
|
||||
/* Report on the last calls */
|
||||
if (sh->lk_call_count > VBSD_MAX_KERNEL_CALLS)
|
||||
first_call_tracked = sh->lk_call_count - VBSD_MAX_KERNEL_CALLS;
|
||||
for (call = first_call_tracked; call < sh->lk_call_count; call++) {
|
||||
const VbSharedDataKernelCall* shc =
|
||||
sh->lk_calls + (call & (VBSD_MAX_KERNEL_CALLS - 1));
|
||||
int first_part_tracked = 0;
|
||||
int part;
|
||||
|
||||
used += snprintf(
|
||||
dest + used, size - used,
|
||||
"Call %d:\n"
|
||||
" Boot flags=0x%02x\n"
|
||||
" Boot mode=%d\n"
|
||||
" Test error=%d\n"
|
||||
" Return code=%d\n"
|
||||
" Debug flags=0x%02x\n"
|
||||
" Drive sectors=%" PRIu64 "\n"
|
||||
" Sector size=%d\n"
|
||||
" Check result=%d\n"
|
||||
" Kernel partitions found=%d\n",
|
||||
call + 1,
|
||||
shc->boot_flags,
|
||||
shc->boot_mode,
|
||||
shc->test_error_num,
|
||||
shc->return_code,
|
||||
shc->flags,
|
||||
shc->sector_count,
|
||||
shc->sector_size,
|
||||
shc->check_result,
|
||||
shc->kernel_parts_found);
|
||||
if (used > size)
|
||||
goto LoadKernelDebugExit;
|
||||
|
||||
/* If we found too many partitions, only prints ones where the
|
||||
* structure has info. */
|
||||
if (shc->kernel_parts_found > VBSD_MAX_KERNEL_PARTS)
|
||||
first_part_tracked = shc->kernel_parts_found - VBSD_MAX_KERNEL_PARTS;
|
||||
|
||||
/* Report on the partitions checked */
|
||||
for (part = first_part_tracked; part < shc->kernel_parts_found; part++) {
|
||||
const VbSharedDataKernelPart* shp =
|
||||
shc->parts + (part & (VBSD_MAX_KERNEL_PARTS - 1));
|
||||
|
||||
used += snprintf(
|
||||
dest + used, size - used,
|
||||
" Kernel %d:\n"
|
||||
" GPT index=%d\n"
|
||||
" Start sector=%" PRIu64 "\n"
|
||||
" Sector count=%" PRIu64 "\n"
|
||||
" Combined version=0x%08x\n"
|
||||
" Check result=%d\n"
|
||||
" Debug flags=0x%02x\n",
|
||||
part + 1,
|
||||
shp->gpt_index,
|
||||
shp->sector_start,
|
||||
shp->sector_count,
|
||||
shp->combined_version,
|
||||
shp->check_result,
|
||||
shp->flags);
|
||||
if (used > size)
|
||||
goto LoadKernelDebugExit;
|
||||
}
|
||||
}
|
||||
|
||||
LoadKernelDebugExit:
|
||||
|
||||
/* Warn if data was truncated; we left space for this above. */
|
||||
if (used > size)
|
||||
strcat(dest, TRUNCATED);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
char* GetVdatString(char* dest, int size, VdatStringField field)
|
||||
{
|
||||
VbSharedDataHeader* sh;
|
||||
AcpiBuffer* ab = VbGetBuffer(ACPI_VDAT_PATH);
|
||||
char* value = dest;
|
||||
if (!ab)
|
||||
return NULL;
|
||||
|
||||
@@ -642,13 +756,11 @@ char* GetVdatString(char* dest, int size, VdatStringField field)
|
||||
break;
|
||||
|
||||
case VDAT_STRING_LOAD_FIRMWARE_DEBUG:
|
||||
snprintf(dest, size,
|
||||
"check=%d,%d index=0x%02x tpmver=0x%x lowestver=0x%x",
|
||||
sh->check_fw_a_result,
|
||||
sh->check_fw_b_result,
|
||||
sh->firmware_index,
|
||||
sh->fw_version_tpm_start,
|
||||
sh->fw_version_lowest);
|
||||
value = GetVdatLoadFirmwareDebug(dest, size, sh);
|
||||
break;
|
||||
|
||||
case VDAT_STRING_LOAD_KERNEL_DEBUG:
|
||||
value = GetVdatLoadKernelDebug(dest, size, sh);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -657,7 +769,7 @@ char* GetVdatString(char* dest, int size, VdatStringField field)
|
||||
}
|
||||
|
||||
Free(ab);
|
||||
return dest;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -819,6 +931,8 @@ const char* VbGetSystemPropertyString(const char* name, char* dest, int size) {
|
||||
return GetVdatString(dest, size, VDAT_STRING_TIMERS);
|
||||
} else if (!strcasecmp(name, "vdat_lfdebug")) {
|
||||
return GetVdatString(dest, size, VDAT_STRING_LOAD_FIRMWARE_DEBUG);
|
||||
} else if (!strcasecmp(name, "vdat_lkdebug")) {
|
||||
return GetVdatString(dest, size, VDAT_STRING_LOAD_KERNEL_DEBUG);
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
#include "crossystem.h"
|
||||
|
||||
/* Max length of a string parameter */
|
||||
#define MAX_STRING 8192
|
||||
|
||||
/* Flags for Param */
|
||||
#define IS_STRING 0x01 /* String (not present = integer) */
|
||||
#define CAN_WRITE 0x02 /* Writable (not present = read-only */
|
||||
@@ -52,7 +55,6 @@ const Param sys_param_list[] = {
|
||||
{"ecfw_act", IS_STRING, "Active EC firmware"},
|
||||
{"kernkey_vfy", IS_STRING, "Type of verification done on kernel key block"},
|
||||
{"vdat_timers", IS_STRING, "Timer values from VbSharedData"},
|
||||
{"vdat_lfdebug", IS_STRING, "LoadFirmware() debug data VbSharedData"},
|
||||
/* Writable integers */
|
||||
{"nvram_cleared", CAN_WRITE, "Have NV settings been lost? Write 0 to clear"},
|
||||
{"kern_nv", CAN_WRITE, "Non-volatile field for kernel use", "0x%08x"},
|
||||
@@ -61,7 +63,11 @@ const Param sys_param_list[] = {
|
||||
{"fwb_tries", CAN_WRITE, "Try firmware B count (writable)"},
|
||||
{"vbtest_errfunc", CAN_WRITE, "Verified boot test error function (writable)"},
|
||||
{"vbtest_errno", CAN_WRITE, "Verified boot test error number (writable)"},
|
||||
|
||||
/* Fields not shown in a print-all list */
|
||||
{"vdat_lfdebug", IS_STRING|NO_PRINT_ALL,
|
||||
"LoadFirmware() debug data (not in print-all)"},
|
||||
{"vdat_lkdebug", IS_STRING|NO_PRINT_ALL,
|
||||
"LoadKernel() debug data (not in print-all)"},
|
||||
/* Terminate with null name */
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
@@ -125,7 +131,7 @@ int SetParam(const Param* p, const char* value) {
|
||||
* Returns 0 if success (match), non-zero if error (mismatch). */
|
||||
int CheckParam(const Param* p, char* expect) {
|
||||
if (p->flags & IS_STRING) {
|
||||
char buf[256];
|
||||
char buf[MAX_STRING];
|
||||
const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
|
||||
if (!v || 0 != strcmp(v, expect))
|
||||
return 1;
|
||||
@@ -147,7 +153,7 @@ int CheckParam(const Param* p, char* expect) {
|
||||
* Returns 0 if success, non-zero if error. */
|
||||
int PrintParam(const Param* p) {
|
||||
if (p->flags & IS_STRING) {
|
||||
char buf[256];
|
||||
char buf[MAX_STRING];
|
||||
const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
|
||||
if (!v)
|
||||
return 1;
|
||||
@@ -168,7 +174,7 @@ int PrintParam(const Param* p) {
|
||||
int PrintAllParams(void) {
|
||||
const Param* p;
|
||||
int retval = 0;
|
||||
char buf[256];
|
||||
char buf[MAX_STRING];
|
||||
const char* value;
|
||||
|
||||
for (p = sys_param_list; p->name; p++) {
|
||||
|
||||
Reference in New Issue
Block a user