gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
intelmp.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 The Hewlett-Packard Development Company
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Gabe Black
38  */
39 
40 #include "arch/x86/bios/intelmp.hh"
41 
42 #include "arch/x86/isa_traits.hh"
43 #include "base/misc.hh"
44 #include "base/types.hh"
45 #include "mem/port_proxy.hh"
46 #include "sim/byteswap.hh"
47 
48 // Config entry types
49 #include "params/X86IntelMPBaseConfigEntry.hh"
50 #include "params/X86IntelMPExtConfigEntry.hh"
51 
52 // General table structures
53 #include "params/X86IntelMPConfigTable.hh"
54 #include "params/X86IntelMPFloatingPointer.hh"
55 
56 // Base entry types
57 #include "params/X86IntelMPBus.hh"
58 #include "params/X86IntelMPIOAPIC.hh"
59 #include "params/X86IntelMPIOIntAssignment.hh"
60 #include "params/X86IntelMPLocalIntAssignment.hh"
61 #include "params/X86IntelMPProcessor.hh"
62 
63 // Extended entry types
64 #include "params/X86IntelMPAddrSpaceMapping.hh"
65 #include "params/X86IntelMPBusHierarchy.hh"
66 #include "params/X86IntelMPCompatAddrSpaceMod.hh"
67 
68 using namespace std;
69 
71 
72 template<class T>
73 uint8_t
75 {
76  uint64_t guestVal = X86ISA::htog(val);
77  proxy.writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
78 
79  uint8_t checkSum = 0;
80  while (guestVal) {
81  checkSum += guestVal;
82  guestVal >>= 8;
83  }
84  return checkSum;
85 }
86 
87 uint8_t
88 writeOutString(PortProxy& proxy, Addr addr, string str, int length)
89 {
90  char cleanedString[length + 1];
91  cleanedString[length] = 0;
92 
93  if (str.length() > length) {
94  memcpy(cleanedString, str.c_str(), length);
95  warn("Intel MP configuration table string \"%s\" "
96  "will be truncated to \"%s\".\n", str, (char *)&cleanedString);
97  } else {
98  memcpy(cleanedString, str.c_str(), str.length());
99  memset(cleanedString + str.length(), 0, length - str.length());
100  }
101  proxy.writeBlob(addr, (uint8_t *)(&cleanedString), length);
102 
103  uint8_t checkSum = 0;
104  for (int i = 0; i < length; i++)
105  checkSum += cleanedString[i];
106 
107  return checkSum;
108 }
109 
110 Addr
112 {
113  // Make sure that either a config table is present or a default
114  // configuration was found but not both.
115  if (!tableAddr && !defaultConfig)
116  fatal("Either an MP configuration table or a default configuration "
117  "must be used.");
118  if (tableAddr && defaultConfig)
119  fatal("Both an MP configuration table and a default configuration "
120  "were set.");
121 
122  uint8_t checkSum = 0;
123 
124  proxy.writeBlob(addr, (uint8_t *)signature, 4);
125  for (int i = 0; i < 4; i++)
126  checkSum += signature[i];
127 
128  checkSum += writeOutField(proxy, addr + 4, tableAddr);
129 
130  // The length of the structure in paragraphs, aka 16 byte chunks.
131  uint8_t length = 1;
132  proxy.writeBlob(addr + 8, &length, 1);
133  checkSum += length;
134 
135  proxy.writeBlob(addr + 9, &specRev, 1);
136  checkSum += specRev;
137 
138  proxy.writeBlob(addr + 11, &defaultConfig, 1);
139  checkSum += defaultConfig;
140 
141  uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
142  checkSum += writeOutField(proxy, addr + 12, features2_5);
143 
144  checkSum = -checkSum;
145  proxy.writeBlob(addr + 10, &checkSum, 1);
146 
147  return 16;
148 }
149 
151  SimObject(p), tableAddr(0), specRev(p->spec_rev),
152  defaultConfig(p->default_config), imcrPresent(p->imcr_present)
153 {}
154 
156 X86IntelMPFloatingPointerParams::create()
157 {
158  return new X86ISA::IntelMP::FloatingPointer(this);
159 }
160 
161 Addr
163  Addr addr, uint8_t &checkSum)
164 {
165  proxy.writeBlob(addr, &type, 1);
166  checkSum += type;
167  return 1;
168 }
169 
171  SimObject(p), type(_type)
172 {}
173 
174 Addr
176  Addr addr, uint8_t &checkSum)
177 {
178  proxy.writeBlob(addr, &type, 1);
179  checkSum += type;
180  proxy.writeBlob(addr + 1, &length, 1);
181  checkSum += length;
182  return 1;
183 }
184 
186  uint8_t _type, uint8_t _length) :
187  SimObject(p), type(_type), length(_length)
188 {}
189 
190 const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
191 
192 Addr
194 {
195  uint8_t checkSum = 0;
196 
197  proxy.writeBlob(addr, (uint8_t *)signature, 4);
198  for (int i = 0; i < 4; i++)
199  checkSum += signature[i];
200 
201  // Base table length goes here but will be calculated later.
202 
203  proxy.writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
204  checkSum += specRev;
205 
206  // The checksum goes here but is still being calculated.
207 
208  checkSum += writeOutString(proxy, addr + 8, oemID, 8);
209  checkSum += writeOutString(proxy, addr + 16, productID, 12);
210 
211  checkSum += writeOutField(proxy, addr + 28, oemTableAddr);
212  checkSum += writeOutField(proxy, addr + 32, oemTableSize);
213  checkSum += writeOutField(proxy, addr + 34, (uint16_t)baseEntries.size());
214  checkSum += writeOutField(proxy, addr + 36, localApic);
215 
216  uint8_t reserved = 0;
217  proxy.writeBlob(addr + 43, &reserved, 1);
218  checkSum += reserved;
219 
221  uint16_t offset = 44;
222  for (baseEnt = baseEntries.begin();
223  baseEnt != baseEntries.end(); baseEnt++) {
224  offset += (*baseEnt)->writeOut(proxy, addr + offset, checkSum);
225  }
226 
227  // We've found the end of the base table this point.
228  checkSum += writeOutField(proxy, addr + 4, offset);
229 
231  uint16_t extOffset = 0;
232  uint8_t extCheckSum = 0;
233  for (extEnt = extEntries.begin();
234  extEnt != extEntries.end(); extEnt++) {
235  extOffset += (*extEnt)->writeOut(proxy,
236  addr + offset + extOffset, extCheckSum);
237  }
238 
239  checkSum += writeOutField(proxy, addr + 40, extOffset);
240  extCheckSum = -extCheckSum;
241  checkSum += writeOutField(proxy, addr + 42, extCheckSum);
242 
243  // And now, we finally have the whole check sum completed.
244  checkSum = -checkSum;
245  writeOutField(proxy, addr + 7, checkSum);
246 
247  return offset + extOffset;
248 };
249 
251  specRev(p->spec_rev), oemID(p->oem_id), productID(p->product_id),
252  oemTableAddr(p->oem_table_addr), oemTableSize(p->oem_table_size),
253  localApic(p->local_apic),
254  baseEntries(p->base_entries), extEntries(p->ext_entries)
255 {}
256 
258 X86IntelMPConfigTableParams::create()
259 {
260  return new X86ISA::IntelMP::ConfigTable(this);
261 }
262 
263 Addr
265  PortProxy& proxy, Addr addr, uint8_t &checkSum)
266 {
267  BaseConfigEntry::writeOut(proxy, addr, checkSum);
268  checkSum += writeOutField(proxy, addr + 1, localApicID);
269  checkSum += writeOutField(proxy, addr + 2, localApicVersion);
270  checkSum += writeOutField(proxy, addr + 3, cpuFlags);
271  checkSum += writeOutField(proxy, addr + 4, cpuSignature);
272  checkSum += writeOutField(proxy, addr + 8, featureFlags);
273 
274  uint32_t reserved = 0;
275  proxy.writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
276  proxy.writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
277  return 20;
278 }
279 
281  localApicID(p->local_apic_id), localApicVersion(p->local_apic_version),
282  cpuFlags(0), cpuSignature(0), featureFlags(p->feature_flags)
283 {
284  if (p->enable)
285  cpuFlags |= (1 << 0);
286  if (p->bootstrap)
287  cpuFlags |= (1 << 1);
288 
289  replaceBits(cpuSignature, 0, 3, p->stepping);
290  replaceBits(cpuSignature, 4, 7, p->model);
291  replaceBits(cpuSignature, 8, 11, p->family);
292 }
293 
295 X86IntelMPProcessorParams::create()
296 {
297  return new X86ISA::IntelMP::Processor(this);
298 }
299 
300 Addr
302  PortProxy& proxy, Addr addr, uint8_t &checkSum)
303 {
304  BaseConfigEntry::writeOut(proxy, addr, checkSum);
305  checkSum += writeOutField(proxy, addr + 1, busID);
306  checkSum += writeOutString(proxy, addr + 2, busType, 6);
307  return 8;
308 }
309 
311  busID(p->bus_id), busType(p->bus_type)
312 {}
313 
315 X86IntelMPBusParams::create()
316 {
317  return new X86ISA::IntelMP::Bus(this);
318 }
319 
320 Addr
322  PortProxy& proxy, Addr addr, uint8_t &checkSum)
323 {
324  BaseConfigEntry::writeOut(proxy, addr, checkSum);
325  checkSum += writeOutField(proxy, addr + 1, id);
326  checkSum += writeOutField(proxy, addr + 2, version);
327  checkSum += writeOutField(proxy, addr + 3, flags);
328  checkSum += writeOutField(proxy, addr + 4, address);
329  return 8;
330 }
331 
333  id(p->id), version(p->version), flags(0), address(p->address)
334 {
335  if (p->enable)
336  flags |= 1;
337 }
338 
340 X86IntelMPIOAPICParams::create()
341 {
342  return new X86ISA::IntelMP::IOAPIC(this);
343 }
344 
345 Addr
347  PortProxy& proxy, Addr addr, uint8_t &checkSum)
348 {
349  BaseConfigEntry::writeOut(proxy, addr, checkSum);
350  checkSum += writeOutField(proxy, addr + 1, interruptType);
351  checkSum += writeOutField(proxy, addr + 2, flags);
352  checkSum += writeOutField(proxy, addr + 4, sourceBusID);
353  checkSum += writeOutField(proxy, addr + 5, sourceBusIRQ);
354  checkSum += writeOutField(proxy, addr + 6, destApicID);
355  checkSum += writeOutField(proxy, addr + 7, destApicIntIn);
356  return 8;
357 }
358 
360  IntAssignment(p, p->interrupt_type, p->polarity, p->trigger, 3,
361  p->source_bus_id, p->source_bus_irq,
362  p->dest_io_apic_id, p->dest_io_apic_intin)
363 {}
364 
366 X86IntelMPIOIntAssignmentParams::create()
367 {
368  return new X86ISA::IntelMP::IOIntAssignment(this);
369 }
370 
372  IntAssignment(p, p->interrupt_type, p->polarity, p->trigger, 4,
373  p->source_bus_id, p->source_bus_irq,
374  p->dest_local_apic_id, p->dest_local_apic_intin)
375 {}
376 
378 X86IntelMPLocalIntAssignmentParams::create()
379 {
380  return new X86ISA::IntelMP::LocalIntAssignment(this);
381 }
382 
383 Addr
385  PortProxy& proxy, Addr addr, uint8_t &checkSum)
386 {
387  ExtConfigEntry::writeOut(proxy, addr, checkSum);
388  checkSum += writeOutField(proxy, addr + 2, busID);
389  checkSum += writeOutField(proxy, addr + 3, addrType);
390  checkSum += writeOutField(proxy, addr + 4, addr);
391  checkSum += writeOutField(proxy, addr + 12, addrLength);
392  return length;
393 }
394 
396  ExtConfigEntry(p, 128, 20),
397  busID(p->bus_id), addrType(p->address_type),
398  addr(p->address), addrLength(p->length)
399 {}
400 
402 X86IntelMPAddrSpaceMappingParams::create()
403 {
404  return new X86ISA::IntelMP::AddrSpaceMapping(this);
405 }
406 
407 Addr
409  PortProxy& proxy, Addr addr, uint8_t &checkSum)
410 {
411  ExtConfigEntry::writeOut(proxy, addr, checkSum);
412  checkSum += writeOutField(proxy, addr + 2, busID);
413  checkSum += writeOutField(proxy, addr + 3, info);
414  checkSum += writeOutField(proxy, addr + 4, parentBus);
415 
416  uint32_t reserved = 0;
417  proxy.writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
418 
419  return length;
420 }
421 
423  ExtConfigEntry(p, 129, 8),
424  busID(p->bus_id), info(0), parentBus(p->parent_bus)
425 {
426  if (p->subtractive_decode)
427  info |= 1;
428 }
429 
431 X86IntelMPBusHierarchyParams::create()
432 {
433  return new X86ISA::IntelMP::BusHierarchy(this);
434 }
435 
436 Addr
438  PortProxy& proxy, Addr addr, uint8_t &checkSum)
439 {
440  ExtConfigEntry::writeOut(proxy, addr, checkSum);
441  checkSum += writeOutField(proxy, addr + 2, busID);
442  checkSum += writeOutField(proxy, addr + 3, mod);
443  checkSum += writeOutField(proxy, addr + 4, rangeList);
444  return length;
445 }
446 
448  ExtConfigEntry(p, 130, 8),
449  busID(p->bus_id), mod(0), rangeList(p->range_list)
450 {
451  if (p->add)
452  mod |= 1;
453 }
454 
456 X86IntelMPCompatAddrSpaceModParams::create()
457 {
458  return new X86ISA::IntelMP::CompatAddrSpaceMod(this);
459 }
offset
Definition: misc.hh:977
Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:408
X86IntelMPBaseConfigEntryParams Params
Definition: intelmp.hh:120
T htog(T value)
Definition: byteswap.hh:177
Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:321
Bitfield< 7 > i
Definition: miscregs.hh:1378
BaseConfigEntry(Params *p, uint8_t _type)
Definition: intelmp.cc:170
Addr writeOut(PortProxy &proxy, Addr addr)
Definition: intelmp.cc:193
Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:264
ip6_addr_t addr
Definition: inet.hh:335
Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:301
uint8_t writeOutString(PortProxy &proxy, Addr addr, string str, int length)
Definition: intelmp.cc:88
ExtConfigEntry(Params *p, uint8_t _type, uint8_t _length)
Definition: intelmp.cc:185
X86IntelMPFloatingPointerParams Params
Definition: intelmp.hh:91
uint8_t writeOutField(PortProxy &proxy, Addr addr, T val)
Definition: intelmp.cc:74
STL vector class.
Definition: stl.hh:40
Bitfield< 63 > val
Definition: misc.hh:770
#define warn(...)
Definition: misc.hh:219
mod
Definition: types.hh:88
PortProxy Object Declaration.
virtual Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:162
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:145
Addr writeOut(PortProxy &proxy, Addr addr)
Definition: intelmp.cc:111
#define fatal(...)
Definition: misc.hh:163
virtual Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:175
static const char signature[]
Definition: intelmp.hh:98
X86IntelMPExtConfigEntryParams Params
Definition: intelmp.hh:134
Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:437
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:346
X86IntelMPConfigTableParams Params
Definition: intelmp.hh:149
This object is a proxy for a structural port, to be used for debug accesses.
Definition: port_proxy.hh:84
type
Definition: misc.hh:728
Bus(Params *p)
Definition: intelmp.cc:310
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.
Definition: port_proxy.cc:58
uint8_t length
Definition: inet.hh:334
Bitfield< 0 > p
Definition: pagetable.hh:95
Bitfield< 21 > trigger
Definition: intmessage.hh:49
Bitfield< 11 > id
Definition: miscregs.hh:124
Bitfield< 0 > p
static const char signature[]
Definition: intelmp.hh:151
Bitfield< 3 > addr
Definition: types.hh:81
Abstract superclass for simulation objects.
Definition: sim_object.hh:94
Addr writeOut(PortProxy &proxy, Addr addr, uint8_t &checkSum)
Definition: intelmp.cc:384

Generated on Fri Jun 9 2017 13:03:40 for gem5 by doxygen 1.8.6