Changeset a1d88954b2913bb6b992077accad6b23c6767abe
- Timestamp:
- 10/30/09 21:00:09 (2 years ago)
- Author:
- Erwan Velu <erwan.velu@…>
- Children:
- 512de9792b2fd4a9af1033ea6ef6c8033e4dfb9f, dee3fa2de1912a9ad88982f6e412656375d8ca3e, aa1724e7a975430c7b8b53359e94c225622f4957
- Parents:
- cf14910be4b9941247f5aebb8d901455532553dc
- git-committer:
- Erwan Velu <erwan.velu@free.fr> / 2009-10-30T22:00:09Z+0100
- Message:
-
dmi: Adding smbios detection
Impact: Avoid misdetection of dmi version
On some hosts, the legacy DMI version is reported as 0.0.
We can use SMBIOS to get the real version.
Solves HDT's ticket #8
- Location:
- com32
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r0b19ab
|
ra1d889
|
|
| 14 | 14 | #define DMI_H |
| 15 | 15 | #include <inttypes.h> |
| | 16 | #define DMI_BUFFER_SIZE 16 |
| 16 | 17 | #define MAX_DMI_MEMORY_ITEMS 32 |
| 17 | 18 | #define MAX_DMI_CACHE_ITEMS 32 |
| … |
… |
|
| 87 | 88 | void dmi_bios_runtime_size(uint32_t code, s_dmi * dmi); |
| 88 | 89 | const char *dmi_string(struct dmi_header *dm, uint8_t s); |
| 89 | | int dmi_checksum(uint8_t * buf); |
| | 90 | int dmi_checksum(uint8_t * buf, int len); |
| 90 | 91 | void parse_dmitable(s_dmi * dmi); |
| 91 | 92 | void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi); |
-
|
r0b19ab
|
ra1d889
|
|
| 407 | 407 | if (cpu_flags_strings[i] != NULL && edx & (1 << i)) |
| 408 | 408 | ((bool *) (&dmi->processor.cpu_flags))[i] = true; |
| 409 | | //printf("%s\t%s\n", prefix, flags[i]); |
| 410 | 409 | } |
| 411 | 410 | } |
| … |
… |
|
| 446 | 445 | } |
| 447 | 446 | |
| 448 | | int dmi_checksum(uint8_t * buf) |
| | 447 | int dmi_checksum(uint8_t * buf, int len) |
| 449 | 448 | { |
| 450 | 449 | uint8_t sum = 0; |
| 451 | 450 | int a; |
| 452 | 451 | |
| 453 | | for (a = 0; a < 15; a++) |
| | 452 | for (a = 0; a < len; a++) |
| 454 | 453 | sum += buf[a]; |
| 455 | 454 | return (sum == 0); |
| 456 | 455 | } |
| 457 | 456 | |
| | 457 | static int smbios_decode(s_dmi *dmi, uint8_t *buf) |
| | 458 | { |
| | 459 | |
| | 460 | dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07]; |
| | 461 | /* Some BIOS report weird SMBIOS version, fix that up */ |
| | 462 | switch (dmi->dmitable.ver) { |
| | 463 | case 0x021F: |
| | 464 | dmi->dmitable.ver = 0x0203; |
| | 465 | break; |
| | 466 | case 0x0233: |
| | 467 | dmi->dmitable.ver = 0x0206; |
| | 468 | break; |
| | 469 | } |
| | 470 | dmi->dmitable.major_version=dmi->dmitable.ver >> 8; |
| | 471 | dmi->dmitable.minor_version=dmi->dmitable.ver & 0xFF; |
| | 472 | |
| | 473 | return DMI_TABLE_PRESENT; |
| | 474 | } |
| | 475 | |
| | 476 | |
| | 477 | static int legacy_decode(s_dmi *dmi, uint8_t *buf) |
| | 478 | { |
| | 479 | dmi->dmitable.num = buf[13] << 8 | buf[12]; |
| | 480 | dmi->dmitable.len = buf[7] << 8 | buf[6]; |
| | 481 | dmi->dmitable.base = |
| | 482 | buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8]; |
| | 483 | |
| | 484 | if (dmi->dmitable.ver>0) return DMI_TABLE_PRESENT; |
| | 485 | |
| | 486 | dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07]; |
| | 487 | |
| | 488 | /* |
| | 489 | * DMI version 0.0 means that the real version is taken from |
| | 490 | * the SMBIOS version, which we don't know at this point. |
| | 491 | */ |
| | 492 | if (buf[14] != 0) { |
| | 493 | dmi->dmitable.major_version = buf[14] >> 4; |
| | 494 | dmi->dmitable.minor_version = buf[14] & 0x0F; |
| | 495 | } else { |
| | 496 | dmi->dmitable.major_version = 0; |
| | 497 | dmi->dmitable.minor_version = 0; |
| | 498 | } |
| | 499 | return DMI_TABLE_PRESENT; |
| | 500 | } |
| | 501 | |
| | 502 | |
| 458 | 503 | int dmi_iterate(s_dmi * dmi) |
| 459 | 504 | { |
| 460 | | uint8_t buf[16]; |
| | 505 | uint8_t buf[DMI_BUFFER_SIZE]; |
| 461 | 506 | char *p, *q; |
| 462 | 507 | |
| … |
… |
|
| 484 | 529 | for (q = p; q < p + 0x10000; q += 16) { |
| 485 | 530 | memcpy(buf, q, 15); |
| 486 | | if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf)) { |
| 487 | | dmi->dmitable.num = buf[13] << 8 | buf[12]; |
| 488 | | dmi->dmitable.len = buf[7] << 8 | buf[6]; |
| 489 | | dmi->dmitable.base = |
| 490 | | buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8]; |
| 491 | | dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07]; |
| 492 | | |
| 493 | | /* |
| 494 | | * DMI version 0.0 means that the real version is taken from |
| 495 | | * the SMBIOS version, which we don't know at this point. |
| 496 | | */ |
| 497 | | if (buf[14] != 0) { |
| 498 | | dmi->dmitable.major_version = buf[14] >> 4; |
| 499 | | dmi->dmitable.minor_version = buf[14] & 0x0F; |
| 500 | | } else { |
| 501 | | dmi->dmitable.major_version = 0; |
| 502 | | dmi->dmitable.minor_version = 0; |
| 503 | | |
| 504 | | } |
| 505 | | /* printf("DMI present (version %d.%d)\n", dmitable.major_version,dmitable.minor_version); |
| 506 | | printf("%d structures occupying %d bytes.\n",dmitable.num, dmitable.len); |
| 507 | | printf("DMI table at 0x%08X.\n",dmitable.base);*/ |
| 508 | | return DMI_TABLE_PRESENT; |
| | 531 | if (memcmp(buf, "_SM_", 4) == 0) { |
| | 532 | smbios_decode(dmi,buf); |
| | 533 | } |
| | 534 | if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf,sizeof(buf))) { |
| | 535 | return legacy_decode(dmi,buf); |
| 509 | 536 | } |
| 510 | 537 | } |
| … |
… |
|
| 525 | 552 | switch (h->type) { |
| 526 | 553 | case 0: /* 3.3.1 BIOS Information */ |
| 527 | | // printf("BIOS Information\n"); |
| 528 | 554 | if (h->length < 0x12) |
| 529 | 555 | break; |
| … |
… |
|
| 553 | 579 | break; |
| 554 | 580 | case 1: /* 3.3.2 System Information */ |
| 555 | | // printf("System Information\n"); |
| 556 | 581 | if (h->length < 0x08) |
| 557 | 582 | break; |
| … |
… |
|
| 572 | 597 | |
| 573 | 598 | case 2: /* 3.3.3 Base Board Information */ |
| 574 | | // printf("Base Board Information\n"); |
| 575 | 599 | if (h->length < 0x08) |
| 576 | 600 | break; |
| … |
… |
|
| 590 | 614 | break; |
| 591 | 615 | case 3: /* 3.3.4 Chassis Information */ |
| 592 | | // printf("Chassis Information\n"); |
| 593 | 616 | if(h->length<0x09) break; |
| 594 | 617 | dmi->chassis.filled=true; |
| … |
… |
|
| 612 | 635 | |
| 613 | 636 | case 4: /* 3.3.5 Processor Information */ |
| 614 | | // printf("Processor Information\n"); |
| 615 | 637 | if(h->length<0x1A) break; |
| 616 | 638 | dmi->processor.filled=true; |
| … |
… |
|
| 844 | 866 | break; |
| 845 | 867 | } |
| 846 | | // printf("Handle 0x%04X, DMI type %d, %d bytes\n", h.handle, h.type, h.length); |
| 847 | 868 | |
| 848 | 869 | /* loo for the next handle */ |
-
|
r6f9540
|
ra1d889
|
|
| 506 | 506 | return; |
| 507 | 507 | } |
| 508 | | printf("DMI Table version %d.%d found\n", |
| | 508 | printf("DMI Table version %u.%u found\n", |
| 509 | 509 | hardware->dmi.dmitable.major_version, |
| 510 | 510 | hardware->dmi.dmitable.minor_version); |
-
|
r9aaf51
|
ra1d889
|
|
| 180 | 180 | return -1; |
| 181 | 181 | } else { |
| 182 | | printf("DMI %d.%d present.\n", dmi.dmitable.major_version, |
| | 182 | printf("DMI %u.%u present.\n", dmi.dmitable.major_version, |
| 183 | 183 | dmi.dmitable.minor_version); |
| 184 | 184 | printf("%d structures occupying %d bytes.\n", dmi.dmitable.num, |