X86: Make APICs communicate through the memory system.
[gem5.git] / src / arch / x86 / x86_traits.hh
index 9ea8eaef4d120afb5f9abdc7b03b7340f39508d9..be7572517ef2cc2489486cb913a6fbccd0b1093e 100644 (file)
 #ifndef __ARCH_X86_X86TRAITS_HH__
 #define __ARCH_X86_X86TRAITS_HH__
 
+#include <assert.h>
+
+#include "sim/host.hh"
+
 namespace X86ISA
 {
     const int NumMicroIntRegs = 16;
 
     const int NumPseudoIntRegs = 1;
     //1. The condition code bits of the rflags register.
-    const int NumImplicitIntRegs = 4;
+    const int NumImplicitIntRegs = 5;
     //1. The lower part of the result of multiplication.
     //2. The upper part of the result of multiplication.
     //3. The quotient from division
     //4. The remainder from division
+    //5. The divisor for division
 
     const int NumMMXRegs = 8;
     const int NumXMMRegs = 16;
@@ -79,6 +84,45 @@ namespace X86ISA
 
     const int NumSegments = 6;
     const int NumSysSegments = 4;
+
+    const Addr IntAddrPrefixMask = ULL(0xffffffff00000000);
+    const Addr IntAddrPrefixCPUID = ULL(0x100000000);
+    const Addr IntAddrPrefixMSR = ULL(0x200000000);
+    const Addr IntAddrPrefixIO = ULL(0x300000000);
+
+    const Addr PhysAddrPrefixIO = ULL(0x8000000000000000);
+    const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000);
+    const Addr PhysAddrPrefixLocalAPIC = ULL(0xA000000000000000);
+    const Addr PhysAddrPrefixInterrupts = ULL(0x2000000000000000);
+    // Each APIC gets two pages. One page is used for local apics to field
+    // accesses from the CPU, and the other is for all APICs to communicate.
+    const Addr PhysAddrAPICRangeSize = 1 << 12;
+
+    static inline Addr
+    x86IOAddress(const uint32_t port)
+    {
+        return PhysAddrPrefixIO | port;
+    }
+
+    static inline Addr
+    x86PciConfigAddress(const uint32_t addr)
+    {
+        return PhysAddrPrefixPciConfig | addr;
+    }
+
+    static inline Addr
+    x86LocalAPICAddress(const uint8_t id, const uint16_t addr)
+    {
+        assert(addr < (1 << 12));
+        return PhysAddrPrefixLocalAPIC | (id * (1 << 12)) | addr;
+    }
+
+    static inline Addr
+    x86InterruptAddress(const uint8_t id, const uint16_t addr)
+    {
+        assert(addr < PhysAddrAPICRangeSize);
+        return PhysAddrPrefixInterrupts | (id * PhysAddrAPICRangeSize) | addr;
+    }
 }
 
 #endif //__ARCH_X86_X86TRAITS_HH__