summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2008-06-12 00:54:19 -0400
committerGabe Black <gblack@eecs.umich.edu>2008-06-12 00:54:19 -0400
commit81936ae2ed0368f4687e74374bf32575376bf9df (patch)
tree973bd445d2620c82edeaa44e174d72827b377e94 /src
parent6b8d0363ee271a1b36dd03e3bac5e62efc52aad4 (diff)
downloadgem5-81936ae2ed0368f4687e74374bf32575376bf9df.tar.xz
X86: Add an event for the apic timer timeout. It doesn't get used yet.
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/miscregfile.cc28
-rw-r--r--src/arch/x86/miscregfile.hh19
2 files changed, 39 insertions, 8 deletions
diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc
index 64dac6147..f40b1adf5 100644
--- a/src/arch/x86/miscregfile.cc
+++ b/src/arch/x86/miscregfile.cc
@@ -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;
diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh
index e095e06e9..3abe4ec58 100644
--- a/src/arch/x86/miscregfile.hh
+++ b/src/arch/x86/miscregfile.hh
@@ -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();