TokenD4.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 <iomanip>
00024 #include <string.h>
00025 
00026 #include "TokenImpl.h"
00027 
00028 using namespace std;
00029 
00030 namespace smbios
00031 {
00032     CmosTokenD4::CmosTokenD4( const smbios::ISmbiosItem &initItem, const indexed_io_token *initToken )
00033             : IToken(), ICmosToken(), item(initItem.clone()), cmos(cmos::CmosRWFactory::getFactory()->getSingleton())
00034     {
00035         memcpy( const_cast<indexed_io_token *>(&token), initToken, sizeof(token) );
00036 
00037         size_t size;
00038         const u8 *ptr =  item->getBufferCopy(size) ; // MUST DELETE[]!
00039         memcpy( const_cast<indexed_io_access_structure*>(&structure), ptr, sizeof(structure) );
00040         delete [] const_cast<u8 *>(ptr); //const_cast to fix msvc++
00041     }
00042 
00043     // no dynamically allocated memory, yay!
00044     CmosTokenD4::~CmosTokenD4() throw()
00045     {}
00046 
00047     string CmosTokenD4::getTokenClass() const
00048     {
00049         return "TokenD4";
00050     }
00051 
00052     const ISmbiosItem &CmosTokenD4::getItemRef() const
00053     {
00054         return *item;
00055     }
00056 
00057     u32 CmosTokenD4::getType() const
00058     {
00059         return token.tokenId;
00060     }
00061 
00062     bool CmosTokenD4::isActive() const
00063     {
00064         if( isString() )
00065             throw InvalidAccessModeImpl("tried to call isActive() on a string token." );
00066 
00067         bool retval = false;
00068 
00069         u8 byte = cmos->readByte(
00070                       structure.indexPort,
00071                       structure.dataPort,
00072                       token.location
00073                   );
00074 
00075         if( (byte & (~token.andMask)) == token.orValue  )
00076             retval = true;
00077 
00078         return retval;
00079     }
00080 
00081     void CmosTokenD4::activate() const
00082     {
00083         if( isString() )
00084             throw InvalidAccessModeImpl("tried to activate() a string token." );
00085 
00086         u8 byte = cmos->readByte(
00087                       structure.indexPort,
00088                       structure.dataPort,
00089                       token.location
00090                   );
00091 
00092         byte = byte & token.andMask;
00093         byte = byte | token.orValue;
00094 
00095         cmos->writeByte(
00096             structure.indexPort,
00097             structure.dataPort,
00098             token.location,
00099             byte
00100         );
00101     }
00102 
00103     bool CmosTokenD4::isString() const
00104     {
00105         bool retval = false;
00106         if( 0 == token.andMask)
00107             retval = true;
00108         return retval;
00109     }
00110 
00111     bool CmosTokenD4::isBool() const
00112     {
00113         return ! isString();
00114     }
00115 
00116     const string CmosTokenD4::getString(u8 *byteArray, unsigned int size ) const
00117     {
00118         if( ! isString() )
00119             throw InvalidAccessModeImpl("tried to call getString() on a bit token.");
00120 
00121         bool allocatedMem = false;
00122         try
00123         {
00124             unsigned int strSize = getStringLength();
00125             if( !byteArray )
00126             {
00127                 size = strSize + 1;
00128                 byteArray = new u8[size];
00129                 allocatedMem = true;
00130             }
00131 
00132             if( size < strSize + 1 )
00133                 throw ParameterErrorImpl("called getString() with too small of a buffer."); // not enough space to store results
00134 
00135             for( unsigned int i=0; i<strSize; ++i )
00136                 byteArray[i] = '\0';
00137 
00138             cmos::readByteArray(
00139                 *cmos,
00140                 structure.indexPort,
00141                 structure.dataPort,
00142                 token.location,
00143                 byteArray,
00144                 strSize
00145             );
00146 
00147             byteArray[ getStringLength() ] = '\0';
00148             string retval(reinterpret_cast<const char *>(byteArray));
00149             if( allocatedMem )
00150             {
00151                 delete [] byteArray;
00152                 byteArray = 0;
00153                 allocatedMem = false;
00154             }
00155             return retval;
00156 
00157         }
00158         catch ( const std::exception & )
00159         {
00160             if( allocatedMem )
00161                 delete [] byteArray;
00162             throw;
00163         }
00164 
00165     }
00166 
00167     void CmosTokenD4::setString( const u8 *byteArray, size_t size ) const
00168     {
00169         if( ! isString() )
00170             throw InvalidAccessModeImpl("tried to setString() on non-string.");
00171 
00172         unsigned int strSize = getStringLength();
00173 
00174         u8 *targetBuffer = new u8[strSize];
00175         memset(targetBuffer, 0, strSize);
00176         memcpy( targetBuffer, byteArray, size < strSize ? size : strSize );
00177 
00178         cmos::writeByteArray(
00179             *cmos,
00180             structure.indexPort,
00181             structure.dataPort,
00182             token.location,
00183             targetBuffer,
00184             strSize
00185         );
00186 
00187         delete[](targetBuffer);
00188     }
00189 
00190     unsigned int CmosTokenD4::getStringLength() const
00191     {
00192         if( ! isString() )
00193             throw InvalidAccessModeImpl("tried to getStringLength on non-string.");
00194         // STRING must be at least 1 byte. Does not make sense
00195         // otherwise. BIOS Error? NVRAM byte tokens (0x83/0x84) seem to be
00196         // string tokens of length 0. That looks wrong.
00197         return token.stringLength ? token.stringLength : 1;
00198     }
00199 
00200     void CmosTokenD4::getCMOSDetails( u16 *indexPort, u16 *dataPort, u8 *location ) const
00201     {
00202         *indexPort = structure.indexPort;
00203         *dataPort = structure.dataPort;
00204         *location = token.location;
00205         return;
00206     }
00207 
00208     std::ostream & CmosTokenD4::streamify( std::ostream & cout ) const
00209     {
00210         std::ios::fmtflags old_opts = cout.flags ();
00211 
00212         cout << "DMI type 0x" << hex << setfill ('0') << setw (2) << static_cast<int>(structure.type);
00213         cout << "  Handle 0x" << hex << setfill ('0') << setw (4) << static_cast<int>(structure.handle);
00214         cout << "  Index Port 0x" << hex << setw(2) << structure.indexPort;
00215         cout << "  Data Port 0x"  << hex << setw(2) << structure.dataPort;
00216         cout << "  Type 0x" << hex << setw(4) << static_cast<int>(getType());
00217         cout << "  Location 0x" << hex << setw(2) << static_cast<int>(token.location);
00218         if( isString() )
00219         {
00220             cout << " STRING  Length " << dec << setfill('0') << setw(2) << getStringLength() ;
00221             cout << " value(" << getString() << ")";
00222         }
00223         else
00224         {
00225             cout << " AND(" << setw(1) << static_cast<int>(token.andMask) << ") ";
00226             cout << "OR(" << setw(1) << static_cast<int>(token.orValue) << ") ";
00227             cout << " BITFIELD: " << isActive();
00228         }
00229 
00230         cout.flags (old_opts);
00231 
00232         return cout;
00233     }
00234 
00235 }

Generated on Wed Apr 2 16:37:38 2008 for SMBIOS Library by  doxygen 1.5.1