SMBIOS Library
TokenD4.cpp
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
3  *
4  * Copyright (C) 2005 Dell Inc.
5  * by Michael Brown <Michael_E_Brown@dell.com>
6  * Licensed under the Open Software License version 2.1
7  *
8  * Alternatively, you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2 of the License,
11  * or (at your option) any later version.
12 
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  */
18 
19 // compat header should always be first header if including system headers
20 #define LIBSMBIOS_SOURCE
21 #include "smbios/compat.h"
22 
23 #include <iomanip>
24 #include <string.h>
25 
26 #include "TokenImpl.h"
27 
28 using namespace std;
29 
30 namespace smbios
31 {
32  CmosTokenD4::CmosTokenD4( const smbios::ISmbiosItem &initItem, const indexed_io_token *initToken )
33  : IToken(), ICmosToken(), item(initItem.clone()), cmos(cmos::CmosRWFactory::getFactory()->getSingleton())
34  {
35  memcpy( const_cast<indexed_io_token *>(&token), initToken, sizeof(token) );
36 
37  size_t size;
38  const u8 *ptr = item->getBufferCopy(size) ; // MUST DELETE[]!
39  memcpy( const_cast<indexed_io_access_structure*>(&structure), ptr, sizeof(structure) );
40  delete [] const_cast<u8 *>(ptr); //const_cast to fix msvc++
41  }
42 
43  // no dynamically allocated memory, yay!
45  {}
46 
48  {
49  return "TokenD4";
50  }
51 
53  {
54  return *item;
55  }
56 
58  {
59  return token.tokenId;
60  }
61 
62  bool CmosTokenD4::isActive() const
63  {
64  if( isString() )
65  throw InvalidAccessModeImpl("tried to call isActive() on a string token." );
66 
67  bool retval = false;
68 
69  u8 byte = cmos->readByte(
73  );
74 
75  if( (byte & (~token.andMask)) == token.orValue )
76  retval = true;
77 
78  return retval;
79  }
80 
81  void CmosTokenD4::activate() const
82  {
83  if( isString() )
84  throw InvalidAccessModeImpl("tried to activate() a string token." );
85 
86  u8 byte = cmos->readByte(
90  );
91 
92  byte = byte & token.andMask;
93  byte = byte | token.orValue;
94 
95  cmos->writeByte(
99  byte
100  );
101  }
102 
104  {
105  bool retval = false;
106  if( 0 == token.andMask)
107  retval = true;
108  return retval;
109  }
110 
111  bool CmosTokenD4::isBool() const
112  {
113  return ! isString();
114  }
115 
116  const string CmosTokenD4::getString(u8 *byteArray, unsigned int size ) const
117  {
118  if( ! isString() )
119  throw InvalidAccessModeImpl("tried to call getString() on a bit token.");
120 
121  bool allocatedMem = false;
122  try
123  {
124  unsigned int strSize = getStringLength();
125  if( !byteArray )
126  {
127  size = strSize + 1;
128  byteArray = new u8[size];
129  allocatedMem = true;
130  }
131 
132  if( size < strSize + 1 )
133  throw ParameterErrorImpl("called getString() with too small of a buffer."); // not enough space to store results
134 
135  for( unsigned int i=0; i<strSize; ++i )
136  byteArray[i] = '\0';
137 
139  *cmos,
142  token.location,
143  byteArray,
144  strSize
145  );
146 
147  byteArray[ getStringLength() ] = '\0';
148  string retval(reinterpret_cast<const char *>(byteArray));
149  if( allocatedMem )
150  {
151  delete [] byteArray;
152  byteArray = 0;
153  allocatedMem = false;
154  }
155  return retval;
156 
157  }
158  catch ( const std::exception & )
159  {
160  if( allocatedMem )
161  delete [] byteArray;
162  throw;
163  }
164 
165  }
166 
167  void CmosTokenD4::setString( const u8 *byteArray, size_t size ) const
168  {
169  if( ! isString() )
170  throw InvalidAccessModeImpl("tried to setString() on non-string.");
171 
172  unsigned int strSize = getStringLength();
173 
174  u8 *targetBuffer = new u8[strSize];
175  memset(targetBuffer, 0, strSize);
176  memcpy( targetBuffer, byteArray, size < strSize ? size : strSize );
177 
179  *cmos,
182  token.location,
183  targetBuffer,
184  strSize
185  );
186 
187  delete[](targetBuffer);
188  }
189 
190  unsigned int CmosTokenD4::getStringLength() const
191  {
192  if( ! isString() )
193  throw InvalidAccessModeImpl("tried to getStringLength on non-string.");
194  // STRING must be at least 1 byte. Does not make sense
195  // otherwise. BIOS Error? NVRAM byte tokens (0x83/0x84) seem to be
196  // string tokens of length 0. That looks wrong.
197  return token.stringLength ? token.stringLength : 1;
198  }
199 
200  void CmosTokenD4::getCMOSDetails( u16 *indexPort, u16 *dataPort, u8 *location ) const
201  {
202  *indexPort = structure.indexPort;
203  *dataPort = structure.dataPort;
204  *location = token.location;
205  return;
206  }
207 
208  std::ostream & CmosTokenD4::streamify( std::ostream & cout ) const
209  {
210  std::ios::fmtflags old_opts = cout.flags ();
211 
212  cout << "DMI type 0x" << hex << setfill ('0') << setw (2) << static_cast<int>(structure.type);
213  cout << " Handle 0x" << hex << setfill ('0') << setw (4) << static_cast<int>(structure.handle);
214  cout << " Index Port 0x" << hex << setw(2) << structure.indexPort;
215  cout << " Data Port 0x" << hex << setw(2) << structure.dataPort;
216  cout << " Type 0x" << hex << setw(4) << static_cast<int>(getType());
217  cout << " Location 0x" << hex << setw(2) << static_cast<int>(token.location);
218  if( isString() )
219  {
220  cout << " STRING Length " << dec << setfill('0') << setw(2) << getStringLength() ;
221  cout << " value(" << getString() << ")";
222  }
223  else
224  {
225  cout << " AND(" << setw(1) << static_cast<int>(token.andMask) << ") ";
226  cout << "OR(" << setw(1) << static_cast<int>(token.orValue) << ") ";
227  cout << " BITFIELD: " << isActive();
228  }
229 
230  cout.flags (old_opts);
231 
232  return cout;
233  }
234 
235 }