SMBIOS Library
TokenTable.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 <sstream>
24 
25 #include "TokenImpl.h"
26 
27 using namespace std;
28 
29 // for functions that are not implemented at this level in the
30 // inheritance heirarchy at all.
31 #define NOT_IMPLEMENTED do { throw NotImplementedImpl(); } while(0)
32 
33 // Token numbering:
34 // -- all tokens are 16-bit, this means we can store token number in 32-bit
35 // value and use topmost bits as a 'type' code.
36 
37 namespace smbios
38 {
39  ITokenTable::ITokenTable()
40  {}
41 
42  //
43  //
44  TokenTable::TokenTable( const smbios::ISmbiosTable & table)
45  {
46  addD4Structures(table);
47  addD5Structures(table);
48  addD6Structures(table);
49  addDAStructures(table);
50  }
51 
52  void TokenTable::addD4Structures(const smbios::ISmbiosTable & table)
53  {
54  // usually have around 4 checksums or so. estimate here to speed up stuff later.
55  checksumList.reserve(4);
56 
57  // Pull out all of the 0xD4 entries and create Tokens out of them
58  // iterate over each 0xD4 token (Dell_Indexed_Io)
59  for(
61  item != table.end();
62  ++item)
63  {
64  // get a copy of the buffer
65  size_t size = 0;
66  const u8 *ptr = item->getBufferCopy(size) ; // MUST DELETE[]!
67  try
68  {
69  addChecksumObserverForD4Struct( item, ptr, size );
70  getD4TokensFromStruct( item, ptr, size );
71 
72  }
73  // loathe C++. Why in the heck is there no finally()?
74  // oh yeah, that would be Stroustrup again. :-(
75  catch ( const std::exception & )
76  {
77  // make sure this is always in sync with below
78  delete [] const_cast<u8*>(ptr);
79  ptr = 0;
80  throw;
81  }
82  // make sure this is always in sync with the above.
83  delete [] const_cast<u8*>(ptr);
84  ptr = 0;
85  }
86  }
87 
88  void TokenTable::addChecksumObserverForD4Struct(const smbios::ISmbiosTable::const_iterator &item, const u8 *ptr, size_t size)
89  {
90  ostringstream ost;
91  ost << *item;
92  (void) size; // avoid unused param warning
93 
94  // cast buffer to 'indexed_io_access' struct to make
95  // life easier.
96  const indexed_io_access_structure *io_struct =
97  reinterpret_cast<const indexed_io_access_structure *>(ptr);
98 
99  // no need to delete, it is a singleton.
100  //cout << "Adding checksum observer" << endl;
103  ost.str(),
104  cmos,
105  io_struct->checkType,
106  io_struct->indexPort,
107  io_struct->dataPort,
108  io_struct->checkedRangeStartIndex,
109  io_struct->checkedRangeEndIndex,
110  io_struct->checkValueIndex );
111  checksumList.push_back( chk );
112  }
113 
114  void TokenTable::getD4TokensFromStruct(const smbios::ISmbiosTable::const_iterator &item, const u8 *ptr, size_t size)
115  {
116  // cast buffer to 'indexed_io_access' struct to make
117  // life easier.
118  const indexed_io_access_structure *io_struct =
119  reinterpret_cast<const indexed_io_access_structure *>(ptr);
120 
121  // now iterate over each token in the structure
122  // here, the last item in the struct is "first_token", which
123  // is really just a pointer to the first in an array.
124  int count = 0;
125  const indexed_io_token *iterToken;
126  iterToken = &(io_struct->first_token);
127  for(
128  int i = 0;
129  (iterToken[i].tokenId != TokenTypeEOT);
130  ++i
131  )
132  {
133  // work arounds for astyle bug (temp vars instead of doing
134  // this all in if()):
135  const u8 *cur_loc = reinterpret_cast<const u8 *>(&iterToken[i]);
136  const u8 *struct_base_loc = reinterpret_cast<const u8 *>(io_struct);
137  if ( cur_loc >= struct_base_loc + size )
138  {
139 #if LIBSMBIOS_VERBOSE_BIOS_BUG_COMPLAINTS
140  cout << "FATAL: iterToken > size. Missing EOT, has the world gone mad?" << endl;
141 #endif
142  break;
143  }
144  //instantiate the token
145  CmosTokenD4 *tk = new CmosTokenD4( (*item), &iterToken[i] );
146  tokenList.push_back( tk ); // pushes a copy
147  ++ count;
148  }
149  }
150 
151  void TokenTable::addD5Structures(const smbios::ISmbiosTable & table)
152  {
153  // Pull out all of the 0xD5 entries and create Tokens out of them
154  // iterate over each 0xD5 token (protected value 1)
155  for(
157  item != table.end();
158  ++item)
159  {
160  //instantiate the token
161  CmosTokenD5 *tk = new CmosTokenD5( (*item), checksumList );
162  tokenList.push_back( tk ); // pushes a copy
163  }
164  }
165 
166  void TokenTable::addD6Structures(const smbios::ISmbiosTable & table)
167  {
168  // Pull out all of the 0xD6 entries and create Tokens out of them
169  // iterate over each 0xD6 token (protected value 1)
170  for(
172  item != table.end();
173  ++item)
174  {
175  //instantiate the token
176  CmosTokenD6 *tk = new CmosTokenD6( (*item), checksumList );
177  tokenList.push_back( tk ); // pushes a copy
178  }
179  }
180 
181  void TokenTable::addDAStructures(const smbios::ISmbiosTable & table)
182  {
183  // Pull out all of the 0xDA entries and create Tokens out of them
184  // iterate over each 0xDA token (Dell_Indexed_Io)
185  for(
187  item != table.end();
188  ++item)
189  {
190  // get a copy of the buffer
191  size_t size = 0;
192  const u8 *ptr = item->getBufferCopy(size) ; // MUST DELETE[]!
193  try
194  {
195  getDATokensFromStruct( item, ptr, size );
196 
197  }
198  // loathe C++. Why in the heck is there no finally()?
199  // oh yeah, that would be Stroustrup again. :-(
200  catch ( const std::exception & )
201  {
202  // make sure this is always in sync with below
203  delete [] const_cast<u8*>(ptr);
204  ptr = 0;
205  throw;
206  }
207  // make sure this is always in sync with the above.
208  delete [] const_cast<u8*>(ptr);
209  ptr = 0;
210  }
211  }
212 
213  void TokenTable::getDATokensFromStruct(const smbios::ISmbiosTable::const_iterator &item, const u8 *ptr, size_t size)
214  {
215  // cast buffer to 'calling_interface_structure' struct to make
216  // life easier.
217  const calling_interface_structure *structure =
218  reinterpret_cast<const calling_interface_structure *>(ptr);
219 
220  // now iterate over each token in the structure
221  // here, the last item in the struct is "first_token", which
222  // is really just a pointer to the first in an array.
223  int count = 0;
224  const calling_interface_token *iterToken;
225  iterToken = &(structure->first_token);
226  for(
227  int i = 0;
228  (iterToken[i].tokenId != TokenTypeEOT);
229  ++i
230  )
231  {
232  // work arounds for astyle bug (temp vars instead of doing
233  // this all in if()):
234  const u8 *cur_loc = reinterpret_cast<const u8 *>(&iterToken[i]);
235  const u8 *struct_base_loc = reinterpret_cast<const u8 *>(structure);
236  if ( cur_loc + sizeof(calling_interface_token) >= struct_base_loc + size )
237  {
238 #if LIBSMBIOS_VERBOSE_BIOS_BUG_COMPLAINTS
239  // BIOS violates spec.
240  if(i>0)
241  cout << endl << "FATAL: iterToken > size. Missing EOT, has the world gone mad?" << endl << *item << endl;
242 #endif
243 
244  break;
245  }
246  //instantiate the token
247  //cout
248  // << "TokenId: " << hex << (int)iterToken[i].tokenId << " "
249  // << "location: " << hex << (int)iterToken[i].location << " "
250  // << "value: " << hex << (int)iterToken[i].value << endl;
251 
252  SmiTokenDA *tk = new SmiTokenDA( (*item), &iterToken[i] );
253  tokenList.push_back( tk ); // pushes a copy
254  ++ count;
255  }
256  }
257 
258  TokenTable::~TokenTable( )
259  {
260  std::vector< IToken *>::iterator token;
261  for( token = tokenList.begin(); token != tokenList.end(); ++token )
262  {
263  delete *token;
264  }
265  }
266 
267  ITokenTable::~ITokenTable( )
268  {}
269 
270  TokenTable::iterator TokenTable::begin ()
271  {
272  return TokenTable::iterator (this);
273  }
274 
275  TokenTable::const_iterator TokenTable::begin () const
276  {
277  return TokenTable::const_iterator (this);
278  }
279 
280  TokenTable::iterator TokenTable::end ()
281  {
282  return TokenTable::iterator ();
283  }
284 
285  TokenTable::const_iterator TokenTable::end ()const
286  {
287  return TokenTable::const_iterator ();
288  }
289 
290  TokenTable::iterator TokenTable::operator[] (const int type)
291  {
292  return TokenTable::iterator (this, type);
293  }
294 
295  TokenTable::const_iterator TokenTable::operator[](const int type) const
296  {
297  // this == const TokenTable();
298  return TokenTable::const_iterator (this, type);
299  }
300 
301  TokenTable::iterator TokenTable::operator[] (const string &)
302  {
304  }
305 
306  TokenTable::const_iterator TokenTable::operator[](const string &) const
307  {
309  }
310 
311 
312  ostream & TokenTable::streamify(ostream & cout) const
313  {
314  cout << "Token Table";
315  return cout;
316  }
317 
318  std::ostream & operator << (std::ostream & cout, const ITokenTable & table)
319  {
320  return table.streamify(cout);
321  }
322 }