|
2 | 2 | * DMI Decode
|
3 | 3 | *
|
4 | 4 | * Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
|
5 | | - * Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de> |
| 5 | + * Copyright (C) 2002-2017 Jean Delvare <jdelvare@suse.de> |
6 | 6 | *
|
7 | 7 | * This program is free software; you can redistribute it and/or modify
|
8 | 8 | * it under the terms of the GNU General Public License as published by
|
|
50 | 50 | * - DMTF DSP0239 version 1.1.0
|
51 | 51 | * "Management Component Transport Protocol (MCTP) IDs and Codes"
|
52 | 52 | * http://www.dmtf.org/standards/pmci
|
| 53 | + * - "TPM Main, Part 2 TPM Structures" |
| 54 | + * Specification version 1.2, level 2, revision 116 |
| 55 | + * https://trustedcomputinggroup.org/tpm-main-specification/ |
| 56 | + * - "PC Client Platform TPM Profile (PTP) Specification" |
| 57 | + * Family "2.0", Level 00, Revision 00.43, January 26, 2015 |
| 58 | + * https://trustedcomputinggroup.org/pc-client-platform-tpm-profile-ptp-specification/ |
53 | 59 | */
|
54 | 60 |
|
55 | 61 | #include <stdio.h>
|
@@ -170,12 +176,13 @@ static const char *dmi_smbios_structure_type(u8 code)
|
170 | 176 | "Power Supply",
|
171 | 177 | "Additional Information",
|
172 | 178 | "Onboard Device",
|
173 | | - "Management Controller Host Interface", /* 42 */ |
| 179 | + "Management Controller Host Interface", |
| 180 | + "TPM Device", /* 43 */ |
174 | 181 | };
|
175 | 182 |
|
176 | 183 | if (code >= 128)
|
177 | 184 | return "OEM-specific";
|
178 | | - if (code <= 42) |
| 185 | + if (code <= 43) |
179 | 186 | return type[code];
|
180 | 187 | return out_of_spec;
|
181 | 188 | }
|
@@ -3309,6 +3316,57 @@ static const char *dmi_management_controller_host_type(u8 code)
|
3309 | 3316 | return out_of_spec;
|
3310 | 3317 | }
|
3311 | 3318 |
|
| 3319 | +/* |
| 3320 | + * 7.44 TPM Device (Type 43) |
| 3321 | + */ |
| 3322 | + |
| 3323 | +static void dmi_tpm_vendor_id(const u8 *p) |
| 3324 | +{ |
| 3325 | + char vendor_id[5]; |
| 3326 | + int i; |
| 3327 | + |
| 3328 | + /* ASCII filtering */ |
| 3329 | + for (i = 0; i < 4 && p[i] != 0; i++) |
| 3330 | + { |
| 3331 | + if (p[i] < 32 || p[i] >= 127) |
| 3332 | + vendor_id[i] = '.'; |
| 3333 | + else |
| 3334 | + vendor_id[i] = p[i]; |
| 3335 | + } |
| 3336 | + |
| 3337 | + /* Terminate the string */ |
| 3338 | + vendor_id[i] = '0円'; |
| 3339 | + |
| 3340 | + printf(" %s", vendor_id); |
| 3341 | +} |
| 3342 | + |
| 3343 | +static void dmi_tpm_characteristics(u64 code, const char *prefix) |
| 3344 | +{ |
| 3345 | + /* 7.1.1 */ |
| 3346 | + static const char *characteristics[] = { |
| 3347 | + "TPM Device characteristics not supported", /* 2 */ |
| 3348 | + "Family configurable via firmware update", |
| 3349 | + "Family configurable via platform software support", |
| 3350 | + "Family configurable via OEM proprietary mechanism" /* 5 */ |
| 3351 | + }; |
| 3352 | + int i; |
| 3353 | + |
| 3354 | + /* |
| 3355 | + * This isn't very clear what this bit is supposed to mean |
| 3356 | + */ |
| 3357 | + if (code.l & (1 << 2)) |
| 3358 | + { |
| 3359 | + printf("%s%s\n", |
| 3360 | + prefix, characteristics[0]); |
| 3361 | + return; |
| 3362 | + } |
| 3363 | + |
| 3364 | + for (i = 3; i <= 5; i++) |
| 3365 | + if (code.l & (1 << i)) |
| 3366 | + printf("%s%s\n", |
| 3367 | + prefix, characteristics[i - 2]); |
| 3368 | +} |
| 3369 | + |
3312 | 3370 | /*
|
3313 | 3371 | * Main
|
3314 | 3372 | */
|
@@ -4425,6 +4483,43 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
|
4425 | 4483 | }
|
4426 | 4484 | break;
|
4427 | 4485 |
|
| 4486 | + case 43: /* 7.44 TPM Device */ |
| 4487 | + printf("TPM Device\n"); |
| 4488 | + if (h->length < 0x1B) break; |
| 4489 | + printf("\tVendor ID:"); |
| 4490 | + dmi_tpm_vendor_id(data + 0x04); |
| 4491 | + printf("\n"); |
| 4492 | + printf("\tSpecification Version: %d.%d", data[0x08], data[0x09]); |
| 4493 | + switch (data[0x08]) |
| 4494 | + { |
| 4495 | + case 0x01: |
| 4496 | + /* |
| 4497 | + * We skip the first 2 bytes, which are |
| 4498 | + * redundant with the above, and uncoded |
| 4499 | + * in a silly way. |
| 4500 | + */ |
| 4501 | + printf("\tFirmware Revision: %u.%u\n", |
| 4502 | + data[0x0C], data[0x0D]); |
| 4503 | + break; |
| 4504 | + case 0x02: |
| 4505 | + printf("\tFirmware Revision: %u.%u\n", |
| 4506 | + DWORD(data + 0x0A) >> 16, |
| 4507 | + DWORD(data + 0x0A) && 0xFF); |
| 4508 | + /* |
| 4509 | + * We skip the next 4 bytes, as their |
| 4510 | + * format is not standardized and their |
| 4511 | + * usefulness seems limited anyway. |
| 4512 | + */ |
| 4513 | + break; |
| 4514 | + } |
| 4515 | + printf("\tDescription: %s", dmi_string(h, data[0x12])); |
| 4516 | + printf("\tCharacteristics:\n"); |
| 4517 | + dmi_tpm_characteristics(QWORD(data + 0x13), "\t\t"); |
| 4518 | + if (h->length < 0x1F) break; |
| 4519 | + printf("\tOEM-specific Information: 0x%08X\n", |
| 4520 | + DWORD(data + 0x1B)); |
| 4521 | + break; |
| 4522 | + |
4428 | 4523 | case 126: /* 7.44 Inactive */
|
4429 | 4524 | printf("Inactive\n");
|
4430 | 4525 | break;
|
|
0 commit comments