Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

TokenTable.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 // compat header should always be first header if including system headers
00020 #define LIBSMBIOS_SOURCE
00021 #include "smbios/compat.h"
00022 
00023 #include <sstream>
00024 
00025 #include "TokenImpl.h"
00026 
00027 using namespace std;
00028 
00029 // for functions that are not implemented at this level in the
00030 // inheritance heirarchy at all.
00031 #define NOT_IMPLEMENTED do { throw NotImplementedImpl(); } while(0)
00032 
00033 // Token numbering:
00034 //   -- all tokens are 16-bit, this means we can store token number in 32-bit
00035 //      value and use topmost bits as a 'type' code.
00036 
00037 namespace smbios
00038 {
00039     ITokenTable::ITokenTable()
00040     {}
00041 
00042     //
00043     //
00044     TokenTable::TokenTable( const smbios::ISmbiosTable & table)
00045     {
00046         addD4Structures(table);
00047         addD5Structures(table);
00048         addD6Structures(table);
00049         addDAStructures(table);
00050     }
00051 
00052     void TokenTable::addD4Structures(const smbios::ISmbiosTable & table)
00053     {
00054         // usually have around 4 checksums or so. estimate here to speed up stuff later.
00055         checksumList.reserve(4);
00056 
00057         // Pull out all of the 0xD4 entries and create Tokens out of them
00058         // iterate over each 0xD4 token (Dell_Indexed_Io)
00059         for(
00060             smbios::ISmbiosTable::const_iterator item = table[DellIndexedIoTokenType];
00061             item != table.end();
00062             ++item)
00063         {
00064             // get a copy of the buffer
00065             size_t size = 0;
00066             const u8 *ptr =  item->getBufferCopy(size) ; // MUST DELETE[]!
00067             try
00068             {
00069                 addChecksumObserverForD4Struct( item, ptr, size );
00070                 getD4TokensFromStruct( item, ptr, size );
00071 
00072             }
00073             // loathe C++. Why in the heck is there no finally()?
00074             // oh yeah, that would be Stroustrup again. :-(
00075             catch ( const std::exception & )
00076             {
00077                 // make sure this is always in sync with below
00078                 delete [] const_cast<u8*>(ptr);
00079                 ptr = 0;
00080                 throw;
00081             }
00082             // make sure this is always in sync with the above.
00083             delete [] const_cast<u8*>(ptr);
00084             ptr = 0;
00085         }
00086     }
00087 
00088     void TokenTable::addChecksumObserverForD4Struct(const smbios::ISmbiosTable::const_iterator &item, const u8 *ptr, size_t size)
00089     {
00090         ostringstream ost;
00091         ost << *item;
00092         (void) size; // avoid unused param warning
00093 
00094         //  cast buffer to 'indexed_io_access' struct to make
00095         //  life easier.
00096         const indexed_io_access_structure *io_struct =
00097             reinterpret_cast<const indexed_io_access_structure *>(ptr);
00098 
00099         // no need to delete, it is a singleton.
00100         //cout << "Adding checksum observer" << endl;
00101         cmos::ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00102         CmosRWChecksumObserver chk(
00103             ost.str(),
00104             cmos,
00105             io_struct->checkType,
00106             io_struct->indexPort,
00107             io_struct->dataPort,
00108             io_struct->checkedRangeStartIndex,
00109             io_struct->checkedRangeEndIndex,
00110             io_struct->checkValueIndex  );
00111         checksumList.push_back( chk );
00112     }
00113 
00114     void TokenTable::getD4TokensFromStruct(const smbios::ISmbiosTable::const_iterator &item, const u8 *ptr, size_t size)
00115     {
00116         //  cast buffer to 'indexed_io_access' struct to make
00117         //  life easier.
00118         const indexed_io_access_structure *io_struct =
00119             reinterpret_cast<const indexed_io_access_structure *>(ptr);
00120 
00121         // now iterate over each token in the structure
00122         //   here, the last item in the struct is "first_token", which
00123         //   is really just a pointer to the first in an array.
00124         int count = 0;
00125         const indexed_io_token *iterToken;
00126         iterToken = &(io_struct->first_token);
00127         for(
00128             int i = 0;
00129             (iterToken[i].tokenId != TokenTypeEOT);
00130             ++i
00131         )
00132         {
00133             // work arounds for astyle bug (temp vars instead of doing
00134             // this all in if()):
00135             const u8 *cur_loc = reinterpret_cast<const u8 *>(&iterToken[i]);
00136             const u8 *struct_base_loc = reinterpret_cast<const u8 *>(io_struct);
00137             if ( cur_loc >= struct_base_loc + size )
00138             {
00139 #if LIBSMBIOS_VERBOSE_BIOS_BUG_COMPLAINTS
00140                 cout << "FATAL: iterToken > size.  Missing EOT, has the world gone mad?" << endl;
00141 #endif
00142                 break;
00143             }
00144             //instantiate the token
00145             CmosTokenD4 *tk = new CmosTokenD4( (*item), &iterToken[i] );
00146             tokenList.push_back( tk ); // pushes a copy
00147             ++ count;
00148         }
00149     }
00150 
00151     void TokenTable::addD5Structures(const smbios::ISmbiosTable & table)
00152     {
00153         // Pull out all of the 0xD5 entries and create Tokens out of them
00154         // iterate over each 0xD5 token (protected value 1)
00155         for(
00156             smbios::ISmbiosTable::const_iterator item = table[DellProtectedAreaType1];
00157             item != table.end();
00158             ++item)
00159         {
00160             //instantiate the token
00161             CmosTokenD5 *tk = new CmosTokenD5( (*item), checksumList );
00162             tokenList.push_back( tk ); // pushes a copy
00163         }
00164     }
00165 
00166     void TokenTable::addD6Structures(const smbios::ISmbiosTable & table)
00167     {
00168         // Pull out all of the 0xD6 entries and create Tokens out of them
00169         // iterate over each 0xD6 token (protected value 1)
00170         for(
00171             smbios::ISmbiosTable::const_iterator item = table[DellProtectedAreaType2];
00172             item != table.end();
00173             ++item)
00174         {
00175             //instantiate the token
00176             CmosTokenD6 *tk = new CmosTokenD6( (*item), checksumList );
00177             tokenList.push_back( tk ); // pushes a copy
00178         }
00179     }
00180 
00181     void TokenTable::addDAStructures(const smbios::ISmbiosTable & table)
00182     {
00183         // Pull out all of the 0xDA entries and create Tokens out of them
00184         // iterate over each 0xDA token (Dell_Indexed_Io)
00185         for(
00186             smbios::ISmbiosTable::const_iterator item = table[DellCallingInterface];
00187             item != table.end();
00188             ++item)
00189         {
00190             // get a copy of the buffer
00191             size_t size = 0;
00192             const u8 *ptr =  item->getBufferCopy(size) ; // MUST DELETE[]!
00193             try
00194             {
00195                 getDATokensFromStruct( item, ptr, size );
00196 
00197             }
00198             // loathe C++. Why in the heck is there no finally()?
00199             // oh yeah, that would be Stroustrup again. :-(
00200             catch ( const std::exception & )
00201             {
00202                 // make sure this is always in sync with below
00203                 delete [] const_cast<u8*>(ptr);
00204                 ptr = 0;
00205                 throw;
00206             }
00207             // make sure this is always in sync with the above.
00208             delete [] const_cast<u8*>(ptr);
00209             ptr = 0;
00210         }
00211     }
00212 
00213     void TokenTable::getDATokensFromStruct(const smbios::ISmbiosTable::const_iterator &item, const u8 *ptr, size_t size)
00214     {
00215         //  cast buffer to 'calling_interface_structure' struct to make
00216         //  life easier.
00217         const calling_interface_structure *structure =
00218             reinterpret_cast<const calling_interface_structure *>(ptr);
00219 
00220         // now iterate over each token in the structure
00221         //   here, the last item in the struct is "first_token", which
00222         //   is really just a pointer to the first in an array.
00223         int count = 0;
00224         const calling_interface_token *iterToken;
00225         iterToken = &(structure->first_token);
00226         for(
00227             int i = 0;
00228             (iterToken[i].tokenId != TokenTypeEOT);
00229             ++i
00230         )
00231         {
00232             // work arounds for astyle bug (temp vars instead of doing
00233             // this all in if()):
00234             const u8 *cur_loc = reinterpret_cast<const u8 *>(&iterToken[i]);
00235             const u8 *struct_base_loc = reinterpret_cast<const u8 *>(structure);
00236             if ( cur_loc + sizeof(calling_interface_token) >= struct_base_loc + size )
00237             {
00238 #if LIBSMBIOS_VERBOSE_BIOS_BUG_COMPLAINTS
00239                 // BIOS violates spec.
00240                 if(i>0)
00241                     cout << endl << "FATAL: iterToken > size.  Missing EOT, has the world gone mad?" << endl << *item << endl;
00242 #endif
00243 
00244                 break;
00245             }
00246             //instantiate the token
00247             //cout
00248             //    << "TokenId: " << hex << (int)iterToken[i].tokenId << "  "
00249             //    << "location: " << hex << (int)iterToken[i].location << "  "
00250             //    << "value: " << hex << (int)iterToken[i].value << endl;
00251 
00252             SmiTokenDA *tk = new SmiTokenDA( (*item), &iterToken[i] );
00253             tokenList.push_back( tk ); // pushes a copy
00254             ++ count;
00255         }
00256     }
00257 
00258     TokenTable::~TokenTable( )
00259     {
00260         std::vector< IToken *>::iterator token;
00261         for( token = tokenList.begin(); token != tokenList.end(); ++token )
00262         {
00263             delete *token;
00264         }
00265     }
00266 
00267     ITokenTable::~ITokenTable( )
00268     {}
00269 
00270     TokenTable::iterator TokenTable::begin ()
00271     {
00272         return TokenTable::iterator (this);
00273     }
00274 
00275     TokenTable::const_iterator TokenTable::begin () const
00276     {
00277         return TokenTable::const_iterator (this);
00278     }
00279 
00280     TokenTable::iterator TokenTable::end ()
00281     {
00282         return TokenTable::iterator ();
00283     }
00284 
00285     TokenTable::const_iterator TokenTable::end ()const
00286     {
00287         return TokenTable::const_iterator ();
00288     }
00289 
00290     TokenTable::iterator TokenTable::operator[] (const int type)
00291     {
00292         return TokenTable::iterator (this, type);
00293     }
00294 
00295     TokenTable::const_iterator TokenTable::operator[](const int type) const
00296     {
00297         // this == const TokenTable();
00298         return TokenTable::const_iterator (this, type);
00299     }
00300 
00301     TokenTable::iterator TokenTable::operator[] (const string &)
00302     {
00303         NOT_IMPLEMENTED;
00304     }
00305 
00306     TokenTable::const_iterator TokenTable::operator[](const string &) const
00307     {
00308         NOT_IMPLEMENTED;
00309     }
00310 
00311 
00312     ostream & TokenTable::streamify(ostream & cout) const
00313     {
00314         cout << "Token Table";
00315         return cout;
00316     }
00317 
00318     std::ostream & operator << (std::ostream & cout, const ITokenTable & table)
00319     {
00320         return table.streamify(cout);
00321     }
00322 }

Generated on Wed Apr 11 16:25:10 2007 for SMBIOS Library by doxygen 1.3.5