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

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

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