diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2008-06-12 00:54:19 -0400 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2008-06-12 00:54:19 -0400 |
commit | 81936ae2ed0368f4687e74374bf32575376bf9df (patch) | |
tree | 973bd445d2620c82edeaa44e174d72827b377e94 /src | |
parent | 6b8d0363ee271a1b36dd03e3bac5e62efc52aad4 (diff) | |
download | gem5-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.cc | 28 | ||||
-rw-r--r-- | src/arch/x86/miscregfile.hh | 19 |
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(); |