00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef ZYGOMA_IA32_MPS_H_
00025 #define ZYGOMA_IA32_MPS_H_
00026
00027 #include <arch/apic.h>
00028 #include <config.h>
00029 #include "arch/ioapic.h"
00030 #include <iosfwd>
00031 #include <iterator>
00032 #include <memory.h>
00033 #include <types.h>
00034
00043 namespace Zygoma
00044 {
00045 namespace ia32
00046 {
00050 namespace MPS
00051 {
00052
00053 class ConfigTableHeader;
00054
00066 class FloatingPointer
00067 {
00068 public:
00069 static const int kSIGNATURE_LENGTH = 4;
00070 static const u08 kSIGNATURE[kSIGNATURE_LENGTH];
00071
00072 public:
00073 static const FloatingPointer* kNOT_FOUND;
00074
00075 static const FloatingPointer* locateMPFP();
00076
00082 ConfigTableHeader*
00083 configTableHeader() const
00084 { return reinterpret_cast<ConfigTableHeader*>(m_configTableAddress); }
00085
00093 u08
00094 configType() const
00095 { return m_features[0]; }
00096
00103 bool
00104 imcrIsPresent() const
00105 { return ((m_features[1] & 0x80) != 0); }
00106
00107 private:
00108 u08 m_signature[kSIGNATURE_LENGTH];
00109 u32 m_configTableAddress;
00110 u08 m_length;
00111 u08 m_revision;
00112 u08 m_checksum;
00113 u08 m_features[5];
00114 } ZYGOMA_PACKED;
00115
00116
00117 class ConfigTableEntry;
00118
00127 class ConfigTableIterator
00128 : public std::iterator<std::forward_iterator_tag, const ConfigTableEntry>
00129 {
00130 public:
00131 explicit ConfigTableIterator(ConfigTableHeader*);
00132
00133 reference
00134 operator*() const;
00135
00136 pointer
00137 operator->() const;
00138
00139 ConfigTableIterator&
00140 operator++();
00141
00142 ConfigTableIterator&
00143 operator++(int);
00144
00145 bool
00146 equals(const ConfigTableIterator& rhs) const
00147 { return m_curEntryAddress == rhs.m_curEntryAddress; }
00148
00149 private:
00150 const ConfigTableEntry* m_curEntryAddress;
00151 };
00152
00153
00162 inline bool
00163 operator==(const ConfigTableIterator& lhs, const ConfigTableIterator& rhs)
00164 { return lhs.equals(rhs); }
00165
00166
00172 inline bool
00173 operator!=(const ConfigTableIterator& lhs, const ConfigTableIterator& rhs)
00174 { return !lhs.equals(rhs); }
00175
00176
00186 class ConfigTableHeader
00187 {
00188 static const int kSIGNATURE_LENGTH = 4;
00189 static const int kOEM_ID_LENGTH = 8;
00190 static const int kPRODUCT_ID_LENGTH = 12;
00191 public:
00192 typedef ConfigTableIterator iterator;
00193
00197 LocalApic*
00198 apicAddress() const
00199 { return reinterpret_cast<LocalApic*>(m_apicAddress); }
00200
00205 iterator
00206 begin();
00207
00212 iterator
00213 end();
00214
00216 std::ostream&
00217 printStream(std::ostream& ostr) const;
00218
00219 public:
00220 u08 m_signature[kSIGNATURE_LENGTH];
00221 u16 m_baseTableLength;
00222 u08 m_revision;
00223 u08 m_checksum;
00224 u08 m_oemId[kOEM_ID_LENGTH];
00225 u08 m_productId[kPRODUCT_ID_LENGTH];
00226 u32 m_oemTableAddress;
00227 u16 m_oemTableSize;
00228 u16 m_entryCount;
00229 u32 m_apicAddress;
00230 u16 m_extendedTableLength;
00231 u08 m_extendedTableChecksum;
00232 u08 m_reserved;
00233 } ZYGOMA_PACKED;
00234
00235
00242 inline std::ostream&
00243 operator<<(std::ostream& ostr, const ConfigTableHeader& table)
00244 {
00245 return table.printStream(ostr);
00246 }
00247
00248
00254 class ConfigTableEntry
00255 {
00256 public:
00260 enum EntryType
00261 {
00262 kCONFIG_TABLE_PROCESSOR = 0,
00263 kCONFIG_TABLE_BUS = 1,
00264 kCONFIG_TABLE_IO_APIC = 2,
00265 kCONFIG_TABLE_IO_INTERRUPT = 3,
00266 kCONFIG_TABLE_LOCAL_INTERRUPT = 4,
00267 };
00268
00269 public:
00273 EntryType
00274 entryType() const
00275 {
00276 return static_cast<EntryType>(m_entryType&0xff);
00277 }
00278
00279 private:
00280 u08 m_entryType;
00281 } ZYGOMA_PACKED;
00282
00283
00290 class ProcessorEntry
00291 : public ConfigTableEntry
00292 {
00293 public:
00295 int
00296 id() const
00297 { return m_localApicId & 0xff; }
00298
00300 bool
00301 isEnabled() const
00302 { return m_isEnabled; }
00303
00305 bool
00306 isBootstrapProcessor() const
00307 { return m_isBootstrap; }
00308
00310 int
00311 family() const
00312 { return m_family & 0xff; }
00313
00315 int
00316 model() const
00317 { return m_model & 0xff; }
00318
00320 int
00321 stepping() const
00322 { return m_stepping & 0xff; }
00323
00325 std::ostream&
00326 printStream(std::ostream& ostr) const;
00327
00328 private:
00329 u08 m_localApicId;
00330 u08 m_localApicVersion;
00331 u08 m_isEnabled:1;
00332 u08 m_isBootstrap:1;
00333 u08 m_reserved:2;
00334 u08 m_stepping:4;
00335 u08 m_model:4;
00336 u08 m_family:4;
00337 u32 m_onChipFpu:1;
00338 u32 m_reserved1:6;
00339 u32 m_machineCheckException:1;
00340 u32 m_cmpxchg8b:1;
00341 u32 m_onChipApic:1;
00342 } ZYGOMA_PACKED;
00343
00344
00346 inline std::ostream&
00347 operator<<(std::ostream& ostr, const ProcessorEntry& p)
00348 { return p.printStream(ostr); }
00349
00356 class BusEntry
00357 : public ConfigTableEntry
00358 {
00359 public:
00360 static const int kBUS_TYPE_LENGTH = 4;
00361
00362 public:
00366 int
00367 id() const
00368 { return m_id; }
00369
00370 public:
00371 u08 m_id;
00372 u08 m_type[kBUS_TYPE_LENGTH];
00373 } ZYGOMA_PACKED;
00374
00375
00392 class IOApicEntry
00393 : public ConfigTableEntry
00394 {
00395 public:
00399 int
00400 id() const
00401 { return m_id; }
00402
00406 u08
00407 version() const
00408 { return m_version; }
00409
00413 bool
00414 isEnabled() const
00415 { return m_isUsable; }
00416
00422 IOApic*
00423 address() const
00424 { return reinterpret_cast<IOApic*>(m_address); }
00425
00426 private:
00427 u08 m_id;
00428 u08 m_version;
00429 u08 m_isUsable:1;
00430 u32 m_address;
00431 } ZYGOMA_PACKED;
00432
00433
00441 class IOInterruptEntry
00442 : public ConfigTableEntry
00443 {
00444 public:
00448 enum InterruptType
00449 {
00451 kINTERRUPT_TYPE_INT = 0,
00453 kINTERRUPT_TYPE_NMI = 1,
00455 kINTERRUPT_TYPE_SMI = 2,
00457 kINTERRUPT_EXT_INT = 3
00458 };
00459
00460 enum Polarity
00461 {
00462 kPOLARITY_BUS_SPEC = 0,
00463 kPOLARITY_ACTIVE_HIGH = 1,
00464 kPOLARITY_ACTIVE_LOW = 3
00465 };
00466
00467 enum TriggerMode
00468 {
00469 kTRIGGER_MODE_BUS_SPEC = 0,
00470 kTRIGGER_EDGE_TRIGGERED = 1,
00471 kTRIGGER_LEVEL_TRIGGERED = 3
00472 };
00473
00474 public:
00478 InterruptType
00479 interruptType() const
00480 {
00481 return static_cast<InterruptType>(m_type&0xff);
00482 }
00483
00487 Polarity
00488 polarity() const
00489 {
00490 return static_cast<Polarity>(m_polarity&0xff);
00491 }
00492
00496 TriggerMode
00497 triggerMode() const
00498 {
00499 return static_cast<TriggerMode>(m_triggerMode&0xff);
00500 }
00501
00505 int
00506 sourceBusId() const
00507 { return m_sourceBus & 0xff; }
00508
00512 int
00513 sourceBusIrq() const
00514 { return m_sourceBusIrq & 0xff; }
00515
00521 int
00522 destinationApicId() const
00523 { return m_destinationApicId & 0xff; }
00524
00529 int
00530 destinationApicInt() const
00531 { return m_destinationApicInt & 0xff; }
00532
00533 private:
00534 u08 m_type;
00535 u08 m_polarity:2;
00536 u08 m_triggerMode:2;
00537 u08 m_reserved;
00538 u08 m_sourceBus;
00539 u08 m_sourceBusIrq;
00540 u08 m_destinationApicId;
00541 u08 m_destinationApicInt;
00542 } ZYGOMA_PACKED;
00543
00544
00552 class LocalInterruptEntry
00553 : public ConfigTableEntry
00554 {
00555 public:
00559 enum InterruptType
00560 {
00562 kINTERRUPT_TYPE_INT = 0,
00564 kINTERRUPT_TYPE_NMI = 1,
00566 kINTERRUPT_TYPE_SMI = 2,
00568 kINTERRUPT_EXT_INT = 3
00569 };
00570
00571 enum Polarity
00572 {
00573 kPOLARITY_BUS_SPEC = 0,
00574 kPOLARITY_ACTIVE_HIGH = 1,
00575 kPOLARITY_ACTIVE_LOW = 3
00576 };
00577
00578 enum TriggerMode
00579 {
00580 kTRIGGER_MODE_BUS_SPEC = 0,
00581 kTRIGGER_EDGE_TRIGGERED = 1,
00582 kTRIGGER_LEVEL_TRIGGERED = 3
00583 };
00584
00585 public:
00589 InterruptType
00590 interruptType() const
00591 {
00592 return static_cast<InterruptType>(m_type&0xff);
00593 }
00594
00598 Polarity
00599 polarity() const
00600 {
00601 return static_cast<Polarity>(m_polarity&0xff);
00602 }
00603
00607 TriggerMode
00608 triggerMode() const
00609 {
00610 return static_cast<TriggerMode>(m_triggerMode&0xff);
00611 }
00612
00616 int
00617 sourceBusId()
00618 { return m_sourceBus & 0xff; }
00619
00623 int
00624 sourceBusIrq()
00625 { return m_sourceBusIrq & 0xff; }
00626
00632 int
00633 destinationApicId()
00634 { return m_destinationApicId & 0xff; }
00635
00640 int
00641 destinationApicInt()
00642 { return m_destinationApicInt & 0xff; }
00643
00644 private:
00645 u08 m_type;
00646 u08 m_polarity:2;
00647 u08 m_triggerMode:2;
00648 u08 m_reserved;
00649 u08 m_sourceBus;
00650 u08 m_sourceBusIrq;
00651 u08 m_destinationApicId;
00652 u08 m_destinationApicInt;
00653 } ZYGOMA_PACKED;
00654
00655
00656
00657 }
00658 }
00659 }
00660
00661 #endif // ZYGOMA_IA32_MPS_H_