X86: Add an event for the apic timer timeout. It doesn't get used yet.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:54:19 +0000 (00:54 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:54:19 +0000 (00:54 -0400)
src/arch/x86/miscregfile.cc
src/arch/x86/miscregfile.hh

index 64dac61475e9a28e93fad75f2800d68182fbcf66..f40b1adf523afdef475fc59b96a2ccb57ee11932 100644 (file)
@@ -110,6 +110,16 @@ void MiscRegFile::clear()
     regVal[MISCREG_APIC_DESTINATION_FORMAT] = (MiscReg)(-1);
 }
 
+int divideFromConf(MiscReg conf)
+{
+    // This figures out what division we want from the division configuration
+    // register in the local APIC. The encoding is a little odd but it can
+    // be deciphered fairly easily.
+    int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
+    shift = (shift + 1) % 8;
+    return 1 << shift;
+};
+
 MiscReg MiscRegFile::readRegNoEffect(int miscReg)
 {
     // Make sure we're not dealing with an illegal control register.
@@ -152,11 +162,10 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
             panic("Local APIC Interrupt Command high"
                     " register unimplemented.\n");
             break;
-          case MISCREG_APIC_INITIAL_COUNT:
-            panic("Local APIC Initial Count register unimplemented.\n");
-            break;
           case MISCREG_APIC_CURRENT_COUNT:
-            panic("Local APIC Current Count register unimplemented.\n");
+            return (regVal[miscReg] - tc->getCpuPtr()->curCycle()) /
+                (16 * divideFromConf(
+                    regVal[MISCREG_APIC_DIVIDE_CONFIGURATION]));
             break;
         }
     }
@@ -262,11 +271,16 @@ void MiscRegFile::setReg(int miscReg,
             }
             break;
           case MISCREG_APIC_INITIAL_COUNT:
-            panic("Local APIC Initial Count register unimplemented.\n");
+            newVal = bits(val, 31, 0);
+            regVal[MISCREG_APIC_CURRENT_COUNT] =
+                tc->getCpuPtr()->curCycle() +
+                (16 * divideFromConf(
+                    regVal[MISCREG_APIC_DIVIDE_CONFIGURATION])) * newVal;
+            //FIXME This should schedule the timer event.
             break;
           case MISCREG_APIC_CURRENT_COUNT:
-            panic("Local APIC Current Count register unimplemented.\n");
-            break;
+            //Local APIC Current Count register is read only.
+            return;
           case MISCREG_APIC_DIVIDE_CONFIGURATION:
             newVal = val & 0xB;
             break;
index e095e06e9bfeeae3af7b4b2311bdd9bdb34a9191..3abe4ec58bb00001fdc5846ec29ffa449b0bc15a 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 /*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
  * All rights reserved.
  *
  * Redistribution and use of this software in source and binary forms,
@@ -91,6 +91,8 @@
 #include "arch/x86/faults.hh"
 #include "arch/x86/miscregs.hh"
 #include "arch/x86/types.hh"
+#include "sim/eventq.hh"
+#include "sim/host.hh"
 
 #include <string>
 
@@ -98,6 +100,7 @@ class Checkpoint;
 
 namespace X86ISA
 {
+
     std::string getMiscRegName(RegIndex);
 
     //These will have to be updated in the future.
@@ -109,6 +112,20 @@ namespace X86ISA
       protected:
         MiscReg regVal[NumMiscRegs];
 
+        class ApicTimerEvent : public Event
+        {
+          public:
+            ApicTimerEvent() : Event(&mainEventQueue)
+            {}
+
+            void process()
+            {
+                warn("Local APIC timer event doesn't do anything!\n");
+            }
+        };
+
+        ApicTimerEvent apicTimerEvent;
+
       public:
         void clear();