2008-03-05 09:52:00 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Microsoft Research Singularity
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
|
|
// File: HalDevices.cs
|
|
|
|
//
|
|
|
|
// Note:
|
|
|
|
//
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
using System.Threading;
|
|
|
|
|
|
|
|
using Microsoft.Singularity;
|
|
|
|
using Microsoft.Singularity.Hal.Acpi;
|
2008-11-17 18:29:00 -05:00
|
|
|
using Microsoft.Singularity.Io;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
namespace Microsoft.Singularity.Hal
|
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
public class HalDevicesLegacyPC : HalDevices
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
private static HalDevicesLegacyPC devices;
|
2008-03-05 09:52:00 -05:00
|
|
|
private static Pic pic;
|
2008-11-17 18:29:00 -05:00
|
|
|
private static Timer8254LegacyPC timer;
|
2008-03-05 09:52:00 -05:00
|
|
|
private static PMTimer pmTimer;
|
2008-11-17 18:29:00 -05:00
|
|
|
private static RTClockLegacyPC clock;
|
|
|
|
private static HalScreenDirect halScreen;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
private static HalMemory halMemory;
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
public static HalDevices Create()
|
|
|
|
{
|
|
|
|
devices = new HalDevicesLegacyPC();
|
|
|
|
|
|
|
|
return devices;
|
|
|
|
}
|
|
|
|
|
2008-03-05 09:52:00 -05:00
|
|
|
[CLSCompliant(false)]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void Initialize(Processor rootProcessor)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
DebugStub.Print("HalDevices.Initialize() - Legacy\n");
|
|
|
|
|
|
|
|
pmTimer = AcpiTables.GetPMTimer();
|
|
|
|
|
|
|
|
// PIC
|
|
|
|
PnpConfig picConfig
|
|
|
|
= (PnpConfig)IoSystem.YieldResources("/pnp/PNP0000", typeof(Pic));
|
|
|
|
pic = new Pic(picConfig);
|
|
|
|
pic.Initialize();
|
|
|
|
|
|
|
|
// Timer
|
|
|
|
PnpConfig timerConfig
|
2008-11-17 18:29:00 -05:00
|
|
|
= (PnpConfig)IoSystem.YieldResources("/pnp/PNP0100", typeof(Timer8254LegacyPC));
|
|
|
|
timer = new Timer8254LegacyPC(timerConfig, pic);
|
2008-03-05 09:52:00 -05:00
|
|
|
byte timerInterrupt = timer.Initialize();
|
|
|
|
|
|
|
|
// Real-time clock
|
|
|
|
PnpConfig clockConfig
|
2008-11-17 18:29:00 -05:00
|
|
|
= (PnpConfig)IoSystem.YieldResources("/pnp/PNP0B00", typeof(RTClockLegacyPC));
|
|
|
|
clock = new RTClockLegacyPC(clockConfig, pic, timer);
|
2008-03-05 09:52:00 -05:00
|
|
|
byte clockInterrupt = clock.Initialize();
|
|
|
|
|
|
|
|
bool noisyTimer = false;
|
|
|
|
if (pmTimer != null) {
|
|
|
|
noisyTimer = CalibrateTimers.Run(pmTimer, timer);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
CalibrateTimers.Run(clock, timer);
|
|
|
|
}
|
|
|
|
|
|
|
|
clock.SetNoisyTimer(noisyTimer);
|
|
|
|
clock.Start();
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
SystemClock.Initialize(clock, TimeSpan.FromHours(8).Ticks);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
rootProcessor.AddPic(pic);
|
|
|
|
rootProcessor.AddTimer(timerInterrupt, timer);
|
|
|
|
rootProcessor.AddClock(clockInterrupt, clock);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
// ----------------------------------------------------------
|
2008-11-17 18:29:00 -05:00
|
|
|
// Add Srat tables to the Processor
|
|
|
|
halMemory = new HalMemorySrat(AcpiTables.GetSrat());
|
|
|
|
Processor.AddMemory(halMemory);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
timer.Start();
|
|
|
|
|
|
|
|
// Get the screen resources. Since we have metadata above to
|
|
|
|
// declare all fixed resources used by the screen,
|
|
|
|
// YieldResources("") will keep the resource tracking correct:
|
2008-11-17 18:29:00 -05:00
|
|
|
|
|
|
|
halScreen = new HalScreenDirect(IoSystem.YieldResources("", typeof(HalScreen)));
|
|
|
|
Console.Screen = (HalScreen)halScreen;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void ReleaseResources()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
clock.ReleaseResources();
|
2008-03-05 09:52:00 -05:00
|
|
|
clock = null;
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
timer.ReleaseResources();
|
2008-03-05 09:52:00 -05:00
|
|
|
timer = null;
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
pic.ReleaseResources();
|
2008-03-05 09:52:00 -05:00
|
|
|
pic = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override byte GetMaximumIrq()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
return pic.MaximumIrq;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Adding and removing interrupts from the Pic.
|
|
|
|
//
|
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void EnableIoInterrupt(byte irq)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
pic.EnableIrq(irq);
|
|
|
|
}
|
|
|
|
|
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void DisableIoInterrupt(byte irq)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
pic.DisableIrq(irq);
|
|
|
|
}
|
|
|
|
|
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override bool InternalInterrupt(byte interrupt)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
// Strictly there are no interrupts internal to
|
|
|
|
// this Hal instance. In practice, some hardware seems
|
|
|
|
// intent on firing an interrupt even if it is masked.
|
|
|
|
//
|
|
|
|
// Return true if interrupt appears to be valid but
|
|
|
|
// is masked, false otherwise.
|
|
|
|
byte irq = pic.InterruptToIrq(interrupt);
|
|
|
|
|
|
|
|
#if DEBUG_SPURIOUS
|
|
|
|
DebugStub.Break();
|
|
|
|
#endif
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
if (pic.IrqMasked(irq) == true) {
|
2008-03-05 09:52:00 -05:00
|
|
|
DebugStub.WriteLine("--- Acked spurious Irq={0:x2}", __arglist(irq));
|
|
|
|
pic.AckIrq(irq);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override int GetProcessorCount()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void StartApProcessors(int cpus)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public override void ResetApProcessors()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void FreezeProcessors()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void SendFixedIPI(byte vector, int from, int to)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void BroadcastFixedIPI(byte vector, bool includeSelf)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
public override byte TranslatePciInterrupt(byte currentInterruptLine,
|
|
|
|
byte pciInterruptPin,
|
|
|
|
PciPort pciPort)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// On a non-ACPI PC, there's nothing to translate;
|
|
|
|
// just return the current interrupt line.
|
|
|
|
//
|
|
|
|
return currentInterruptLine;
|
|
|
|
}
|
|
|
|
|
2008-03-05 09:52:00 -05:00
|
|
|
[CLSCompliant(false)]
|
|
|
|
[NoHeapAllocation]
|
2008-11-17 18:29:00 -05:00
|
|
|
public override void ClearFixedIPI(int interrupt)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|