Cosmos/source/Cosmos.HAL2/PCI.cs
Valentin Charbonnier c75cdffbb4 Ata boot fix.
2017-10-10 21:40:11 +02:00

110 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cosmos.Debug.Kernel;
namespace Cosmos.HAL
{
public class PCI
{
private static List<PCIDevice> Devices;
public static uint Count
{
get { return (uint)Devices.Count; }
}
public static void Setup()
{
Devices = new List<PCIDevice>();
if ((PCIDevice.GetHeaderType(0x0, 0x0, 0x0) & 0x80) == 0)
{
CheckBus(0x0);
}
else
{
for (ushort fn = 0; fn < 8; fn++)
{
if (PCIDevice.GetVendorID(0x0, 0x0, fn) != 0xFFFF)
break;
CheckBus(fn);
}
}
foreach (PCIDevice device in Devices)
{
if (device.ClassCode == 0x01 && device.Subclass == 0x06 && device.ProgIF == 0x01)
{
//Serial ATA (AHCI 1.0)
Global.atamode = 1;
}
else if (device.ClassCode == 0x01 && device.Subclass == 0x04 && device.ProgIF == 0x00)
{
//RAID Controller
Global.atamode = 2;
}
else if (device.ClassCode == 0x01 && device.Subclass == 0x01)
{
//IDE Controller
Global.atamode = 3;
}
}
}
private static void CheckBus(ushort xBus)
{
for (ushort device = 0; device < 32; device++)
{
if (PCIDevice.GetVendorID(xBus, device, 0x0) == 0xFFFF)
continue;
CheckFunction(new PCIDevice(xBus, device, 0x0));
if ((PCIDevice.GetHeaderType(xBus, device, 0x0) & 0x80) != 0)
{
for (ushort fn = 1; fn < 8; fn++)
{
if (PCIDevice.GetVendorID(xBus, device, fn) != 0xFFFF)
CheckFunction(new PCIDevice(xBus, device, fn));
}
}
}
}
private static void CheckFunction(PCIDevice xPCIDevice)
{
Devices.Add(xPCIDevice);
if (xPCIDevice.ClassCode == 0x6 && xPCIDevice.Subclass == 0x4)
CheckBus(xPCIDevice.SecondaryBusNumber);
}
public static PCIDevice GetDevice(ushort VendorID, ushort DeviceID)
{
for (int i = 0; i < Devices.Count; i++)
{
var xDevice = Devices[i];
if (xDevice.VendorID == VendorID && xDevice.DeviceID == DeviceID)
{
return Devices[i];
}
}
return null;
}
public static PCIDevice GetDeviceClass(ushort Class, ushort SubClass)
{
for (int i = 0; i < Devices.Count; i++)
{
var xDevice = Devices[i];
if (xDevice.ClassCode == Class && xDevice.Subclass == SubClass)
{
return Devices[i];
}
}
return null;
}
}
}