singrdk/base/Kernel/Singularity.Hal.ApicPC/MpHalClock.cs

143 lines
4.0 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: HalMpClock.cs
//
// Note:
//
// This file is an implementation of Interfaces/Hal/HalClock.csi
//
// For now we just read the time from the HPET or PMTimer. Both of these
// use a spinlock to protect the relevant state. The PMTimer is incredibly
// expensive.
#if !SINGULARITY_MP
#error "This file is only for MP builds."
#endif
namespace Microsoft.Singularity.Hal
{
using Microsoft.Singularity.Hal.Acpi;
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
2008-11-17 18:29:00 -05:00
public class HalClockApic : HalClock
2008-03-05 09:52:00 -05:00
{
Apic apic;
PMClock pmClock;
2008-11-17 18:29:00 -05:00
RTClockApic rtClock;
2008-03-05 09:52:00 -05:00
HpetClock hpetClock;
SpinLock spinLock;
2008-11-17 18:29:00 -05:00
internal HalClockApic(Apic apic, RTClockApic rtClock, PMClock pmClock)
2008-03-05 09:52:00 -05:00
{
this.apic = apic;
this.rtClock = rtClock;
this.pmClock = pmClock;
this.hpetClock = null;
2008-11-17 18:29:00 -05:00
this.spinLock = new SpinLock(SpinLock.Types.MpHalClock);
2008-03-05 09:52:00 -05:00
}
[Conditional("SINGULARITY_MP")]
[NoHeapAllocation]
private void AcquireLock()
{
this.spinLock.Acquire();
}
[Conditional("SINGULARITY_MP")]
[NoHeapAllocation]
private void ReleaseLock()
{
this.spinLock.Release();
}
2008-11-17 18:29:00 -05:00
[NoHeapAllocation][HalLock]
public override long GetKernelTicks()
2008-03-05 09:52:00 -05:00
{
bool en = Processor.DisableInterrupts();
this.AcquireLock();
try {
if (this.hpetClock == null) {
return (long) pmClock.GetKernelTicks();
}
else {
return (long) hpetClock.GetKernelTicks();
}
}
finally {
this.ReleaseLock();
Processor.RestoreInterrupts(en);
}
}
internal byte Interrupt
{
[NoHeapAllocation]
get { return rtClock.Interrupt; }
}
2008-11-17 18:29:00 -05:00
[NoHeapAllocation][HalLock]
public override void ClearInterrupt()
2008-03-05 09:52:00 -05:00
{
bool en = Processor.DisableInterrupts();
this.AcquireLock();
try {
2008-11-17 18:29:00 -05:00
Microsoft.Singularity.Hal.Platform p = Microsoft.Singularity.Hal.Platform.ThePlatform;
2008-03-05 09:52:00 -05:00
if (hpetClock == null) {
pmClock.Update();
}
else {
hpetClock.Update();
}
rtClock.ClearInterrupt();
}
finally {
this.ReleaseLock();
Processor.RestoreInterrupts(en);
}
}
2008-11-17 18:29:00 -05:00
[HalLock]
2008-03-05 09:52:00 -05:00
internal void SwitchToHpetClock(HpetClock hc)
{
// Change rt clock interrupt frequency to appropriate
// rate for HPET main clock.
bool en = Processor.DisableInterrupts();
this.AcquireLock();
try {
rtClock.SetFrequency(HpetClock.UpdateFrequency(hc.Hpet));
hpetClock = hc;
}
finally {
this.ReleaseLock();
Processor.RestoreInterrupts(en);
}
DebugStub.Print("Hal switching to HpetClock.\n");
}
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public override void CpuResumeFromHaltEvent()
2008-03-05 09:52:00 -05:00
{
}
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public override long GetRtcTime()
2008-03-05 09:52:00 -05:00
{
return rtClock.GetBootTime() + GetKernelTicks();
}
2008-11-17 18:29:00 -05:00
public override void SetRtcTime(long newRtcTime)
2008-03-05 09:52:00 -05:00
{
rtClock.SetRtcTime(newRtcTime, GetKernelTicks());
}
}
}