IdByte.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
00003  *
00004  * Copyright (C) 2005 Dell Inc.
00005  *  by Michael Brown <Michael_E_Brown@dell.com>
00006  * Licensed under the Open Software License version 2.1
00007  *
00008  * Alternatively, you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  */
00018 
00019 #include <cstring>
00020 
00021 #define LIBSMBIOS_SOURCE
00022 #include "smbios/ISmbios.h"
00023 #include "smbios/IToken.h"
00024 
00025 #include "smbios/SystemInfo.h"
00026 #include "smbios/IMemory.h"
00027 #include "smbios/SmbiosDefs.h"
00028 #include "ExceptionImpl.h"
00029 
00030 #include "SystemDetect.h"
00031 #include "DellMagic.h"
00032 
00033 // should always be included last.
00034 #include "smbios/message.h"
00035 
00036 using namespace smbios;
00037 using namespace cmos;
00038 using namespace std;
00039 
00040 extern smbios::Exception<smbios::IException> SysInfoException;
00041 
00042 //
00043 //
00044 // ID Byte functions
00045 //
00046 //
00047 static u16 getIdByteFromMem ()
00048 {
00049     u16 tempWord = 0;
00050     u16 idWord = 0;
00051     memory::IMemory *mem = 0;
00052 
00053     struct two_byte_structure tbs;
00054     struct two_byte_structure *ptbs = &tbs;
00055     struct one_byte_structure *pobs =
00056                     reinterpret_cast<one_byte_structure*>(&(tbs.bios_version));
00057 
00058     mem = memory::MemoryFactory::getFactory()->getSingleton();
00059 
00060     if( 0 == mem )
00061         throw InternalErrorImpl();
00062 
00063     // Step 1: Check that "Dell System" is present at the proper offset
00064     u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
00065     mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC, DELL_SYSTEM_STRING_LEN - 1 );
00066     if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) != 0 )
00067         goto out;
00068 
00069     // Step 2: fill the id structs
00070     mem->fillBuffer( reinterpret_cast<u8 *>(ptbs), TWO_BYTE_STRUCT_LOC, sizeof(two_byte_structure) );
00071 
00072     // Step 3: check the checksum of one-byte struct
00073     //    update: checksum is not reliable, so don't use it...
00074 
00075     // Step 4: Check one byte ID
00076     tempWord = pobs->system_id;
00077 
00078     // Step 5: if 0xFE, then it is a double byte (word) ID.
00079     // *  -- byte at 0xFE845 is 0xFE
00080     if (0xFE == tempWord)
00081 {
00082         // Step 6: check two byte struct checksum
00083         // *  -- three bytes at 0xFE845 sum to 0x00 but are not all 0x00.
00084         //*  -- extension checksum is 0
00085 
00086         // Step 7: get ID.
00087         tempWord = ptbs->two_byte_id;
00088     }
00089 
00090     idWord = tempWord;
00091 
00092 out:
00093     return idWord;
00094 }
00095 
00096 static u16 getIdByteFromMem_Diamond ()
00097 {
00098     u16 idWord = 0;
00099     memory::IMemory *mem = 0;
00100     u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
00101 
00102     mem = memory::MemoryFactory::getFactory()->getSingleton();
00103 
00104     if( 0 == mem )
00105         throw InternalErrorImpl();
00106 
00107     // Step 1: Check that "Dell System" is present at the proper offset
00108     mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_1, DELL_SYSTEM_STRING_LEN - 1 );
00109     if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00110         if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_1 ) )
00111             idWord = SYSTEM_ID_DIAMOND;
00112 
00113     mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_2, DELL_SYSTEM_STRING_LEN - 1 );
00114     if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00115         if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_2 ) )
00116             idWord = SYSTEM_ID_DIAMOND;
00117 
00118     return idWord;
00119 }
00120 
00121 static u16 getIdByteFromOEMItem ()
00122 {
00123     //functionEnter( "%s", "" );
00124     u16 idWord = 0;
00125     smbios::ISmbiosTable *table = 0;
00126     smbios::ISmbiosTable::iterator item;
00127     if (!couldBeBayonet())
00128         goto out;
00129 
00130     table = smbios::SmbiosFactory::getFactory()->getSingleton();
00131 
00132     if (0 == table)
00133         throw InternalErrorImpl();
00134 
00135     // search through 0x0B (OEM_Strings) items
00136     for( item = (*table)[OEM_Strings] ; item != table->end(); ++item)
00137     {
00138         const char *str = item->getStringByStringNumber (2);
00139         //isBayonet = true;
00140         //  Id byte is in second string in table 0x0B
00141         //  the format is "n[NN]", where NN is the idbyte;
00142         //  note the &str[2] below to skip the 'n['
00143         if( 0 != str )
00144             // quiet vc.net warning using cast
00145             idWord = static_cast<u16>(strtol( &str[2], NULL, 16 ));
00146     }
00147 
00148 out:
00149     //functionLeave( "\t\tretval = %i\n", (int)idWord );
00150     return idWord;
00151 }
00152 
00153 static u16 getIdByteFromRevItem ()
00154 {
00155     //functionEnter( "%s", "" );
00156     u16 idWord = 0;
00157     smbios::ISmbiosTable *table = 0;
00158     smbios::ISmbiosTable::iterator item;
00159 
00160     table = smbios::SmbiosFactory::getFactory()->getSingleton();
00161 
00162     if (0 == table)
00163         throw InternalErrorImpl();
00164 
00165     // search through 0x0B (Revisions_and_IDs_Structure)
00166     for( item = (*table)[Dell_Revisions_and_IDs]; item != table->end(); ++item)
00167     {
00168         //If byte field is 0xFE, we need to look in the extension field
00169         idWord = getU8_FromItem(*item, 0x06);
00170         if( 0xFE == idWord )
00171         {
00172             idWord = getU16_FromItem(*item, 0x08);
00173         }
00174     }
00175     //functionLeave( "\t\tretval = %i\n", (int)idWord );
00176     return idWord;
00177 }
00178 
00179 //The code for detecting ID byte in case of Diamond is left out.
00180 //  need to write a function for it.
00181 struct DellIdByteFunctions
00182 {
00183     u16 (*f_ptr)();
00184 }
00185 DellIdByteFunctions[] = {
00186                             {&getIdByteFromMem,},       // normal system -- try this last always.
00187 
00188                             {&getIdByteFromOEMItem,},   // bayonet
00189                             {&getIdByteFromMem_Diamond,}, // diamond
00190 
00191                             // do this last because this may contain an OEM id
00192                             // do this as a last resort because it is
00193                             // unreliable.
00194                             {&getIdByteFromRevItem,},   // Dell Smbios Revisions and ID's struct
00195                         };
00196 
00197 
00198 
00199 
00200 int SMBIOSGetDellSystemId()
00201 {
00202     //functionEnter( "%s", "" );
00203     int systemId = 0;
00204     int numEntries =
00205         sizeof (DellIdByteFunctions) / sizeof (DellIdByteFunctions[0]);
00206 
00207     for (int i = 0; i < numEntries; ++i)
00208     {
00209         // eat exceptions from lowlevel functions and keep going.
00210         try
00211         {
00212             // first function to return non-zero id wins.
00213             systemId = DellIdByteFunctions[i].f_ptr ();
00214         }
00215         catch(const smbios::IException &e)
00216         {
00217             SysInfoException.setMessageString(e.what());
00218         }
00219         catch(...)
00220         {
00221             SysInfoException.setMessageString( _("Unknown internal error occurred") );
00222         }
00223         if (0 != systemId)
00224         {
00225             break;
00226         }
00227     }
00228 
00229     return systemId;
00230 }
00231 

Generated on Thu Jan 24 14:59:34 2008 for SMBIOS Library by  doxygen 1.5.4