singrdk/base/Kernel/Singularity.Hal.Common/HalDevicesFactory.cs

90 lines
3.1 KiB
C#
Raw Normal View History

2008-11-17 18:29:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: HalDevicesFactory.cs
//
// Constructs the correct HAL implementation based on system configuation.
//
using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.Singularity;
using Microsoft.Singularity.Hal;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Isal;
namespace Microsoft.Singularity.Hal
{
[CLSCompliant(false)]
public sealed class HalDevicesFactory
{
public static HalDevices devices = null;
public static bool apic = false; // True if APIC is present
public static object Initialize(Processor processor)
{
if (processor.Id == 0) {
// We have hardware PICS, determine which kind
//
// Detect if an APIC is present on the CPU
//
// From 8.4.2 Presence of the Local APIC on page 337 of the
// Intel 64 and IA-32 Architectures Software Developers Manual
//
// function (1) -> eax
// cpuid
// eax -> p0
// ebx -> p1
// ecx -> p2
// edx -> p3 Bit 9 set if APIC present
//
//
// Note: It has been noted that some older motherboards
// may have an APIC capable processor, but a chipset
// that does not properly support the APIC interrupt
// protocol. These motherboards will remove the APIC
// hardware tables from the ACPI tables as an indication
// that the APIC present on the processor should not
// be used. Of course these are uni-processor only
// motherboards without hyperthreading or multiple-cores.
//
uint p0, p1, p2, p3;
Isa.ReadCpuid((uint)1, out p0, out p1, out p2, out p3);
if (((p3 >> 9) & 0x1) != 0) {
apic = true;
DebugStub.Print("HalDevices: CPUID says APIC present\n");
}
else {
apic = false;
DebugStub.Print("HalDevices: CPUID says APIC NOT present\n");
}
// Dynamically select the proper hardware support drivers
if (apic) {
devices = HalDevicesApic.Create();
}
else {
devices = HalDevicesLegacyPC.Create();
}
}
// This happens for all processors
devices.Initialize(processor);
return devices;
}
}
}