Changeset a1d88954b2913bb6b992077accad6b23c6767abe

Show
Ignore:
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:
4 modified

Legend:

Unmodified
Added
Removed
  • com32/gplinclude/dmi/dmi.h

    r0b19ab ra1d889  
    1414#define DMI_H 
    1515#include <inttypes.h> 
     16#define DMI_BUFFER_SIZE 16  
    1617#define MAX_DMI_MEMORY_ITEMS 32 
    1718#define MAX_DMI_CACHE_ITEMS 32 
     
    8788void dmi_bios_runtime_size(uint32_t code, s_dmi * dmi); 
    8889const char *dmi_string(struct dmi_header *dm, uint8_t s); 
    89 int dmi_checksum(uint8_t * buf); 
     90int dmi_checksum(uint8_t * buf, int len); 
    9091void parse_dmitable(s_dmi * dmi); 
    9192void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi); 
  • com32/gpllib/dmi/dmi.c

    r0b19ab ra1d889  
    407407            if (cpu_flags_strings[i] != NULL && edx & (1 << i)) 
    408408                ((bool *) (&dmi->processor.cpu_flags))[i] = true; 
    409         //printf("%s\t%s\n", prefix, flags[i]); 
    410409    } 
    411410} 
     
    446445} 
    447446 
    448 int dmi_checksum(uint8_t * buf) 
     447int dmi_checksum(uint8_t * buf, int len) 
    449448{ 
    450449    uint8_t sum = 0; 
    451450    int a; 
    452451 
    453     for (a = 0; a < 15; a++) 
     452    for (a = 0; a < len; a++) 
    454453        sum += buf[a]; 
    455454    return (sum == 0); 
    456455} 
    457456 
     457static 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 
     477static 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 
    458503int dmi_iterate(s_dmi * dmi) 
    459504{ 
    460     uint8_t buf[16]; 
     505    uint8_t buf[DMI_BUFFER_SIZE]; 
    461506    char *p, *q; 
    462507 
     
    484529    for (q = p; q < p + 0x10000; q += 16) { 
    485530        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); 
    509536        } 
    510537    } 
     
    525552    switch (h->type) { 
    526553    case 0:                     /* 3.3.1 BIOS Information */ 
    527 //                        printf("BIOS Information\n"); 
    528554        if (h->length < 0x12) 
    529555            break; 
     
    553579        break; 
    554580    case 1:                     /* 3.3.2 System Information */ 
    555 //                        printf("System Information\n"); 
    556581        if (h->length < 0x08) 
    557582            break; 
     
    572597 
    573598    case 2:                     /* 3.3.3 Base Board Information */ 
    574 //                        printf("Base Board Information\n"); 
    575599        if (h->length < 0x08) 
    576600            break; 
     
    590614        break; 
    591615    case 3:                     /* 3.3.4 Chassis Information */ 
    592 //                        printf("Chassis Information\n"); 
    593616                        if(h->length<0x09) break; 
    594617                        dmi->chassis.filled=true; 
     
    612635 
    613636                        case 4: /* 3.3.5 Processor Information */ 
    614 //                        printf("Processor Information\n"); 
    615637                        if(h->length<0x1A) break; 
    616638                        dmi->processor.filled=true; 
     
    844866            break; 
    845867        } 
    846 //        printf("Handle 0x%04X, DMI type %d, %d bytes\n", h.handle, h.type, h.length); 
    847868 
    848869        /* loo for the next handle */ 
  • com32/hdt/hdt-cli-dmi.c

    r6f9540 ra1d889  
    506506    return; 
    507507  } 
    508   printf("DMI Table version %d.%d found\n", 
     508  printf("DMI Table version %u.%u found\n", 
    509509         hardware->dmi.dmitable.major_version, 
    510510         hardware->dmi.dmitable.minor_version); 
  • com32/modules/dmitest.c

    r9aaf51 ra1d889  
    180180        return -1; 
    181181    } else { 
    182         printf("DMI %d.%d present.\n", dmi.dmitable.major_version, 
     182        printf("DMI %u.%u present.\n", dmi.dmitable.major_version, 
    183183               dmi.dmitable.minor_version); 
    184184        printf("%d structures occupying %d bytes.\n", dmi.dmitable.num,