From 74720b3be0ce6bac77f01b618d49e442a4fa745f Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 8 Sep 2017 00:06:29 -0700 Subject: [PATCH 01/85] [AHCI] Supporting AHCI Controller --- source/Cosmos.HAL2/PCI.cs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/PCI.cs b/source/Cosmos.HAL2/PCI.cs index 200b3a09a..f90a816d6 100644 --- a/source/Cosmos.HAL2/PCI.cs +++ b/source/Cosmos.HAL2/PCI.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -18,6 +18,7 @@ namespace Cosmos.HAL public static void Setup() { Devices = new List(); + if ((PCIDevice.GetHeaderType(0x0, 0x0, 0x0) & 0x80) == 0) { CheckBus(0x0); @@ -32,6 +33,26 @@ namespace Cosmos.HAL CheckBus(fn); } } + + foreach (PCIDevice device in Devices) + { + + if (device.ClassCode == 0x01 && device.Subclass == 0x06 && device.ProgIF == 0x01) + { + //Serial ATA (AHCI 1.0) + Global.SATAMode = Global.SATAControllerMode.AHCI; + } + else if (device.ClassCode == 0x01 && device.Subclass == 0x04 && device.ProgIF == 0x00) + { + //RAID Controller + Global.SATAMode = Global.SATAControllerMode.RAID; + } + else if (device.ClassCode == 0x01 && device.Subclass == 0x01) + { + //IDE Controller + Global.SATAMode = Global.SATAControllerMode.IDE; + } + } } private static void CheckBus(ushort xBus) @@ -88,3 +109,4 @@ namespace Cosmos.HAL } } } + From 6d960bd9556b00a3fdf18ce8e12f6b213f704ac6 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 8 Sep 2017 00:13:54 -0700 Subject: [PATCH 02/85] Move IDE to a new Location --- source/Cosmos.HAL2/Drivers/Controllers/IDE.cs | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 source/Cosmos.HAL2/Drivers/Controllers/IDE.cs diff --git a/source/Cosmos.HAL2/Drivers/Controllers/IDE.cs b/source/Cosmos.HAL2/Drivers/Controllers/IDE.cs new file mode 100644 index 000000000..f5670029e --- /dev/null +++ b/source/Cosmos.HAL2/Drivers/Controllers/IDE.cs @@ -0,0 +1,65 @@ +using System; +using Cosmos.HAL.BlockDevice; + +namespace Cosmos.HAL.Drivers.PCI.SATA +{ + public class IDE + { + public static void InitAta(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) + { + var xIO = aControllerID == Ata.ControllerIdEnum.Primary ? Core.Global.BaseIOGroups.ATA1 : Core.Global.BaseIOGroups.ATA2; + var xATA = new AtaPio(xIO, aControllerID, aBusPosition); + if (xATA.DriveType == AtaPio.SpecLevel.Null) + { + return; + } + if (xATA.DriveType == AtaPio.SpecLevel.ATA) + { + BlockDevice.BlockDevice.Devices.Add(xATA); + Ata.AtaDebugger.Send("ATA device with speclevel ATA found."); + } + else + { + //Ata.AtaDebugger.Send("ATA device with spec level " + (int)xATA.DriveType + + // " found, which is not supported!"); + return; + } + var xMbrData = new byte[512]; + xATA.ReadBlock(0UL, 1U, xMbrData); + var xMBR = new MBR(xMbrData); + + if (xMBR.EBRLocation != 0) + { + //EBR Detected + var xEbrData = new byte[512]; + xATA.ReadBlock(xMBR.EBRLocation, 1U, xEbrData); + var xEBR = new EBR(xEbrData); + + for (int i = 0; i < xEBR.Partitions.Count; i++) + { + //var xPart = xEBR.Partitions[i]; + //var xPartDevice = new BlockDevice.Partition(xATA, xPart.StartSector, xPart.SectorCount); + //BlockDevice.BlockDevice.Devices.Add(xPartDevice); + } + } + + // TODO Change this to foreach when foreach is supported + Ata.AtaDebugger.Send("Number of MBR partitions found:"); + Ata.AtaDebugger.SendNumber(xMBR.Partitions.Count); + for (int i = 0; i < xMBR.Partitions.Count; i++) + { + var xPart = xMBR.Partitions[i]; + if (xPart == null) + { + Console.WriteLine("Null partition found at idx: " + i); + } + else + { + var xPartDevice = new Partition(xATA, xPart.StartSector, xPart.SectorCount); + BlockDevice.BlockDevice.Devices.Add(xPartDevice); + Console.WriteLine("Found partition at idx" + i); + } + } + } + } +} From 10e6225f607b96649c12096eb47ee677dbbfdaea Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 8 Sep 2017 01:12:36 -0700 Subject: [PATCH 03/85] Create the AHCI Controller Class --- .../Cosmos.HAL2/Drivers/Controllers/AHCI.cs | 389 ++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 source/Cosmos.HAL2/Drivers/Controllers/AHCI.cs diff --git a/source/Cosmos.HAL2/Drivers/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/Controllers/AHCI.cs new file mode 100644 index 000000000..a5f7ba47a --- /dev/null +++ b/source/Cosmos.HAL2/Drivers/Controllers/AHCI.cs @@ -0,0 +1,389 @@ +using System; +using Cosmos.Core; +using Cosmos.Debug.Kernel; + +namespace Cosmos.HAL.Drivers.PCI.SATA +{ + public struct GenericRegisters + { + public uint CAP; + public uint GHC; + public uint IS; + public uint PI; + public uint VS; + public uint CCC_CTL; + public uint CCC_PORTS; + public uint EM_LOC; + public uint EM_CTL; + public uint CAP2; + public uint BOHC; + public byte[] Reserved0; + public byte[] VendorSpecific; + public PortRegisters[] Ports; + } + + public struct PortRegisters + { + public uint CLB; + public uint CLBU; + public uint FB; + public uint FBU; + public uint IS; + public uint IE; + public uint CMD; + public uint Reserved0; + public uint TFD; + public uint SIG; + public uint SSTS; + public uint SCTL; + public uint SERR; + public uint SACT; + public uint CI; + public uint SNTF; + public uint FBS; + public uint[] Reserved1; + public uint[] VendorSpecific; + } + + public enum FISType + { + FIS_Type_RegisterH2D = 0x27, // Register FIS: Host to Device + FIS_Type_RegisterD2H = 0x34, // Register FIS: Device to Host + FIS_Type_DMA_Activate = 0x39, // DMA Activate + FIS_Type_DMA_Setup = 0x41, // DMA Setup: Device to Host + FIS_Type_Data = 0x46, // Data FIS: Bidirectional + FIS_Type_BIST = 0x58, // BIST + FIS_Type_PIO_Setup = 0x5F, // PIO Setup: Device to Host + FIS_Type_DeviceBits = 0xA1 // Device bits + } + + public enum PortType + { + Nothing = 0x00, + SATA = 0x01, + SATAPI = 0x02, + SEMB = 0x03, + PM = 0x04 + } + + //public struct FIS_REG_H2D + //{ + // public byte FISType; + // + // public byte Options; + // // Reserved + // //public byte CMDCTRL; + // public byte Command; + // public byte FeatureL; + // + // public byte LBA0; + // public byte LBA1; + // public byte LBA2; + // public byte Device; + // + // public byte LBA3; + // public byte LBA4; + // public byte LBA5; + // public byte FeatureH; + // + // public byte CountL; + // public byte CountH; + // public byte ICC; + // public byte Control; + // + // public byte Res2; + //} + + //public struct FIS_REG_D2H { + // public byte FISType; + // + // public byte Options; + // // Reserved + // //public byte InterruptBit; + // // Rseerved + // public byte Status; + // public byte Error; + // + // public byte LBA0; + // public byte LBA1; + // public byte LBA2; + // public byte Device; + // + // public byte LBA3; + // public byte LBA4; + // public byte LBA5; + // // Reserved + // + // public byte CountL; + // public byte CountH; + // public byte ICC; + // public ushort Res2; + // // Reserved + // public uint Res3; + // // Reserved + //} + + //public struct FIS_DATA { + // public byte FISType; + // + // public byte Options; + // // Reserved + // + // // Reserved + // public byte Payload; + //} + + // Unused + //public struct PIO_SETUP { + //public byte FISType; + // + //public byte Options; + //// Reserved + //public byte DataTransferDirection; + //public byte InterruptBit; + //// Reserved + // + //public byte Status; + //public byte Error; + // + //public byte LBA0; + //public byte LBA1; + //public byte LBA2; + //public byte Device; + // + //public byte LBA3; + //public byte LBA4; + //public byte LBA5; + //// Reserved + // + //public byte CountL; + //public byte CountH; + //// Reserved + //public byte NewStatus; + // + //public byte TransferCount; // System.int16 = WORD! + //// Reserved + //} + + //public struct DMA_SETUP { + //public byte FISType; + // + //public byte PortMultiplier; + //// Reserved + //public byte DataTransferDirection; + //public byte InterruptBit; + //public byte AutoActivate; // Specifies if DMA Activate FIS is needed + // + //// Reserved + // + //public byte DMABufferIdentifier; // System.int64 = QWORD! + // + //// Reserved + // + //public byte DMABufferOffset; // System.int32 = DWORD! + // + //public byte TransferCount; // System.int32 = DWORD! + // + //// Reserved + //} + + public class AHCI + { + public const uint SSTS_ADDRESS = 0x00000133; + public const uint SATA_SIG_ATA = 0x00000101; // SATA drive + public const uint SATA_SIG_ATAPI = 0xEB140101; // SATAPI drive + public const uint SATA_SIG_SEMB = 0xC33C0101; // Enclosure management bridge + public const uint SATA_SIG_PM = 0x96690101; // Port multiplier + public const uint PORT_DET_PRESENT = 0x00000003; + public const uint PORT_IPM_ACTIVE = 0x00000001; + public static uint PortLocation; + + public static PCIDevice mAHCIDevice = HAL.PCI.GetDeviceClass(0x01, 0x06); + public static uint BAR5 = mAHCIDevice.BaseAddressBar[5].BaseAddress; + public static MemoryBlock mAHCIMemory = new MemoryBlock(BAR5, 0x10FF); + public static MemoryBlock mAHCIPortMemory = new MemoryBlock(BAR5 + PortLocation, 0x10FF); + internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); + + internal class PortHelper + { + public static PortRegisters GetPort(int aPortNumber) + { + PortLocation = (uint)(aPortNumber); + if (aPortNumber == 00) PortLocation = 0x0100; + else if (aPortNumber == 01) PortLocation = 0x0180; + else if (aPortNumber == 02) PortLocation = 0x0200; + else if (aPortNumber == 03) PortLocation = 0x0280; + else if (aPortNumber == 04) PortLocation = 0x0300; + else if (aPortNumber == 05) PortLocation = 0x0380; + else if (aPortNumber == 06) PortLocation = 0x0400; + else if (aPortNumber == 07) PortLocation = 0x0480; + else if (aPortNumber == 08) PortLocation = 0x0500; + else if (aPortNumber == 09) PortLocation = 0x0580; + else if (aPortNumber == 10) PortLocation = 0x0600; + else if (aPortNumber == 11) PortLocation = 0x0680; + else if (aPortNumber == 12) PortLocation = 0x0700; + else if (aPortNumber == 13) PortLocation = 0x0780; + else if (aPortNumber == 14) PortLocation = 0x0800; + else if (aPortNumber == 15) PortLocation = 0x0880; + else if (aPortNumber == 16) PortLocation = 0x0900; + else if (aPortNumber == 17) PortLocation = 0x0980; + else if (aPortNumber == 18) PortLocation = 0x0A00; + else if (aPortNumber == 19) PortLocation = 0x0A80; + else if (aPortNumber == 20) PortLocation = 0x0B00; + else if (aPortNumber == 21) PortLocation = 0x0B80; + else if (aPortNumber == 22) PortLocation = 0x0C00; + else if (aPortNumber == 23) PortLocation = 0x0C80; + else if (aPortNumber == 24) PortLocation = 0x0D00; + else if (aPortNumber == 25) PortLocation = 0x0D80; + else if (aPortNumber == 26) PortLocation = 0x0E00; + else if (aPortNumber == 27) PortLocation = 0x0E80; + else if (aPortNumber == 28) PortLocation = 0x0F00; + else if (aPortNumber == 29) PortLocation = 0x0F80; + else if (aPortNumber == 30) PortLocation = 0x1000; + else if (aPortNumber == 31) PortLocation = 0x1080; + PortRegisters Port = new PortRegisters() + { + CLB = mAHCIPortMemory[0x00], + CLBU = mAHCIPortMemory[0x04], + FB = mAHCIPortMemory[0x08], + FBU = mAHCIPortMemory[0x0C], + IS = mAHCIPortMemory[0x10], + IE = mAHCIPortMemory[0x14], + CMD = mAHCIPortMemory[0x18], + Reserved0 = mAHCIPortMemory[0x1C], + TFD = mAHCIPortMemory[0x20], + SIG = mAHCIPortMemory[0x24], + SSTS = mAHCIPortMemory[0x28], + SCTL = mAHCIPortMemory[0x2C], + SERR = mAHCIPortMemory[0x30], + SACT = mAHCIPortMemory[0x34], + CI = mAHCIPortMemory[0x38], + SNTF = mAHCIPortMemory[0x3C], + FBS = mAHCIPortMemory[0x40], + Reserved1 = GetValueArray(0x44, 11), + VendorSpecific = GetValueArray(0x70, 4) + }; + return Port; + } + public static uint[] GetValueArray(uint aStartAddress, int aAmount) + { + uint[] FinishedArray = new uint[aAmount]; + + for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) + { + for (int i = 0; i < aAmount; i++) + { + FinishedArray[i] = mAHCIPortMemory[ui]; + } + } + return FinishedArray; + } + public static byte[] GetByteValueArray(uint aStartAddress, int aAmount) + { + byte[] FinishedArray = new byte[aAmount]; + + for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) + { + for (int i = 0; i < aAmount; i++) + { + FinishedArray[i] = mAHCIPortMemory.Bytes[ui]; + } + } + return FinishedArray; + } + } + + private void SearchForDisks(GenericRegisters aGeneric) + { + // Search for disks + var xImplementedPort = aGeneric.PI; + var xPort = 0; + var xSupportedPorts = 0x1F; + while (xPort <= xSupportedPorts) + { + if (xImplementedPort != 0) + { + PortType dt = CheckPortType(PortHelper.GetPort(xPort)); + var xPortString = "0:" + xPort; + if (dt == PortType.SATA) // If Port Type was SATA. + { + mAHCIDebugger.Send("SATA drive found at port " + xPortString); + Console.WriteLine("SATA Drive found at port " + xPortString); + } + else if (dt == PortType.SATAPI) // If Port Type was SATAPI. + { + mAHCIDebugger.Send("SATAPI drive found at port " + xPortString); + Console.WriteLine("CD/DVD Drive found at port " + xPortString); + } + else if (dt == PortType.SEMB) // If Port Type was SEMB. + { + mAHCIDebugger.Send("SEMB drive found at port " + xPortString); + Console.WriteLine("SEMB Drive found at port " + xPortString); + } + else if (dt == PortType.PM) // If Port Type was Port Mulitplier. + { + mAHCIDebugger.Send("Port Multiplier drive found at port " + xPortString); + Console.WriteLine("Port Multiplier Drive found at port " + xPortString); + } + else if (dt == PortType.Nothing) // If Nothing in this Port. + mAHCIDebugger.Send("No drive found at port " + xPortString); + else // If Implemented Port value was not zero and not one of the above. + mAHCIDebugger.Send("Unknown drive found at port " + xPortString); + } + xPort++; + xImplementedPort >>= 1; + } + } + + private PortType CheckPortType(PortRegisters Port) + { + uint Signature = Port.SIG; + uint SATAStatus = Port.SSTS; + + var xIPM = (byte)((SATAStatus >> 8) & 0x0F); + var xDET = (byte)(SATAStatus & 0x0F); + mAHCIDebugger.SendNumber(xIPM); + mAHCIDebugger.SendNumber(xDET); + + if (xIPM != PORT_IPM_ACTIVE) + return PortType.Nothing; + if (xDET != PORT_DET_PRESENT) + return PortType.Nothing; + + switch (Signature) + { + case SATA_SIG_ATAPI: + return PortType.SATAPI; + case SATA_SIG_SEMB: + return PortType.SEMB; + case SATA_SIG_PM: + return PortType.PM; + default: + return PortType.SATA; + } + } + + public static void InitSATA() + { + GenericRegisters mGeneric = new GenericRegisters() + { + CAP = mAHCIMemory[0x00], + GHC = mAHCIMemory[0x04], + IS = mAHCIMemory[0x08], + PI = mAHCIMemory[0x0C], + VS = mAHCIMemory[0x10], + CCC_CTL = mAHCIMemory[0x14], + CCC_PORTS = mAHCIMemory[0x18], + EM_LOC = mAHCIMemory[0x1C], + EM_CTL = mAHCIMemory[0x20], + CAP2 = mAHCIMemory[0x24], + BOHC = mAHCIMemory[0x28], + Reserved0 = PortHelper.GetByteValueArray(0x2C, 29), + VendorSpecific = PortHelper.GetByteValueArray(0xA0, 20), + Ports = new PortRegisters[32] + }; + var xSelf = new AHCI(); + xSelf.SearchForDisks(mGeneric); + } + } +} From 7df899b49b41150da4787e433b8d2b38fc00fd2a Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 8 Sep 2017 01:59:31 -0700 Subject: [PATCH 04/85] Rename source/Cosmos.HAL2/Drivers/Controllers/IDE.cs to source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs --- source/Cosmos.HAL2/Drivers/{ => PCI}/Controllers/IDE.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/Drivers/{ => PCI}/Controllers/IDE.cs (100%) diff --git a/source/Cosmos.HAL2/Drivers/Controllers/IDE.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs similarity index 100% rename from source/Cosmos.HAL2/Drivers/Controllers/IDE.cs rename to source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs From 55534cc5bdffc410eef19e0d580de845305dddde Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 8 Sep 2017 02:00:06 -0700 Subject: [PATCH 05/85] Rename source/Cosmos.HAL2/Drivers/Controllers/AHCI.cs to source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs --- source/Cosmos.HAL2/Drivers/{ => PCI}/Controllers/AHCI.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/Drivers/{ => PCI}/Controllers/AHCI.cs (100%) diff --git a/source/Cosmos.HAL2/Drivers/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs similarity index 100% rename from source/Cosmos.HAL2/Drivers/Controllers/AHCI.cs rename to source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs From 82fc36b523511defdd20e1751776fdee3bd80423 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 8 Sep 2017 02:01:41 -0700 Subject: [PATCH 06/85] Update Global Class for AHCI Support --- source/Cosmos.HAL2/Global.cs | 103 +++++++++++------------------------ 1 file changed, 31 insertions(+), 72 deletions(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index d09b92700..31b97d6e2 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -1,5 +1,5 @@ -using System; - +using System; +using Cosmos.HAL.Drivers.PCI.SATA; using Cosmos.Core; using Cosmos.Debug.Kernel; using Cosmos.HAL.BlockDevice; @@ -15,6 +15,13 @@ namespace Cosmos.HAL public static TextScreenBase TextScreen = new TextScreen(); public static PCI Pci; + public static SATAControllerMode SATAMode; + public enum SATAControllerMode + { + AHCI, + RAID, + IDE, + }; static public void Init(TextScreenBase textScreen) { @@ -35,6 +42,7 @@ namespace Cosmos.HAL //TODO: Since this is FCL, its "common". Otherwise it should be // system level and not accessible from Core. Need to think about this // for the future. + Console.Clear(); Console.WriteLine("Finding PCI Devices"); mDebugger.Send("PCI Devices"); @@ -46,16 +54,27 @@ namespace Cosmos.HAL mDebugger.Send("Done initializing Cosmos.HAL.Global"); - mDebugger.Send("ATA Primary Master"); - InitAta(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); - - //TODO Need to change code to detect if ATA controllers are present or not. How to do this? via PCI enum? - // They do show up in PCI space as well as the fixed space. - // Or is it always here, and was our compiler stack corruption issue? - mDebugger.Send("ATA Secondary Master"); - InitAta(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); - //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); - + switch(SATAMode) // Detect what SATA Controller Mode is in: + { + case SATAControllerMode.AHCI: // SATA-native (AHCI) Mode + mDebugger.Send("AHCI Controller Detected, Initializing"); + AHCI.InitSATA(); + break; + case SATAControllerMode.RAID: // RAID Mode + // TODO: Initialize Raid Driver here + break; + case SATAControllerMode.IDE: // IDE Mode + mDebugger.Send("ATA Primary Master"); + IDE.InitAta(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); + + //TODO Need to change code to detect if ATA controllers are present or not. How to do this? via PCI enum? + // They do show up in PCI space as well as the fixed space. + // Or is it always here, and was our compiler stack corruption issue? + mDebugger.Send("ATA Secondary Master"); + IDE.InitAta(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); + //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); + break; + } } public static void EnableInterrupts() @@ -63,66 +82,6 @@ namespace Cosmos.HAL CPU.EnableInterrupts(); } - private static void InitAta(Ata.ControllerIdEnum aControllerID, - Ata.BusPositionEnum aBusPosition) - { - var xIO = aControllerID == Ata.ControllerIdEnum.Primary - ? Core.Global.BaseIOGroups.ATA1 - : Core.Global.BaseIOGroups.ATA2; - var xATA = new AtaPio(xIO, aControllerID, aBusPosition); - if (xATA.DriveType == AtaPio.SpecLevel.Null) - { - return; - } - if (xATA.DriveType == AtaPio.SpecLevel.ATA) - { - BlockDevice.BlockDevice.Devices.Add(xATA); - Ata.AtaDebugger.Send("ATA device with speclevel ATA found."); - } - else - { - //Ata.AtaDebugger.Send("ATA device with spec level " + (int)xATA.DriveType + - // " found, which is not supported!"); - return; - } - var xMbrData = new byte[512]; - xATA.ReadBlock(0UL, 1U, xMbrData); - var xMBR = new MBR(xMbrData); - - if (xMBR.EBRLocation != 0) - { - //EBR Detected - var xEbrData = new byte[512]; - xATA.ReadBlock(xMBR.EBRLocation, 1U, xEbrData); - var xEBR = new EBR(xEbrData); - - for (int i = 0; i < xEBR.Partitions.Count; i++) - { - //var xPart = xEBR.Partitions[i]; - //var xPartDevice = new BlockDevice.Partition(xATA, xPart.StartSector, xPart.SectorCount); - //BlockDevice.BlockDevice.Devices.Add(xPartDevice); - } - } - - // TODO Change this to foreach when foreach is supported - Ata.AtaDebugger.Send("Number of MBR partitions found:"); - Ata.AtaDebugger.SendNumber(xMBR.Partitions.Count); - for (int i = 0; i < xMBR.Partitions.Count; i++) - { - var xPart = xMBR.Partitions[i]; - if (xPart == null) - { - Console.WriteLine("Null partition found at idx: " + i); - } - else - { - var xPartDevice = new Partition(xATA, xPart.StartSector, xPart.SectorCount); - BlockDevice.BlockDevice.Devices.Add(xPartDevice); - Console.WriteLine("Found partition at idx" + i); - } - } - } - public static bool InterruptsEnabled => CPU.mInterruptsEnabled; } } From 538f3e3c77ae872968abba4020bb8b12d7268abc Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 8 Sep 2017 02:19:02 -0700 Subject: [PATCH 07/85] Update Global.cs --- source/Cosmos.HAL2/Global.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 31b97d6e2..9fddc667c 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -67,9 +67,6 @@ namespace Cosmos.HAL mDebugger.Send("ATA Primary Master"); IDE.InitAta(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); - //TODO Need to change code to detect if ATA controllers are present or not. How to do this? via PCI enum? - // They do show up in PCI space as well as the fixed space. - // Or is it always here, and was our compiler stack corruption issue? mDebugger.Send("ATA Secondary Master"); IDE.InitAta(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); From ee2ddf33ce8e6116edbbd19ccb336f583e150495 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 10 Sep 2017 06:20:30 -0700 Subject: [PATCH 08/85] [AHCI] Read sector, Stop & Start Command, Port Rebase --- .../Drivers/PCI/Controllers/AHCI.cs | 572 ++++++++++++++---- 1 file changed, 453 insertions(+), 119 deletions(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs index a5f7ba47a..e3d1f2994 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs @@ -47,14 +47,61 @@ namespace Cosmos.HAL.Drivers.PCI.SATA public enum FISType { - FIS_Type_RegisterH2D = 0x27, // Register FIS: Host to Device - FIS_Type_RegisterD2H = 0x34, // Register FIS: Device to Host + FIS_Type_RegisterH2D = 0x27, // Register FIS: Host to Device + FIS_Type_RegisterD2H = 0x34, // Register FIS: Device to Host FIS_Type_DMA_Activate = 0x39, // DMA Activate - FIS_Type_DMA_Setup = 0x41, // DMA Setup: Device to Host - FIS_Type_Data = 0x46, // Data FIS: Bidirectional - FIS_Type_BIST = 0x58, // BIST - FIS_Type_PIO_Setup = 0x5F, // PIO Setup: Device to Host - FIS_Type_DeviceBits = 0xA1 // Device bits + FIS_Type_DMA_Setup = 0x41, // DMA Setup: Device to Host + FIS_Type_Data = 0x46, // Data FIS: Bidirectional + FIS_Type_BIST = 0x58, // BIST + FIS_Type_PIO_Setup = 0x5F, // PIO Setup: Device to Host + FIS_Type_DeviceBits = 0xA1 // Device bits + } + + public struct HBACommandHeader + { + public byte CFL; // 5 bits + public byte ATAPI; // 1 bit + public byte Write; // 1 = H2D | 0 = D2H // 1bit + public byte Prefetchable; // 1 bit + + public byte Reset; // 1 bit + public byte BIST; // 1 bit + public byte ClearBusy; // 1 bit + public byte Reserved0; // 1 bit + public byte PMP; // 4 bits + + public ushort PRDTL; // Physical region descriptor table length in entries + + public uint PRDBC; // Physical region descriptor byte count transferred + + public uint CTBA; // Command table descriptor base address + public uint CTBAU; // Command table descriptor base address upper 32 bits (4 bytes) + + public uint[] Reserved1; // [4] + } + + public struct HBACommandTable + { + // 0x00 + public byte[] CFIS; // [64] // = 64 + + // 0x40 + public byte[] ACMD; // [16] // = 16 + 64 = 80 + + // 0x50 + public byte[] Reserved; // [48] // = 48 + 80 = 128 + + public HBAPRDTEntry[] PRDTEntry; // [1] // = 24 + 128 = 152 + } + public struct HBAPRDTEntry + { + public uint DBA; // Data base address + public uint DBAU; // Data base address upper 32 bits + public uint Reserved0; + + public uint DBC; // Byte count, 4M max // 22 bits (2.75 Bytes) + public uint Reserved1; // Reserved // 9 bits + public uint InterruptOnCompletion; // Interrupt on completion // 1 bit } public enum PortType @@ -66,72 +113,72 @@ namespace Cosmos.HAL.Drivers.PCI.SATA PM = 0x04 } - //public struct FIS_REG_H2D - //{ - // public byte FISType; - // - // public byte Options; - // // Reserved - // //public byte CMDCTRL; - // public byte Command; - // public byte FeatureL; - // - // public byte LBA0; - // public byte LBA1; - // public byte LBA2; - // public byte Device; - // - // public byte LBA3; - // public byte LBA4; - // public byte LBA5; - // public byte FeatureH; - // - // public byte CountL; - // public byte CountH; - // public byte ICC; - // public byte Control; - // - // public byte Res2; - //} + public struct FISRegisterH2D + { + public byte FISType; + + //public byte Options; + // Reserved + public byte IsCommand; + public byte Command; + public byte FeatureL; + + public byte LBA0; + public byte LBA1; + public byte LBA2; + public byte Device; + + public byte LBA3; + public byte LBA4; + public byte LBA5; + public byte FeatureH; + + public byte CountL; + public byte CountH; + public byte ICC; + public byte Control; + + public byte Res2; + } - //public struct FIS_REG_D2H { - // public byte FISType; - // - // public byte Options; - // // Reserved - // //public byte InterruptBit; - // // Rseerved - // public byte Status; - // public byte Error; - // - // public byte LBA0; - // public byte LBA1; - // public byte LBA2; - // public byte Device; - // - // public byte LBA3; - // public byte LBA4; - // public byte LBA5; - // // Reserved - // - // public byte CountL; - // public byte CountH; - // public byte ICC; - // public ushort Res2; - // // Reserved - // public uint Res3; - // // Reserved - //} + public struct FISRegisterD2H { + public byte FISType; + + //public byte Options; + // Reserved + //public byte InterruptBit; + // Rseerved + public byte Status; + public byte Error; + + public byte LBA0; + public byte LBA1; + public byte LBA2; + public byte Device; + + public byte LBA3; + public byte LBA4; + public byte LBA5; + // Reserved + + public byte CountL; + public byte CountH; + public byte ICC; + public ushort Res2; + // Reserved + public uint Res3; + // Reserved + } - //public struct FIS_DATA { - // public byte FISType; - // - // public byte Options; - // // Reserved - // - // // Reserved - // public byte Payload; - //} + public struct FISData { + public byte FISType; + + //public byte Options; + // Reserved + + // Reserved + public byte Payload; + } // Unused //public struct PIO_SETUP { @@ -189,58 +236,82 @@ namespace Cosmos.HAL.Drivers.PCI.SATA public class AHCI { - public const uint SSTS_ADDRESS = 0x00000133; - public const uint SATA_SIG_ATA = 0x00000101; // SATA drive - public const uint SATA_SIG_ATAPI = 0xEB140101; // SATAPI drive - public const uint SATA_SIG_SEMB = 0xC33C0101; // Enclosure management bridge - public const uint SATA_SIG_PM = 0x96690101; // Port multiplier - public const uint PORT_DET_PRESENT = 0x00000003; - public const uint PORT_IPM_ACTIVE = 0x00000001; - public static uint PortLocation; + //___________________________________________________// + // SATA Signatures Constants // + public const uint SATA_SIG_ATA = 0x00000101; // SATA drive + public const uint SATA_SIG_ATAPI = 0xEB140101; // SATAPI drive + public const uint SATA_SIG_SEMB = 0xC33C0101; // Enclosure management bridge + public const uint SATA_SIG_PM = 0x96690101; // Port multiplier + // + // SATA Status Bits Constants // + public const uint PORT_DET_PRESENT = 0x00000003; // DET Present Value + public const uint PORT_IPM_ACTIVE = 0x00000001; // IPM Active Value + // + public const uint AHCI_BASE = 0x00400000; // AHCI Base + // + // ATA Device Status // + public const uint ATA_DEV_BUSY = 0x00000080; // ATA Device Busy + public const uint ATA_DEV_DRQ = 0x00000008; // ATA Device DRQ? + // + // HBA PortX Command Constants // + public const uint HBA_PxCMD_CR = (01 << 15); // + public const uint HBA_PxCMD_FR = (01 << 14); // + public const uint HBA_PxCMD_FRE = (01 << 04); // + public const uint HBA_PxCMD_SUD = (01 << 01); // + public const uint HBA_PxCMD_ST = (01 << 00); // + public const uint HBA_PxIS_TFES = (01 << 30); // + // + // ATA Command Constants // + public const uint ATA_CMD_READ_DMA_EX = 0x00000025; // + public const uint ATA_CMD_WRITE_DMA_EX = 0x00000025; // + // + //___________________________________________________// + private static uint mPortLocation; + private static uint[] mPorts = new uint[32]; public static PCIDevice mAHCIDevice = HAL.PCI.GetDeviceClass(0x01, 0x06); public static uint BAR5 = mAHCIDevice.BaseAddressBar[5].BaseAddress; public static MemoryBlock mAHCIMemory = new MemoryBlock(BAR5, 0x10FF); - public static MemoryBlock mAHCIPortMemory = new MemoryBlock(BAR5 + PortLocation, 0x10FF); + public static MemoryBlock mAHCIPortMemory = new MemoryBlock(BAR5 + mPortLocation, 0x10FF); internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); internal class PortHelper { public static PortRegisters GetPort(int aPortNumber) { - PortLocation = (uint)(aPortNumber); - if (aPortNumber == 00) PortLocation = 0x0100; - else if (aPortNumber == 01) PortLocation = 0x0180; - else if (aPortNumber == 02) PortLocation = 0x0200; - else if (aPortNumber == 03) PortLocation = 0x0280; - else if (aPortNumber == 04) PortLocation = 0x0300; - else if (aPortNumber == 05) PortLocation = 0x0380; - else if (aPortNumber == 06) PortLocation = 0x0400; - else if (aPortNumber == 07) PortLocation = 0x0480; - else if (aPortNumber == 08) PortLocation = 0x0500; - else if (aPortNumber == 09) PortLocation = 0x0580; - else if (aPortNumber == 10) PortLocation = 0x0600; - else if (aPortNumber == 11) PortLocation = 0x0680; - else if (aPortNumber == 12) PortLocation = 0x0700; - else if (aPortNumber == 13) PortLocation = 0x0780; - else if (aPortNumber == 14) PortLocation = 0x0800; - else if (aPortNumber == 15) PortLocation = 0x0880; - else if (aPortNumber == 16) PortLocation = 0x0900; - else if (aPortNumber == 17) PortLocation = 0x0980; - else if (aPortNumber == 18) PortLocation = 0x0A00; - else if (aPortNumber == 19) PortLocation = 0x0A80; - else if (aPortNumber == 20) PortLocation = 0x0B00; - else if (aPortNumber == 21) PortLocation = 0x0B80; - else if (aPortNumber == 22) PortLocation = 0x0C00; - else if (aPortNumber == 23) PortLocation = 0x0C80; - else if (aPortNumber == 24) PortLocation = 0x0D00; - else if (aPortNumber == 25) PortLocation = 0x0D80; - else if (aPortNumber == 26) PortLocation = 0x0E00; - else if (aPortNumber == 27) PortLocation = 0x0E80; - else if (aPortNumber == 28) PortLocation = 0x0F00; - else if (aPortNumber == 29) PortLocation = 0x0F80; - else if (aPortNumber == 30) PortLocation = 0x1000; - else if (aPortNumber == 31) PortLocation = 0x1080; + mPortLocation = (uint)(aPortNumber); + if (aPortNumber == 00) mPortLocation = 0x0100; + else if (aPortNumber == 01) mPortLocation = 0x0180; + else if (aPortNumber == 02) mPortLocation = 0x0200; + else if (aPortNumber == 03) mPortLocation = 0x0280; + else if (aPortNumber == 04) mPortLocation = 0x0300; + else if (aPortNumber == 05) mPortLocation = 0x0380; + else if (aPortNumber == 06) mPortLocation = 0x0400; + else if (aPortNumber == 07) mPortLocation = 0x0480; + else if (aPortNumber == 08) mPortLocation = 0x0500; + else if (aPortNumber == 09) mPortLocation = 0x0580; + else if (aPortNumber == 10) mPortLocation = 0x0600; + else if (aPortNumber == 11) mPortLocation = 0x0680; + else if (aPortNumber == 12) mPortLocation = 0x0700; + else if (aPortNumber == 13) mPortLocation = 0x0780; + else if (aPortNumber == 14) mPortLocation = 0x0800; + else if (aPortNumber == 15) mPortLocation = 0x0880; + else if (aPortNumber == 16) mPortLocation = 0x0900; + else if (aPortNumber == 17) mPortLocation = 0x0980; + else if (aPortNumber == 18) mPortLocation = 0x0A00; + else if (aPortNumber == 19) mPortLocation = 0x0A80; + else if (aPortNumber == 20) mPortLocation = 0x0B00; + else if (aPortNumber == 21) mPortLocation = 0x0B80; + else if (aPortNumber == 22) mPortLocation = 0x0C00; + else if (aPortNumber == 23) mPortLocation = 0x0C80; + else if (aPortNumber == 24) mPortLocation = 0x0D00; + else if (aPortNumber == 25) mPortLocation = 0x0D80; + else if (aPortNumber == 26) mPortLocation = 0x0E00; + else if (aPortNumber == 27) mPortLocation = 0x0E80; + else if (aPortNumber == 28) mPortLocation = 0x0F00; + else if (aPortNumber == 29) mPortLocation = 0x0F80; + else if (aPortNumber == 30) mPortLocation = 0x1000; + else if (aPortNumber == 31) mPortLocation = 0x1080; PortRegisters Port = new PortRegisters() { CLB = mAHCIPortMemory[0x00], @@ -298,38 +369,46 @@ namespace Cosmos.HAL.Drivers.PCI.SATA // Search for disks var xImplementedPort = aGeneric.PI; var xPort = 0; + var xPortType = 0U; var xSupportedPorts = 0x1F; while (xPort <= xSupportedPorts) { if (xImplementedPort != 0) { - PortType dt = CheckPortType(PortHelper.GetPort(xPort)); + PortType PortType = CheckPortType(PortHelper.GetPort(xPort)); var xPortString = "0:" + xPort; - if (dt == PortType.SATA) // If Port Type was SATA. + if (PortType == PortType.SATA) // If Port Type was SATA. { mAHCIDebugger.Send("SATA drive found at port " + xPortString); Console.WriteLine("SATA Drive found at port " + xPortString); + xPortType = 0x01; + PortRebase(PortHelper.GetPort(xPort), xPort); + Read(PortHelper.GetPort(xPort), 0, 0, 2, (ushort)BAR5); } - else if (dt == PortType.SATAPI) // If Port Type was SATAPI. + else if (PortType == PortType.SATAPI) // If Port Type was SATAPI. { mAHCIDebugger.Send("SATAPI drive found at port " + xPortString); Console.WriteLine("CD/DVD Drive found at port " + xPortString); + xPortType = 0x02; } - else if (dt == PortType.SEMB) // If Port Type was SEMB. + else if (PortType == PortType.SEMB) // If Port Type was SEMB. { mAHCIDebugger.Send("SEMB drive found at port " + xPortString); Console.WriteLine("SEMB Drive found at port " + xPortString); + xPortType = 0x03; } - else if (dt == PortType.PM) // If Port Type was Port Mulitplier. + else if (PortType == PortType.PM) // If Port Type was Port Mulitplier. { mAHCIDebugger.Send("Port Multiplier drive found at port " + xPortString); Console.WriteLine("Port Multiplier Drive found at port " + xPortString); + xPortType = 0x04; } - else if (dt == PortType.Nothing) // If Nothing in this Port. + else if (PortType == PortType.Nothing) // If Nothing in this Port. mAHCIDebugger.Send("No drive found at port " + xPortString); else // If Implemented Port value was not zero and not one of the above. mAHCIDebugger.Send("Unknown drive found at port " + xPortString); } + mPorts[xPort] = xPortType; xPort++; xImplementedPort >>= 1; } @@ -363,6 +442,260 @@ namespace Cosmos.HAL.Drivers.PCI.SATA } } + public void PortRebase(PortRegisters aPort, int aPortNumber) + { + StopCMD(aPort); + + aPort.CLB = (uint)(AHCI_BASE + (aPortNumber << 10)); + aPort.CLBU = 0; + mAHCIPortMemory.Fill(aPort.CLB, 0, 1024); + + // FIS offset: 32K+256*portno + // FIS entry size = 256 bytes per port + aPort.FB = (uint)(AHCI_BASE + (32 << 10) + (aPortNumber << 8)); + aPort.FBU = 0; + mAHCIPortMemory.Fill(aPort.FB, 0, 256); + + HBACommandHeader[] xCMDHeader = new HBACommandHeader[32]; + for (int i = 0; i < 32; i++) + { + xCMDHeader[i].PRDTL = 8; // 8 prdt entries per command table + // 256 bytes per command table, 64+16+48+16*8 + // Command table offset: 40K + 8K*portno + cmdheader_index*256 + xCMDHeader[i].CTBA = (uint)(AHCI_BASE + (40 << 10) + (aPortNumber << 13) + (i << 8)); + xCMDHeader[i].CTBAU = 0; + mAHCIPortMemory.Fill(xCMDHeader[i].CTBA, 0, 256); + } + + StartCMD(aPort); + } + public void StartCMD(PortRegisters aPort) + { + while ((aPort.CMD & HBA_PxCMD_CR) != 0) ; + + aPort.CMD |= HBA_PxCMD_FRE; + aPort.CMD |= HBA_PxCMD_ST; + } + + public void StopCMD(PortRegisters aPort) + { + aPort.CMD &= ~HBA_PxCMD_ST; + + while(true) + { + if ((aPort.CMD & HBA_PxCMD_FR) != 0) + continue; + if ((aPort.CMD & HBA_PxCMD_CR) != 0) + continue; + break; + } + + aPort.CMD &= ~HBA_PxCMD_FRE; + } + + public bool Read(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer) + { + aPort.IS -= 1; + int xSpin = 0; // Spin lock Timeout Counter + int xSlot = FindCMDSlot(aPort); + if (xSlot == -1) + return false; + + HBACommandHeader xCMDHeader = new HBACommandHeader(); + aPort.CLB += (uint)xSlot; + xCMDHeader.CFL = (byte)(17 / sizeof(uint)); + xCMDHeader.Write = 0; + xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); + + HBACommandTable xCMDTable = new HBACommandTable(); // xCMDHeader.CTBA + mAHCIPortMemory.Fill(xCMDHeader.CTBA, 0, (158 + (xCMDHeader.PRDTL - 1U)) * 24); + xCMDTable.PRDTEntry = new HBAPRDTEntry[1]; + + int i = 0; // i for PRDTEntry outside the loop? + + for (i = 0; i < xCMDHeader.PRDTL - 1; i++) + { + + xCMDTable.PRDTEntry[i].DBA = (uint)(aBuffer); + xCMDTable.PRDTEntry[i].DBC = 8 * 1024; + xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; + aBuffer += 4 * 1024; + aCount -= 16; + } + // Last entry + + xCMDTable.PRDTEntry[i].DBA = (uint)aBuffer; + xCMDTable.PRDTEntry[i].DBC = aCount << 9; + xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; + + // Setup the command + FISRegisterH2D CommandFIS = new FISRegisterH2D() // Address CMDTBL.CFIS; + { + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)ATA_CMD_READ_DMA_EX, + + LBA0 = (byte)aStartLow, + LBA1 = (byte)(aStartLow >> 8), + LBA2 = (byte)(aStartLow >> 16), + Device = 1 << 6, // LBA Mode + + LBA3 = (byte)(aStartLow >> 24), + LBA4 = (byte)aStartHigh, + LBA5 = (byte)(aStartHigh >> 8), + + CountL = (byte)(aCount & 0xFF), + CountH = (byte)(aCount >> 8), + }; + while ((aPort.TFD & (ATA_DEV_BUSY | ATA_DEV_DRQ)) != 0 && xSpin < 1000000) + { + xSpin++; + } + if (xSpin == 1000000) + { + mAHCIDebugger.Send("Port timed out"); + return false; + } + + aPort.CI = 1U << xSlot; // Issue with Command + + // Wait for Completion + while (true) + { + // In some longer duration reads, It may be Helpful to Spin on the DPS bit + // in the aPort.IS port field as well (1 << 5) + if ((aPort.CI & (1 << xSlot)) == 0) + break; + if ((aPort.IS == HBA_PxIS_TFES)) + { + Console.WriteLine("Error occured while Reading the Disk"); + mAHCIDebugger.Send("Read disk error!"); + return false; + } + } + + // Check Again + if (aPort.IS == HBA_PxIS_TFES) + { + Console.WriteLine("Error occured while Reading the Disk"); + mAHCIDebugger.Send("Read disk error!"); + return false; + } + + return true; + } + + // Inverting Some codes (Read -> Write) + public bool Write(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer) + { + aPort.IS -= 1; + int xSpin = 0; // Spin lock Timeout Counter + int xSlot = FindCMDSlot(aPort); + if (xSlot == -1) + return false; + + HBACommandHeader xCMDHeader = new HBACommandHeader(); + aPort.CLB += (uint)xSlot; + xCMDHeader.CFL = 15 / sizeof(uint); + xCMDHeader.Write = 1; + xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); + + HBACommandTable xCMDTable = new HBACommandTable(); // xCMDHeader.CTBA + mAHCIPortMemory.Fill(xCMDHeader.CTBA, 0, (158 + (xCMDHeader.PRDTL - 1U)) * 24); + xCMDTable.PRDTEntry = new HBAPRDTEntry[1]; + + int i = 0; // i for PRDTEntry outside the loop? + + for (i = 0; i < xCMDHeader.PRDTL - 1; i++) + { + + xCMDTable.PRDTEntry[i].DBA = (uint)(aBuffer); + xCMDTable.PRDTEntry[i].DBC = 8 * 1024; + xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; + aBuffer += 4 * 1024; + aCount -= 16; + } + // Last entry + + xCMDTable.PRDTEntry[i].DBA = (uint)aBuffer; + xCMDTable.PRDTEntry[i].DBC = aCount << 9; + xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; + + // Setup the command + FISRegisterH2D CommandFIS = new FISRegisterH2D // Address CMDTBL.CFIS; + { + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)ATA_CMD_WRITE_DMA_EX, + + LBA0 = (byte)aStartLow, + LBA1 = (byte)(aStartLow >> 8), + LBA2 = (byte)(aStartLow >> 16), + Device = 1 << 6, // LBA Mode + + LBA3 = (byte)(aStartLow >> 24), + LBA4 = (byte)aStartHigh, + LBA5 = (byte)(aStartHigh >> 8), + + CountL = (byte)(aCount & 0xFF), + CountH = (byte)(aCount >> 8) + }; + + while ((aPort.TFD & (ATA_DEV_BUSY | ATA_DEV_DRQ)) != 0 && xSpin < 1000000) + { + xSpin++; + } + + if (xSpin == 1000000) + { + mAHCIDebugger.Send("Port timed out"); + return false; + } + + aPort.CI = 1U << xSlot; // Issue with Command + + // Wait for Completion + while (true) + { + // In some longer duration writes, It may be Helpful to Spin on the DPS bit + // in the aPort.IS port field as well (1 << 5) + if ((aPort.CI & (1 << xSlot)) == 0) + break; + if ((aPort.IS == HBA_PxIS_TFES)) + { + Console.WriteLine("Error occured while Writing to the Disk"); + mAHCIDebugger.Send("Write disk error!"); + return false; + } + } + + // Check Again + if (aPort.IS == HBA_PxIS_TFES) + { + Console.WriteLine("Error occured while Writing to the Disk"); + mAHCIDebugger.Send("Write disk error!"); + return false; + } + + return true; + } + + public int FindCMDSlot(PortRegisters aPort) + { + // If not set in SACT and CI, the slot is free + var xSlots = (aPort.SACT | aPort.CI); + for (int i = 0; i < xSlots; i++) + { + if ((xSlots & 1) == 0) + mAHCIDebugger.Send("Found a command slot: "); + mAHCIDebugger.SendNumber(i); + return i; + xSlots >>= 1; + } + mAHCIDebugger.Send("Cannot find free command list entry"); + return -1; + } + public static void InitSATA() { GenericRegisters mGeneric = new GenericRegisters() @@ -384,6 +717,7 @@ namespace Cosmos.HAL.Drivers.PCI.SATA }; var xSelf = new AHCI(); xSelf.SearchForDisks(mGeneric); + //xSelf.GetPartitions(xPorts, ); } } } From 4aa7a6dfeaacfda009e62dd1f5635c7eeec84364 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 11 Dec 2017 02:19:51 +0300 Subject: [PATCH 09/85] [AHCI] Fix Bugs and Improvements --- .../Drivers/PCI/Controllers/AHCI.cs | 1073 +++++++++-------- 1 file changed, 596 insertions(+), 477 deletions(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs index e3d1f2994..12175ec71 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs @@ -1,10 +1,16 @@ using System; +using System.Collections.Generic; using Cosmos.Core; +using Cosmos.Core.Memory.Old; using Cosmos.Debug.Kernel; +using Cosmos.HAL.Drivers.PCI.Controllers; -namespace Cosmos.HAL.Drivers.PCI.SATA +namespace Cosmos.HAL.BlockDevice { - public struct GenericRegisters + #region Registers + + //TODO: Must be struct + public class GenericRegisters { public uint CAP; public uint GHC; @@ -22,7 +28,7 @@ namespace Cosmos.HAL.Drivers.PCI.SATA public PortRegisters[] Ports; } - public struct PortRegisters + public class PortRegisters { public uint CLB; public uint CLBU; @@ -57,8 +63,9 @@ namespace Cosmos.HAL.Drivers.PCI.SATA FIS_Type_DeviceBits = 0xA1 // Device bits } - public struct HBACommandHeader + public class HBACommandHeader { + // DWord 0 public byte CFL; // 5 bits public byte ATAPI; // 1 bit public byte Write; // 1 = H2D | 0 = D2H // 1bit @@ -72,36 +79,37 @@ namespace Cosmos.HAL.Drivers.PCI.SATA public ushort PRDTL; // Physical region descriptor table length in entries + // DWord 1 public uint PRDBC; // Physical region descriptor byte count transferred public uint CTBA; // Command table descriptor base address public uint CTBAU; // Command table descriptor base address upper 32 bits (4 bytes) - public uint[] Reserved1; // [4] + // Reserved1; // [4] } - public struct HBACommandTable + public class HBACommandTable { // 0x00 - public byte[] CFIS; // [64] // = 64 + public byte CFIS; // [64] // = 64 // 0x40 - public byte[] ACMD; // [16] // = 16 + 64 = 80 + public byte ACMD; // [16] // = 16 + 64 = 80 // 0x50 - public byte[] Reserved; // [48] // = 48 + 80 = 128 + public byte Reserved; // [48] // = 48 + 80 = 128 - public HBAPRDTEntry[] PRDTEntry; // [1] // = 24 + 128 = 152 + public HBAPRDTEntry[] PRDTEntry; // [1] // = 44 + 128 = 172 } - public struct HBAPRDTEntry - { + public class HBAPRDTEntry + { public uint DBA; // Data base address public uint DBAU; // Data base address upper 32 bits public uint Reserved0; public uint DBC; // Byte count, 4M max // 22 bits (2.75 Bytes) public uint Reserved1; // Reserved // 9 bits - public uint InterruptOnCompletion; // Interrupt on completion // 1 bit + public int InterruptOnCompletion; // Interrupt on completion // 1 bit } public enum PortType @@ -112,55 +120,62 @@ namespace Cosmos.HAL.Drivers.PCI.SATA SEMB = 0x03, PM = 0x04 } - - public struct FISRegisterH2D + + public class FISRegisterH2D { public byte FISType; - + //public byte Options; // Reserved public byte IsCommand; public byte Command; public byte FeatureL; - + public byte LBA0; public byte LBA1; public byte LBA2; public byte Device; - + public byte LBA3; public byte LBA4; public byte LBA5; public byte FeatureH; - + public byte CountL; public byte CountH; public byte ICC; public byte Control; - + public byte Res2; + + public static explicit operator byte(FISRegisterH2D v) + { + byte xValue = sizeof(byte) * 16; + return xValue; + } } - public struct FISRegisterD2H { + public class FISRegisterD2H + { public byte FISType; - + //public byte Options; // Reserved //public byte InterruptBit; // Rseerved public byte Status; public byte Error; - + public byte LBA0; public byte LBA1; public byte LBA2; public byte Device; - + public byte LBA3; public byte LBA4; public byte LBA5; // Reserved - + public byte CountL; public byte CountH; public byte ICC; @@ -168,275 +183,386 @@ namespace Cosmos.HAL.Drivers.PCI.SATA // Reserved public uint Res3; // Reserved + + public static explicit operator byte(FISRegisterD2H v) + { + byte xValue = sizeof(byte) * 15; + return xValue; + } } - public struct FISData { + public class FISData + { public byte FISType; - - //public byte Options; - // Reserved - - // Reserved + public byte Payload; } + #endregion - // Unused - //public struct PIO_SETUP { - //public byte FISType; - // - //public byte Options; - //// Reserved - //public byte DataTransferDirection; - //public byte InterruptBit; - //// Reserved - // - //public byte Status; - //public byte Error; - // - //public byte LBA0; - //public byte LBA1; - //public byte LBA2; - //public byte Device; - // - //public byte LBA3; - //public byte LBA4; - //public byte LBA5; - //// Reserved - // - //public byte CountL; - //public byte CountH; - //// Reserved - //public byte NewStatus; - // - //public byte TransferCount; // System.int16 = WORD! - //// Reserved - //} - - //public struct DMA_SETUP { - //public byte FISType; - // - //public byte PortMultiplier; - //// Reserved - //public byte DataTransferDirection; - //public byte InterruptBit; - //public byte AutoActivate; // Specifies if DMA Activate FIS is needed - // - //// Reserved - // - //public byte DMABufferIdentifier; // System.int64 = QWORD! - // - //// Reserved - // - //public byte DMABufferOffset; // System.int32 = DWORD! - // - //public byte TransferCount; // System.int32 = DWORD! - // - //// Reserved - //} - - public class AHCI + #region Enums + public enum DriveSignature : uint // Drive Signature to identify what drive is plugged to Port X:X + { + SATADrive = 0x00000101, + PMDrive = 0x96690101, + SATAPIDrive = 0xEB140101, + SEMBDrive = 0xC33C0101, + NullDrive = 0xFFFFFFFF + } + + public enum InterfacePowerManagementStatus : uint // SATA Status: Interface Power Management Status + { + NotPresent = 0x00, + Active = 0x01, + Partial = 0x02, + Slumber = 0x06, + DeviceSleep = 0x08 + } + + public enum CurrentInterfaceSpeedStatus : uint // SATA Status: Current Interface Speed + { + NotPresent = 0x00, + Gen1Rate = 0x01, + Gen2Rate = 0x02, + Gen3Rate = 0x03 + } + + public enum DeviceDetectionStatus : uint // SATA Status: Device Detection Status + { + NotDetected = 0x00, + DeviceDetectedNoPhy = 0x01, + DeviceDetectedWithPhy = 0x03, + PhyOffline = 0x04 + } + + public enum ATADeviceStatus : uint + { + Busy = 0x80, + DRQ = 0x08 + } + + public enum CommandAndStatus : uint + { + ICC_Reserved0 = 0x0000000F, + ICC_DevSleep = 0x00000008, + ICC_Slumber = 0x00000006, + ICC_Partial = 0x00000002, + ICC_Active = 0x00000001, + ICC_Idle = 0x00000000, + ASP = (01 << 27), + ALPE = (01 << 26), + EnableATAPILED = (01 << 25), + ATAPIDevice = (01 << 24), + APSTE = (01 << 23), + FISSwitchPort = (01 << 22), + ExternalSATAPort = (01 << 21), + ColdPresenceDetect = (01 << 20), + MPSP = (01 << 19), + HotPlugCapPort = (01 << 18), + PortMultAttach = (01 << 17), + ColdPresenceState = (01 << 16), + CMDListRunning = (01 << 15), + FISRecieveRunning = (01 << 14), + MPSS = (01 << 13), + CurrentCMDSlot = (01 << 12), + Reserved0 = (01 << 07), + FISRecieveEnable = (01 << 04), + CMDListOverride = (01 << 03), + PowerOnDevice = (01 << 02), + SpinUpDevice = (01 << 01), + StartProccess = (01 << 00), + Null = 0xFFFF + } + + public enum InterruptStatus : int + { + ColdPortDetectStatus = (01 << 31), + TaskFileErrorStatus = (01 << 30), + HostBusFatalErrorStatus = (01 << 29), + HostBusDataErrorStatus = (01 << 28), + InterfaceFatalErrorStatus = (01 << 27), + InterfaceNFatalErrorStatus = (01 << 26), + OverflowStatus = (01 << 24), + IncorrectPMStatus = (01 << 23), + PhyRdyChangeStatus = (01 << 22), + DevMechanicalPresenceStatus = (01 << 07), + PortConnectChangeStatus = (01 << 06), + DescriptorProcessed = (01 << 05), + UnknownFISInterrupt = (01 << 04), + SetDeviceBitsInterrupt = (01 << 03), + DMASetupFISInterrupt = (01 << 02), + PIOSetupFISInterrupt = (01 << 01), + D2HRegFISInterrupt = (01 << 00), + Null = 0xFFFF + } + + public enum InterruptEnable : uint + { + OverflowEnable = (01 << 24), + IncorrectPMEnable = (01 << 23), + PhyRdyChangeInterruptEnable = (01 << 22), + DevMechanicalPresenceEnable = (01 << 07), + PortChangeInterruptEnable = (01 << 06), + DescProcessedInterruptEnable = (01 << 05), + UnknownFISInterruptEnable = (01 << 04), + SetDeviceBitsInterruptEnable = (01 << 03), + DMASetupFISInterruptEnable = (01 << 02), + PIOSetupFISInterruptEnable = (01 << 01), + D2HRegFISInterruptEnable = (01 << 00), + Null = 0xFFFF + } + + public enum SATACommands : uint + { + ReadPio = AtaPio.Cmd.ReadPio, + ReadPioExt = AtaPio.Cmd.ReadPioExt, + ReadDma = AtaPio.Cmd.ReadDma, + ReadDmaExt = AtaPio.Cmd.ReadDmaExt, + WritePio = AtaPio.Cmd.WritePio, + WritePioExt = AtaPio.Cmd.WritePioExt, + WriteDma = AtaPio.Cmd.WriteDma, + WriteDmaExt = AtaPio.Cmd.WriteDmaExt, + CacheFlush = AtaPio.Cmd.CacheFlush, + CacheFlushExt = AtaPio.Cmd.CacheFlushExt, + Packet = AtaPio.Cmd.Packet, + IdentifyPacket = AtaPio.Cmd.IdentifyPacket, + Identify = AtaPio.Cmd.Identify, + Read = AtaPio.Cmd.Read, + Eject = AtaPio.Cmd.Eject + } + + public enum Bases : uint { SATA = 0x00400000 } + #endregion + + public class SATA : BlockDevice { - //___________________________________________________// - // SATA Signatures Constants // - public const uint SATA_SIG_ATA = 0x00000101; // SATA drive - public const uint SATA_SIG_ATAPI = 0xEB140101; // SATAPI drive - public const uint SATA_SIG_SEMB = 0xC33C0101; // Enclosure management bridge - public const uint SATA_SIG_PM = 0x96690101; // Port multiplier - // - // SATA Status Bits Constants // - public const uint PORT_DET_PRESENT = 0x00000003; // DET Present Value - public const uint PORT_IPM_ACTIVE = 0x00000001; // IPM Active Value - // - public const uint AHCI_BASE = 0x00400000; // AHCI Base - // - // ATA Device Status // - public const uint ATA_DEV_BUSY = 0x00000080; // ATA Device Busy - public const uint ATA_DEV_DRQ = 0x00000008; // ATA Device DRQ? - // - // HBA PortX Command Constants // - public const uint HBA_PxCMD_CR = (01 << 15); // - public const uint HBA_PxCMD_FR = (01 << 14); // - public const uint HBA_PxCMD_FRE = (01 << 04); // - public const uint HBA_PxCMD_SUD = (01 << 01); // - public const uint HBA_PxCMD_ST = (01 << 00); // - public const uint HBA_PxIS_TFES = (01 << 30); // - // - // ATA Command Constants // - public const uint ATA_CMD_READ_DMA_EX = 0x00000025; // - public const uint ATA_CMD_WRITE_DMA_EX = 0x00000025; // - // - //___________________________________________________// private static uint mPortLocation; private static uint[] mPorts = new uint[32]; - public static PCIDevice mAHCIDevice = HAL.PCI.GetDeviceClass(0x01, 0x06); - public static uint BAR5 = mAHCIDevice.BaseAddressBar[5].BaseAddress; - public static MemoryBlock mAHCIMemory = new MemoryBlock(BAR5, 0x10FF); - public static MemoryBlock mAHCIPortMemory = new MemoryBlock(BAR5 + mPortLocation, 0x10FF); - internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); + private static uint mABAR; + private static MemoryBlock mSATAMemory; + internal static Debugger mSATADebugger = new Debugger("HAL", "SATA"); - internal class PortHelper + public static GenericRegisters mGeneric; + + public List SATAPorts = new List(32); + + public static InterfacePowerManagementStatus mIPM; + public static DeviceDetectionStatus mDET; + private int xPort; + private bool is64DMA; + + #region Registers + internal class Registers + { + public static PortRegisters PortRegisters(int aPortNumber) + { + mPortLocation = 0x100 + (0x80 * (uint)aPortNumber); + PortRegisters xPortReg = new PortRegisters(); + xPortReg.CLB = mSATAMemory[mPortLocation + 0x00]; + xPortReg.CLBU = mSATAMemory[mPortLocation + 0x04]; + xPortReg.FB = mSATAMemory[mPortLocation + 0x08]; + xPortReg.FBU = mSATAMemory[mPortLocation + 0x0C]; + xPortReg.IS = mSATAMemory[mPortLocation + 0x10]; + xPortReg.IE = mSATAMemory[mPortLocation + 0x14]; + xPortReg.CMD = mSATAMemory[mPortLocation + 0x18]; + xPortReg.Reserved0 = mSATAMemory[mPortLocation + 0x1C]; + xPortReg.TFD = mSATAMemory[mPortLocation + 0x20]; + xPortReg.SIG = mSATAMemory[mPortLocation + 0x24]; + xPortReg.SSTS = mSATAMemory[mPortLocation + 0x28]; + xPortReg.SCTL = mSATAMemory[mPortLocation + 0x2C]; + xPortReg.SERR = mSATAMemory[mPortLocation + 0x30]; + xPortReg.SACT = mSATAMemory[mPortLocation + 0x34]; + xPortReg.CI = mSATAMemory[mPortLocation + 0x38]; + xPortReg.SNTF = mSATAMemory[mPortLocation + 0x3C]; + xPortReg.FBS = mSATAMemory[mPortLocation + 0x40]; + xPortReg.Reserved1 = GetValueArray(0x44, 11); + xPortReg.VendorSpecific = GetValueArray(0x70, 4); + mIPM = (InterfacePowerManagementStatus)((byte)((xPortReg.SSTS >> 8) & 0x0F)); + mDET = (DeviceDetectionStatus)((byte)(xPortReg.SSTS & 0x0F)); + return xPortReg; + } + public static PortRegisters PortRegisters(int[] aPortsArray) + { + foreach (int xPortNumber in aPortsArray) + { + mPortLocation = 0x100 + (0x80 * (uint)xPortNumber); + PortRegisters xPortReg = new PortRegisters(); + xPortReg.CLB = mSATAMemory[mPortLocation + 0x00]; + xPortReg.CLBU = mSATAMemory[mPortLocation + 0x04]; + xPortReg.FB = mSATAMemory[mPortLocation + 0x08]; + xPortReg.FBU = mSATAMemory[mPortLocation + 0x0C]; + xPortReg.IS = mSATAMemory[mPortLocation + 0x10]; + xPortReg.IE = mSATAMemory[mPortLocation + 0x14]; + xPortReg.CMD = mSATAMemory[mPortLocation + 0x18]; + xPortReg.Reserved0 = mSATAMemory[mPortLocation + 0x1C]; + xPortReg.TFD = mSATAMemory[mPortLocation + 0x20]; + xPortReg.SIG = mSATAMemory[mPortLocation + 0x24]; + xPortReg.SSTS = mSATAMemory[mPortLocation + 0x28]; + xPortReg.SCTL = mSATAMemory[mPortLocation + 0x2C]; + xPortReg.SERR = mSATAMemory[mPortLocation + 0x30]; + xPortReg.SACT = mSATAMemory[mPortLocation + 0x34]; + xPortReg.CI = mSATAMemory[mPortLocation + 0x38]; + xPortReg.SNTF = mSATAMemory[mPortLocation + 0x3C]; + xPortReg.FBS = mSATAMemory[mPortLocation + 0x40]; + xPortReg.Reserved1 = GetValueArray(0x44, 11); + xPortReg.VendorSpecific = GetValueArray(0x70, 4); + return xPortReg; + } + PortRegisters mNullPort = new PortRegisters(); + return mNullPort; + } + + /// + /// Note: This method only work when SATA is initialized! + /// + public static int GetPortNumber() + { + foreach (int mPort in mPorts) + { + if (mPort == 1) + { + return mPort; // Return mPort SATA Type + } + else + { + // If mPort's value is not 1 then it is a CD/DVD Drive Port, Port Multiplier, SEMB Port or Nothing in the Port + } + } + return -1; + } + public static uint[] GetValueArray(uint aStartAddress, int aAmount) + { + uint[] FinishedArray = new uint[aAmount]; + + int i = 0; + for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) + { + while (i < aAmount) + { + FinishedArray[i] = mSATAMemory[ui]; + i++; + break; + } + } + return FinishedArray; + } + public static byte[] GetByteValueArray(uint aStartAddress, int aAmount) + { + byte[] FinishedArray = new byte[aAmount]; + + for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) + { + for (int i = 0; i < aAmount; i++) + { + FinishedArray[i] = mSATAMemory.Bytes[ui]; + } + } + return FinishedArray; + } + } + #endregion + + public SATA(uint ABAROffset) { - public static PortRegisters GetPort(int aPortNumber) - { - mPortLocation = (uint)(aPortNumber); - if (aPortNumber == 00) mPortLocation = 0x0100; - else if (aPortNumber == 01) mPortLocation = 0x0180; - else if (aPortNumber == 02) mPortLocation = 0x0200; - else if (aPortNumber == 03) mPortLocation = 0x0280; - else if (aPortNumber == 04) mPortLocation = 0x0300; - else if (aPortNumber == 05) mPortLocation = 0x0380; - else if (aPortNumber == 06) mPortLocation = 0x0400; - else if (aPortNumber == 07) mPortLocation = 0x0480; - else if (aPortNumber == 08) mPortLocation = 0x0500; - else if (aPortNumber == 09) mPortLocation = 0x0580; - else if (aPortNumber == 10) mPortLocation = 0x0600; - else if (aPortNumber == 11) mPortLocation = 0x0680; - else if (aPortNumber == 12) mPortLocation = 0x0700; - else if (aPortNumber == 13) mPortLocation = 0x0780; - else if (aPortNumber == 14) mPortLocation = 0x0800; - else if (aPortNumber == 15) mPortLocation = 0x0880; - else if (aPortNumber == 16) mPortLocation = 0x0900; - else if (aPortNumber == 17) mPortLocation = 0x0980; - else if (aPortNumber == 18) mPortLocation = 0x0A00; - else if (aPortNumber == 19) mPortLocation = 0x0A80; - else if (aPortNumber == 20) mPortLocation = 0x0B00; - else if (aPortNumber == 21) mPortLocation = 0x0B80; - else if (aPortNumber == 22) mPortLocation = 0x0C00; - else if (aPortNumber == 23) mPortLocation = 0x0C80; - else if (aPortNumber == 24) mPortLocation = 0x0D00; - else if (aPortNumber == 25) mPortLocation = 0x0D80; - else if (aPortNumber == 26) mPortLocation = 0x0E00; - else if (aPortNumber == 27) mPortLocation = 0x0E80; - else if (aPortNumber == 28) mPortLocation = 0x0F00; - else if (aPortNumber == 29) mPortLocation = 0x0F80; - else if (aPortNumber == 30) mPortLocation = 0x1000; - else if (aPortNumber == 31) mPortLocation = 0x1080; - PortRegisters Port = new PortRegisters() - { - CLB = mAHCIPortMemory[0x00], - CLBU = mAHCIPortMemory[0x04], - FB = mAHCIPortMemory[0x08], - FBU = mAHCIPortMemory[0x0C], - IS = mAHCIPortMemory[0x10], - IE = mAHCIPortMemory[0x14], - CMD = mAHCIPortMemory[0x18], - Reserved0 = mAHCIPortMemory[0x1C], - TFD = mAHCIPortMemory[0x20], - SIG = mAHCIPortMemory[0x24], - SSTS = mAHCIPortMemory[0x28], - SCTL = mAHCIPortMemory[0x2C], - SERR = mAHCIPortMemory[0x30], - SACT = mAHCIPortMemory[0x34], - CI = mAHCIPortMemory[0x38], - SNTF = mAHCIPortMemory[0x3C], - FBS = mAHCIPortMemory[0x40], - Reserved1 = GetValueArray(0x44, 11), - VendorSpecific = GetValueArray(0x70, 4) - }; - return Port; - } - public static uint[] GetValueArray(uint aStartAddress, int aAmount) - { - uint[] FinishedArray = new uint[aAmount]; + // Setting Offset arg to Global offset + mABAR = ABAROffset; + mSATAMemory = new MemoryBlock(mABAR, 0x10FF); - for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) - { - for (int i = 0; i < aAmount; i++) - { - FinishedArray[i] = mAHCIPortMemory[ui]; - } - } - return FinishedArray; - } - public static byte[] GetByteValueArray(uint aStartAddress, int aAmount) + mGeneric = new GenericRegisters { - byte[] FinishedArray = new byte[aAmount]; - - for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) - { - for (int i = 0; i < aAmount; i++) - { - FinishedArray[i] = mAHCIPortMemory.Bytes[ui]; - } - } - return FinishedArray; - } + CAP = mSATAMemory[0x00], + GHC = mSATAMemory[0x04], + IS = mSATAMemory[0x08], + PI = mSATAMemory[0x0C], + VS = mSATAMemory[0x10], + CCC_CTL = mSATAMemory[0x14], + CCC_PORTS = mSATAMemory[0x18], + EM_LOC = mSATAMemory[0x1C], + EM_CTL = mSATAMemory[0x20], + CAP2 = mSATAMemory[0x24], + BOHC = mSATAMemory[0x28], + //Reserved0 = Registers.GetByteValueArray(0x2C, 29), + //VendorSpecific = Registers.GetByteValueArray(0xA0, 20), + Ports = new PortRegisters[32] + }; + while (((mSATAMemory[0x04] >> 31) & 1) == 0) ; + mBlockSize = 512; + mBlockCount = 256; + Console.WriteLine("-- 00 --"); + SearchForDisks(mGeneric); } + + private void SearchForDisks(GenericRegisters aGeneric) { // Search for disks var xImplementedPort = aGeneric.PI; var xPort = 0; var xPortType = 0U; - var xSupportedPorts = 0x1F; - while (xPort <= xSupportedPorts) + while(xPort < 32) { - if (xImplementedPort != 0) + if ((xImplementedPort & 1) != 0) { - PortType PortType = CheckPortType(PortHelper.GetPort(xPort)); + PortType PortType = CheckPortType(Registers.PortRegisters(xPort)); var xPortString = "0:" + xPort; if (PortType == PortType.SATA) // If Port Type was SATA. { - mAHCIDebugger.Send("SATA drive found at port " + xPortString); - Console.WriteLine("SATA Drive found at port " + xPortString); + Console.WriteLine("SATA drive at port " + xPortString + " found"); + Console.WriteLine("SATA Drive at port " + xPortString); + PortRebase(Registers.PortRegisters(xPort), xPort); + ushort ReadedBits = new ushort(); + SATAPorts.Add(xPort); + mSATADebugger.Send("Readen bits: " + ReadedBits); xPortType = 0x01; - PortRebase(PortHelper.GetPort(xPort), xPort); - Read(PortHelper.GetPort(xPort), 0, 0, 2, (ushort)BAR5); } else if (PortType == PortType.SATAPI) // If Port Type was SATAPI. { - mAHCIDebugger.Send("SATAPI drive found at port " + xPortString); - Console.WriteLine("CD/DVD Drive found at port " + xPortString); + Console.WriteLine("SATAPI drive at port " + xPortString + " found, which is not supported yet!"); + Console.WriteLine("CD/DVD Drive at port " + xPortString + " found, which is not supported yet!"); xPortType = 0x02; } else if (PortType == PortType.SEMB) // If Port Type was SEMB. { - mAHCIDebugger.Send("SEMB drive found at port " + xPortString); - Console.WriteLine("SEMB Drive found at port " + xPortString); + //Console.WriteLine("SEMB drive at port " + xPortString + " found, which is not supported yet!"); + Console.WriteLine("SEMB Drive at port " + xPortString + " found, which is not supported yet!"); xPortType = 0x03; } else if (PortType == PortType.PM) // If Port Type was Port Mulitplier. { - mAHCIDebugger.Send("Port Multiplier drive found at port " + xPortString); - Console.WriteLine("Port Multiplier Drive found at port " + xPortString); + //Console.WriteLine("Port Multiplier drive at port " + xPortString + " found, which is not supported yet!"); + Console.WriteLine("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); xPortType = 0x04; } - else if (PortType == PortType.Nothing) // If Nothing in this Port. - mAHCIDebugger.Send("No drive found at port " + xPortString); - else // If Implemented Port value was not zero and not one of the above. - mAHCIDebugger.Send("Unknown drive found at port " + xPortString); + //else if (PortType == PortType.Nothing) // If Nothing in this Port. + //else // If Implemented Port value was not zero and non of the above. } mPorts[xPort] = xPortType; - xPort++; xImplementedPort >>= 1; + xPort++; } } - private PortType CheckPortType(PortRegisters Port) + private PortType CheckPortType(PortRegisters Port) { - uint Signature = Port.SIG; - uint SATAStatus = Port.SSTS; + DriveSignature xSignature = (DriveSignature)Port.SIG; + uint xSATAStatus = Port.SSTS; - var xIPM = (byte)((SATAStatus >> 8) & 0x0F); - var xDET = (byte)(SATAStatus & 0x0F); - mAHCIDebugger.SendNumber(xIPM); - mAHCIDebugger.SendNumber(xDET); - - if (xIPM != PORT_IPM_ACTIVE) + if (mIPM != InterfacePowerManagementStatus.Active) return PortType.Nothing; - if (xDET != PORT_DET_PRESENT) + if (mDET != DeviceDetectionStatus.DeviceDetectedWithPhy) return PortType.Nothing; - switch (Signature) + switch (xSignature) { - case SATA_SIG_ATAPI: + case DriveSignature.SATAPIDrive: return PortType.SATAPI; - case SATA_SIG_SEMB: + case DriveSignature.SEMBDrive: return PortType.SEMB; - case SATA_SIG_PM: + case DriveSignature.PMDrive: return PortType.PM; + case DriveSignature.NullDrive: + return PortType.Nothing; default: return PortType.SATA; } @@ -446,278 +572,271 @@ namespace Cosmos.HAL.Drivers.PCI.SATA { StopCMD(aPort); - aPort.CLB = (uint)(AHCI_BASE + (aPortNumber << 10)); - aPort.CLBU = 0; - mAHCIPortMemory.Fill(aPort.CLB, 0, 1024); + var CLBAddress = Heap.MemAlloc(1024); + var FBAddress = Heap.MemAlloc(256); + Console.WriteLine(CLBAddress.ToString()); + mSATAMemory[mPortLocation] = CLBAddress; + new MemoryBlock(mSATAMemory[mPortLocation], 1024).Fill(0); + //if(is64DMA) + //{ + // mSATAMemory[mPortLocation + 0x04] |= CLBUAddress; + // new MemoryBlock(mSATAMemory[mPortLocation + 0x04], 1024).Fill(0); + //} + + mSATAMemory[mPortLocation + 0x08] = FBAddress; + new MemoryBlock(mSATAMemory[mPortLocation + 0x08], 256).Fill(0); + //if (is64DMA) + //{ + // mSATAMemory[mPortLocation + 0x0C] |= FBUAddress; + // new MemoryBlock(mSATAMemory[mPortLocation + 0x0C], 256).Fill(0); + //} - // FIS offset: 32K+256*portno - // FIS entry size = 256 bytes per port - aPort.FB = (uint)(AHCI_BASE + (32 << 10) + (aPortNumber << 8)); - aPort.FBU = 0; - mAHCIPortMemory.Fill(aPort.FB, 0, 256); - - HBACommandHeader[] xCMDHeader = new HBACommandHeader[32]; - for (int i = 0; i < 32; i++) - { - xCMDHeader[i].PRDTL = 8; // 8 prdt entries per command table - // 256 bytes per command table, 64+16+48+16*8 - // Command table offset: 40K + 8K*portno + cmdheader_index*256 - xCMDHeader[i].CTBA = (uint)(AHCI_BASE + (40 << 10) + (aPortNumber << 13) + (i << 8)); - xCMDHeader[i].CTBAU = 0; - mAHCIPortMemory.Fill(xCMDHeader[i].CTBA, 0, 256); - } + GetCommandHeader(aPort, aPortNumber); // Rebasing Command Header StartCMD(aPort); } + + public static HBACommandHeader[] GetCommandHeader(PortRegisters aPort, int aPortNumber) + { + HBACommandHeader[] xCMDHeader = new HBACommandHeader[32]; + for (int i = 0; i < xCMDHeader.Length; i++) + { + xCMDHeader[i] = new HBACommandHeader(); + xCMDHeader[i].PRDTL = 8; // 8 prdt entries per command table + // 256 bytes per command table, 64+16+48+16*8 + xCMDHeader[i].CTBA = Heap.MemAlloc(256); + xCMDHeader[i].CTBAU = 0; + new MemoryBlock(xCMDHeader[i].CTBA, 256).Fill(0); + var xCMDHeaderMem = new MemoryBlock(mSATAMemory[mPortLocation + 0x00], 1024); + xCMDHeaderMem[0x02] = xCMDHeader[i].PRDTL; + xCMDHeaderMem[0x08] = xCMDHeader[i].CTBA << 7; + xCMDHeaderMem[0x0C] = xCMDHeader[i].CTBAU; + } + return xCMDHeader; + } + public void StartCMD(PortRegisters aPort) { - while ((aPort.CMD & HBA_PxCMD_CR) != 0) ; - - aPort.CMD |= HBA_PxCMD_FRE; - aPort.CMD |= HBA_PxCMD_ST; + while ((mSATAMemory[mPortLocation + 0x18] & (uint)CommandAndStatus.CMDListRunning) != 0) + { + //Console.WriteLine("Command list is already running"); + continue; + } + Console.WriteLine("Starting Process"); + mSATAMemory[mPortLocation + 0x18] |= (uint)CommandAndStatus.FISRecieveEnable; + mSATAMemory[mPortLocation + 0x18] |= (uint)CommandAndStatus.StartProccess; } public void StopCMD(PortRegisters aPort) { - aPort.CMD &= ~HBA_PxCMD_ST; + Console.WriteLine("Stopping Process"); + mSATAMemory[mPortLocation + 0x18] &= ~(uint)CommandAndStatus.FISRecieveEnable; + mSATAMemory[mPortLocation + 0x18] &= ~(uint)CommandAndStatus.StartProccess; - while(true) + while ((mSATAMemory[mPortLocation + 0x18] & (uint)(CommandAndStatus.FISRecieveRunning | CommandAndStatus.CMDListRunning)) != 0) ; + } + + private bool InternalTransfer(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer, bool aWrite = false) + { + //mSATAMemory[mPortLocation + 0x10] = unchecked((uint)-1); + new MemoryBlock(mSATAMemory.Base + mPortLocation + 0x10, sizeof(uint)).Fill(0); + int xSpin = 0; // Spin lock Timeout Counter + int xSlot = FindCMDSlot(aPort); + Console.WriteLine("My Slot: " + xSlot); + if (xSlot == -1) + return false; + + HBACommandHeader xCMDHeader = GetCommandHeader(aPort, Registers.GetPortNumber())[xSlot]; + //mSATAMemory[mPortLocation + 0x00] += (uint)xSlot; + xCMDHeader.CFL = (byte)(17 / sizeof(uint)); + xCMDHeader.Write = (aWrite ? (byte)1 : (byte)0); + xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); + var xCMDHeaderMem = new MemoryBlock(mSATAMemory[mPortLocation + 0x00], 1024); + xCMDHeaderMem[0x00] = (uint)xCMDHeader.PRDTL << 16; + xCMDHeaderMem[0x00] = (uint)xCMDHeader.Write << 6; + xCMDHeaderMem[0x00] = (uint)xCMDHeader.CFL << 0; + + Console.WriteLine(xCMDHeaderMem[0x00].ToString()); + Console.WriteLine(xCMDHeaderMem.Base.ToString()); + Console.WriteLine(xCMDHeader.CTBA.ToString()); + + Console.WriteLine("Before Command Table Initialization"); + HBACommandTable xCMDTable = new HBACommandTable(); // xCMDHeader.CTBA + var xCMDTableMem = new MemoryBlock(xCMDHeader.CTBA, 256); + xCMDTableMem.Fill(0, (((158 / 8) + (xCMDHeader.PRDTL - 1U)) * 24), 0); + xCMDTable.PRDTEntry = new HBAPRDTEntry[1]; + xCMDTable.PRDTEntry[0] = new HBAPRDTEntry(); + Console.WriteLine("After Command Table Initialization"); + + Console.WriteLine("Before MemAlloc"); + var xDataBA = Heap.MemAlloc(sizeof(ushort)); + Console.WriteLine(xDataBA); + var xDataMem = new MemoryBlock(xDataBA, sizeof(ushort)); + xDataMem[0x00] = aBuffer; + Console.WriteLine(xDataMem[0x00]); + Console.WriteLine("After MemAlloc"); + uint i = 1; + while (i - 1 < xCMDHeader.PRDTL - 1) { - if ((aPort.CMD & HBA_PxCMD_FR) != 0) - continue; - if ((aPort.CMD & HBA_PxCMD_CR) != 0) - continue; - break; + + Console.WriteLine("On Loop Command Table Initialization"); + xCMDTable.PRDTEntry[i - 1].DBA = (uint)(xDataBA); + xCMDTable.PRDTEntry[i - 1].DBC = 8 * 1024 - 1; + xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion = 1; + xCMDTableMem[(0x80 * i) + 0x00] = xCMDTable.PRDTEntry[i - 1].DBA << 1; + xCMDTableMem[(0x80 * i) + 0x0C] = xCMDTable.PRDTEntry[i - 1].DBC; + xCMDTableMem[(0x80 * i) + 0x0C] = (uint)xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion << 31; + aBuffer += 4 * 1024; + aCount -= 16; + i++; + } + Console.WriteLine("Last Command Table Initialization"); + + // Last entry + xCMDTable.PRDTEntry[i - 1].DBA = xDataBA; + xCMDTable.PRDTEntry[i - 1].DBC = (aCount << 9) - 1; + xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion = 1; + xCMDTableMem[(0x80 * i) + 0x00] = xCMDTable.PRDTEntry[i - 1].DBA << 1; + xCMDTableMem[(0x80 * i) + 0x0C] = xCMDTable.PRDTEntry[i - 1].DBC; + xCMDTableMem[(0x80 * i) + 0x0C] = (uint)xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion << 31; + + Console.WriteLine("Setup Command FIS"); + // Setup the command + uint xCMDFISAddress = Heap.MemAlloc(0x10); + + xCMDTableMem[0x00] = (uint)xCMDFISAddress; + FISRegisterH2D xCMDFIS = new FISRegisterH2D(); + xCMDFIS.FISType = (byte)FISType.FIS_Type_RegisterH2D; + xCMDFIS.IsCommand = 1; + xCMDFIS.Command = (aWrite ? (byte)SATACommands.WriteDmaExt : (byte)SATACommands.ReadDmaExt); + + xCMDFIS.LBA0 = (byte)aStartLow; + xCMDFIS.LBA1 = (byte)(aStartLow >> 8); + xCMDFIS.LBA2 = (byte)(aStartLow >> 16); + xCMDFIS.Device = 1 << 6; // LBA Mode + + xCMDFIS.LBA3 = 0x00; + xCMDFIS.LBA4 = 0x00; + xCMDFIS.LBA5 = 0x00; + + xCMDFIS.CountL = (byte)(aCount & 0xFF); + xCMDFIS.CountH = (byte)((aCount >> 8) & 0xFF); + var xCMDFISMem = new MemoryBlock((uint)xCMDTableMem[0x00], 0x10); + Console.WriteLine("Setting values to memory offset: " + xCMDTableMem[0x00]); + + // DWord 0 + xCMDFISMem[0x00] = (byte)(xCMDFIS.FISType); // FIS Type + xCMDFISMem[0x00] = (byte)(xCMDFIS.IsCommand >> 15); // IsCommand(or)Control + xCMDFISMem[0x00] = (byte)(xCMDFIS.Command >> 16); // Command register + + // DWord 1 + xCMDFISMem[0x04] = (byte)(xCMDFIS.LBA0); // LBA Low register + xCMDFISMem[0x04] = (byte)(xCMDFIS.LBA1 >> 8); // LBA Mid register + xCMDFISMem[0x04] = (byte)(xCMDFIS.LBA2 >> 16); // LBA Hgh register + xCMDFISMem[0x04] = (byte)(xCMDFIS.Device >> 24); // Device register + + // DWord 2 + xCMDFISMem[0x08] = (byte)(xCMDFIS.LBA3); // LBA register + xCMDFISMem[0x08] = (byte)(xCMDFIS.LBA4 >> 8); // LBA register + xCMDFISMem[0x08] = (byte)(xCMDFIS.LBA5 >> 16); // LBA register + + // DWord 3 + xCMDFISMem[0x0C] = (byte)(xCMDFIS.CountL); // Count Low register + xCMDFISMem[0x0C] = (byte)(xCMDFIS.CountH); // Count Hgh register + + Console.WriteLine(Cosmos.Common.Extensions.ToHexString.ToHex(new MemoryBlock(xCMDFISAddress, 0x10)[0x00])); + + Console.WriteLine("Spinning on xSpin"); + do + { + xSpin++; + Console.WriteLine(xSpin); + } while (((mSATAMemory[mPortLocation + 0x20] & (uint)(ATADeviceStatus.Busy | ATADeviceStatus.DRQ)) > 0 && xSpin < 1000000)); + + if (xSpin == 1000000) + { + Console.WriteLine("Port timed out"); + return false; } - aPort.CMD &= ~HBA_PxCMD_FRE; + mSATAMemory[mPortLocation + 0x38] = (uint)(1 << xSlot); // Issue with Command + + // Wait for Completion + do + { + // If error occured + if (((mSATAMemory[mPortLocation + 0x10] >> 30) & 1) != 0) + { + Console.WriteLine("Write or Read Disk Error!"); + return false; + } + } while (((mSATAMemory[mPortLocation + 0x38] >> xSlot) & 1) != 0); + + // Fill in the data + if (!aWrite) + { + aBuffer = xDataMem.Words[0x00]; + } + + return true; } public bool Read(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer) - { - aPort.IS -= 1; - int xSpin = 0; // Spin lock Timeout Counter - int xSlot = FindCMDSlot(aPort); - if (xSlot == -1) - return false; + => InternalTransfer(aPort, aStartLow, aStartHigh, aCount, aBuffer, false); - HBACommandHeader xCMDHeader = new HBACommandHeader(); - aPort.CLB += (uint)xSlot; - xCMDHeader.CFL = (byte)(17 / sizeof(uint)); - xCMDHeader.Write = 0; - xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); - - HBACommandTable xCMDTable = new HBACommandTable(); // xCMDHeader.CTBA - mAHCIPortMemory.Fill(xCMDHeader.CTBA, 0, (158 + (xCMDHeader.PRDTL - 1U)) * 24); - xCMDTable.PRDTEntry = new HBAPRDTEntry[1]; - - int i = 0; // i for PRDTEntry outside the loop? - - for (i = 0; i < xCMDHeader.PRDTL - 1; i++) - { - - xCMDTable.PRDTEntry[i].DBA = (uint)(aBuffer); - xCMDTable.PRDTEntry[i].DBC = 8 * 1024; - xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; - aBuffer += 4 * 1024; - aCount -= 16; - } - // Last entry - - xCMDTable.PRDTEntry[i].DBA = (uint)aBuffer; - xCMDTable.PRDTEntry[i].DBC = aCount << 9; - xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; - - // Setup the command - FISRegisterH2D CommandFIS = new FISRegisterH2D() // Address CMDTBL.CFIS; - { - FISType = (byte)FISType.FIS_Type_RegisterH2D, - IsCommand = 1, - Command = (byte)ATA_CMD_READ_DMA_EX, - - LBA0 = (byte)aStartLow, - LBA1 = (byte)(aStartLow >> 8), - LBA2 = (byte)(aStartLow >> 16), - Device = 1 << 6, // LBA Mode - - LBA3 = (byte)(aStartLow >> 24), - LBA4 = (byte)aStartHigh, - LBA5 = (byte)(aStartHigh >> 8), - - CountL = (byte)(aCount & 0xFF), - CountH = (byte)(aCount >> 8), - }; - while ((aPort.TFD & (ATA_DEV_BUSY | ATA_DEV_DRQ)) != 0 && xSpin < 1000000) - { - xSpin++; - } - if (xSpin == 1000000) - { - mAHCIDebugger.Send("Port timed out"); - return false; - } - - aPort.CI = 1U << xSlot; // Issue with Command - - // Wait for Completion - while (true) - { - // In some longer duration reads, It may be Helpful to Spin on the DPS bit - // in the aPort.IS port field as well (1 << 5) - if ((aPort.CI & (1 << xSlot)) == 0) - break; - if ((aPort.IS == HBA_PxIS_TFES)) - { - Console.WriteLine("Error occured while Reading the Disk"); - mAHCIDebugger.Send("Read disk error!"); - return false; - } - } - - // Check Again - if (aPort.IS == HBA_PxIS_TFES) - { - Console.WriteLine("Error occured while Reading the Disk"); - mAHCIDebugger.Send("Read disk error!"); - return false; - } - - return true; - } - - // Inverting Some codes (Read -> Write) public bool Write(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer) - { - aPort.IS -= 1; - int xSpin = 0; // Spin lock Timeout Counter - int xSlot = FindCMDSlot(aPort); - if (xSlot == -1) - return false; - - HBACommandHeader xCMDHeader = new HBACommandHeader(); - aPort.CLB += (uint)xSlot; - xCMDHeader.CFL = 15 / sizeof(uint); - xCMDHeader.Write = 1; - xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); - - HBACommandTable xCMDTable = new HBACommandTable(); // xCMDHeader.CTBA - mAHCIPortMemory.Fill(xCMDHeader.CTBA, 0, (158 + (xCMDHeader.PRDTL - 1U)) * 24); - xCMDTable.PRDTEntry = new HBAPRDTEntry[1]; - - int i = 0; // i for PRDTEntry outside the loop? - - for (i = 0; i < xCMDHeader.PRDTL - 1; i++) - { - - xCMDTable.PRDTEntry[i].DBA = (uint)(aBuffer); - xCMDTable.PRDTEntry[i].DBC = 8 * 1024; - xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; - aBuffer += 4 * 1024; - aCount -= 16; - } - // Last entry - - xCMDTable.PRDTEntry[i].DBA = (uint)aBuffer; - xCMDTable.PRDTEntry[i].DBC = aCount << 9; - xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; - - // Setup the command - FISRegisterH2D CommandFIS = new FISRegisterH2D // Address CMDTBL.CFIS; - { - FISType = (byte)FISType.FIS_Type_RegisterH2D, - IsCommand = 1, - Command = (byte)ATA_CMD_WRITE_DMA_EX, - - LBA0 = (byte)aStartLow, - LBA1 = (byte)(aStartLow >> 8), - LBA2 = (byte)(aStartLow >> 16), - Device = 1 << 6, // LBA Mode - - LBA3 = (byte)(aStartLow >> 24), - LBA4 = (byte)aStartHigh, - LBA5 = (byte)(aStartHigh >> 8), - - CountL = (byte)(aCount & 0xFF), - CountH = (byte)(aCount >> 8) - }; - - while ((aPort.TFD & (ATA_DEV_BUSY | ATA_DEV_DRQ)) != 0 && xSpin < 1000000) - { - xSpin++; - } - - if (xSpin == 1000000) - { - mAHCIDebugger.Send("Port timed out"); - return false; - } - - aPort.CI = 1U << xSlot; // Issue with Command - - // Wait for Completion - while (true) - { - // In some longer duration writes, It may be Helpful to Spin on the DPS bit - // in the aPort.IS port field as well (1 << 5) - if ((aPort.CI & (1 << xSlot)) == 0) - break; - if ((aPort.IS == HBA_PxIS_TFES)) - { - Console.WriteLine("Error occured while Writing to the Disk"); - mAHCIDebugger.Send("Write disk error!"); - return false; - } - } - - // Check Again - if (aPort.IS == HBA_PxIS_TFES) - { - Console.WriteLine("Error occured while Writing to the Disk"); - mAHCIDebugger.Send("Write disk error!"); - return false; - } - - return true; - } + => InternalTransfer(aPort, aStartLow, aStartHigh, aCount, aBuffer, true); public int FindCMDSlot(PortRegisters aPort) { // If not set in SACT and CI, the slot is free - var xSlots = (aPort.SACT | aPort.CI); - for (int i = 0; i < xSlots; i++) + var xSlots = (mSATAMemory[mPortLocation + 0x34] | mSATAMemory[mPortLocation + 0x38]); + //for(int i = 0; i < aPort.VendorSpecific.Length; i++) + ////mSATADebugger.SendInternalNumber(aPort.VendorSpecific[i]); + for (int i = 0; i < 32; i++) { if ((xSlots & 1) == 0) - mAHCIDebugger.Send("Found a command slot: "); - mAHCIDebugger.SendNumber(i); + { return i; + } xSlots >>= 1; } - mAHCIDebugger.Send("Cannot find free command list entry"); + //Console.WriteLine("Cannot find free Command list Entry"); return -1; } - public static void InitSATA() + public SATA(int xPort) { - GenericRegisters mGeneric = new GenericRegisters() + } + + public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) + { + CheckDataSize(aData, aBlockCount); + if(SATAPorts.Count > 0) { - CAP = mAHCIMemory[0x00], - GHC = mAHCIMemory[0x04], - IS = mAHCIMemory[0x08], - PI = mAHCIMemory[0x0C], - VS = mAHCIMemory[0x10], - CCC_CTL = mAHCIMemory[0x14], - CCC_PORTS = mAHCIMemory[0x18], - EM_LOC = mAHCIMemory[0x1C], - EM_CTL = mAHCIMemory[0x20], - CAP2 = mAHCIMemory[0x24], - BOHC = mAHCIMemory[0x28], - Reserved0 = PortHelper.GetByteValueArray(0x2C, 29), - VendorSpecific = PortHelper.GetByteValueArray(0xA0, 20), - Ports = new PortRegisters[32] - }; - var xSelf = new AHCI(); - xSelf.SearchForDisks(mGeneric); - //xSelf.GetPartitions(xPorts, ); + var xPort = Registers.PortRegisters(SATAPorts[0]); + for(int i = 0; i < aData.Length; i += 2) + { + ushort xData = (ushort)((aData[i + 1] << 8) | aData[i]); + Read(xPort, (uint)aBlockNo, 0, (uint)aBlockCount, xData); + for (int ui = 0; ui < 200; ui++) ; + aData[i+0] = (byte)(xData); + aData[i+1] = (byte)(xData >> 8); + } + } + } + + public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) + { + CheckDataSize(aData, aBlockCount); + var xPort = Registers.PortRegisters(SATAPorts[0]); + for (int i = 0; i < aData.Length; i += 2) + { + ushort xData = (ushort)((aData[i + 1] << 8) | aData[i]); + Write(xPort, (uint)aBlockNo, 0, (uint)aBlockCount, xData); + for (int ui = 0; ui < 200; ui++) ; + } + // Might not work for some reasons :| } } } From bb2d4ee75948f04fbfd3fc5935ad79b40ce657ab Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 11 Dec 2017 03:14:38 +0300 Subject: [PATCH 10/85] Update Global.cs --- source/Cosmos.HAL2/Global.cs | 126 +++++++++++++++++------------------ 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 9fddc667c..5b505e7e4 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -1,84 +1,78 @@ using System; -using Cosmos.HAL.Drivers.PCI.SATA; using Cosmos.Core; using Cosmos.Debug.Kernel; using Cosmos.HAL.BlockDevice; +using Cosmos.HAL.Drivers.PCI.Controllers; namespace Cosmos.HAL { - public static class Global - { - public static readonly Debugger mDebugger = new Debugger("HAL", "Global"); - - //static public PIT PIT = new PIT(); - // Must be static init, other static inits rely on it not being null - - public static TextScreenBase TextScreen = new TextScreen(); - public static PCI Pci; - public static SATAControllerMode SATAMode; - public enum SATAControllerMode + public static class Global { - AHCI, - RAID, - IDE, - }; + public static readonly Debugger mDebugger = new Debugger("HAL", "Global"); - static public void Init(TextScreenBase textScreen) - { - if (textScreen != null) - { - TextScreen = textScreen; - } + //static public PIT PIT = new PIT(); + // Must be static init, other static inits rely on it not being null - mDebugger.Send("Before Core.Global.Init"); - Core.Global.Init(); + public static TextScreenBase TextScreen = new TextScreen(); + public static PCI Pci; - //TODO Redo this - Global init should be other. - // Move PCI detection to hardware? Or leave it in core? Is Core PC specific, or deeper? - // If we let hardware do it, we need to protect it from being used by System. - // Probably belongs in hardware, and core is more specific stuff like CPU, memory, etc. - //Core.PCI.OnPCIDeviceFound = PCIDeviceFound; + static public void Init(TextScreenBase textScreen) + { + if (textScreen != null) + { + TextScreen = textScreen; + } - //TODO: Since this is FCL, its "common". Otherwise it should be - // system level and not accessible from Core. Need to think about this - // for the future. - Console.Clear(); + mDebugger.Send("Before Core.Global.Init"); + Core.Global.Init(); - Console.WriteLine("Finding PCI Devices"); - mDebugger.Send("PCI Devices"); - PCI.Setup(); + //TODO Redo this - Global init should be other. + // Move PCI detection to hardware? Or leave it in core? Is Core PC specific, or deeper? + // If we let hardware do it, we need to protect it from being used by System. + // Probably belongs in hardware, and core is more specific stuff like CPU, memory, etc. + //Core.PCI.OnPCIDeviceFound = PCIDeviceFound; - Console.WriteLine("Starting ACPI"); - mDebugger.Send("ACPI Init"); - ACPI.Start(); + //TODO: Since this is FCL, its "common". Otherwise it should be + // system level and not accessible from Core. Need to think about this + // for the future. - mDebugger.Send("Done initializing Cosmos.HAL.Global"); + Console.WriteLine("Finding PCI Devices"); + mDebugger.Send("PCI Devices"); + PCI.Setup(); - switch(SATAMode) // Detect what SATA Controller Mode is in: - { - case SATAControllerMode.AHCI: // SATA-native (AHCI) Mode - mDebugger.Send("AHCI Controller Detected, Initializing"); - AHCI.InitSATA(); - break; - case SATAControllerMode.RAID: // RAID Mode - // TODO: Initialize Raid Driver here - break; - case SATAControllerMode.IDE: // IDE Mode - mDebugger.Send("ATA Primary Master"); - IDE.InitAta(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); - - mDebugger.Send("ATA Secondary Master"); - IDE.InitAta(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); - //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); - break; - } + Console.WriteLine("Starting ACPI"); + mDebugger.Send("ACPI Init"); + ACPI.Start(); + + mDebugger.Send("Done initializing Cosmos.HAL.Global"); + + // Currently ATA won't be initialized until we find a solution for the + // Two Controllers initialize bug + //if (PCI.GetDeviceClass(0x01, 0x01) != null) + //{ + // mDebugger.Send("ATA Primary Master"); + // IDE ATA1 = new IDE(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); + // mDebugger.Send("ATA Secondary Master"); + // IDE ATA2 = new IDE(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); + // //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); + //} + if (PCI.GetDeviceClass(0x01, 0x06) != null) + { + Console.WriteLine("Initializing AHCI Controller"); + AHCI xAHCI = new AHCI(PCI.GetDeviceClass(0x01, 0x06).BaseAddressBar[5].BaseAddress); + } + else if (PCI.GetDeviceClass(0x01, 0x01) == null) + { + Console.Write("Booting without ATA Initialization"); + } + + } + + public static void EnableInterrupts() + { + CPU.EnableInterrupts(); + } + + public static bool InterruptsEnabled => CPU.mInterruptsEnabled; } - - public static void EnableInterrupts() - { - CPU.EnableInterrupts(); - } - - public static bool InterruptsEnabled => CPU.mInterruptsEnabled; - } } From 8aa859ba3fb16760f949f277908729d36eb02b0a Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 11 Dec 2017 03:17:47 +0300 Subject: [PATCH 11/85] Update PCI.cs --- source/Cosmos.HAL2/PCI.cs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/source/Cosmos.HAL2/PCI.cs b/source/Cosmos.HAL2/PCI.cs index f90a816d6..b8a9416c2 100644 --- a/source/Cosmos.HAL2/PCI.cs +++ b/source/Cosmos.HAL2/PCI.cs @@ -18,7 +18,6 @@ namespace Cosmos.HAL public static void Setup() { Devices = new List(); - if ((PCIDevice.GetHeaderType(0x0, 0x0, 0x0) & 0x80) == 0) { CheckBus(0x0); @@ -33,26 +32,6 @@ namespace Cosmos.HAL CheckBus(fn); } } - - foreach (PCIDevice device in Devices) - { - - if (device.ClassCode == 0x01 && device.Subclass == 0x06 && device.ProgIF == 0x01) - { - //Serial ATA (AHCI 1.0) - Global.SATAMode = Global.SATAControllerMode.AHCI; - } - else if (device.ClassCode == 0x01 && device.Subclass == 0x04 && device.ProgIF == 0x00) - { - //RAID Controller - Global.SATAMode = Global.SATAControllerMode.RAID; - } - else if (device.ClassCode == 0x01 && device.Subclass == 0x01) - { - //IDE Controller - Global.SATAMode = Global.SATAControllerMode.IDE; - } - } } private static void CheckBus(ushort xBus) @@ -109,4 +88,3 @@ namespace Cosmos.HAL } } } - From 5c421ae2cc5f24d1af9415dedffc195aa0f483de Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 11 Dec 2017 03:24:06 +0300 Subject: [PATCH 12/85] Rename source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs to source/Cosmos.HAL2/BlockDevice/Sata.cs --- .../{Drivers/PCI/Controllers/AHCI.cs => BlockDevice/Sata.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/{Drivers/PCI/Controllers/AHCI.cs => BlockDevice/Sata.cs} (100%) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/Sata.cs similarity index 100% rename from source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs rename to source/Cosmos.HAL2/BlockDevice/Sata.cs From 28148a75e9993621a4b0c00aceafba4f5640b62b Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 11 Dec 2017 03:25:08 +0300 Subject: [PATCH 13/85] Update IDE.cs --- source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs index f5670029e..aa9264ae4 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs @@ -1,7 +1,7 @@ using System; using Cosmos.HAL.BlockDevice; -namespace Cosmos.HAL.Drivers.PCI.SATA +namespace Cosmos.HAL.Drivers.PCI.Controllers { public class IDE { From 5fa47041e7dc02149169d5db5a6680045017863e Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 11 Dec 2017 03:29:17 +0300 Subject: [PATCH 14/85] [AHCI] Initializer --- .../Drivers/PCI/Controllers/AHCI.cs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs new file mode 100644 index 000000000..c71bf35e8 --- /dev/null +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs @@ -0,0 +1,58 @@ +using System; +using Cosmos.HAL; +using Cosmos.Debug.Kernel; +using Cosmos.HAL.BlockDevice; + +namespace Cosmos.HAL.Drivers.PCI.Controllers +{ + public class AHCI + { + internal Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); + + public AHCI(uint aABARAddress) + { + var xSATA = new SATA(aABARAddress); + var xMBRData = new byte[512]; + Console.WriteLine("Before"); + xSATA.ReadBlock(0UL, 1U, xMBRData); + Console.WriteLine(xMBRData[0]); + Console.WriteLine(xMBRData[1]); + Console.WriteLine(xMBRData[2]); + Console.WriteLine(xMBRData[3]); + Console.WriteLine(xMBRData[4]); + Console.WriteLine("Done reading"); + var xMBR = new MBR(xMBRData); + + if (xMBR.EBRLocation != 0) + { + // EBR Detected! + var xEBRData = new byte[512]; + xSATA.ReadBlock(xMBR.EBRLocation, 1U, xEBRData); + var xEBR = new EBR(xEBRData); + for (int i = 0; i < xEBR.Partitions.Count; i++) + { + //var xPart = xEBR.Partitions[i]; + //var xPartDevice = new Partition(xSATA, xPart.StartSector, xPart.SectorCount); + //Devices.Add(xPartDevice); + } + } + + mAHCIDebugger.Send("Number of MBR partitions found: "); + mAHCIDebugger.SendNumber(xMBR.Partitions.Count); + for (int i = 0; i < xMBR.Partitions.Count; i++) + { + var xPart = xMBR.Partitions[i]; + if (xPart == null) + { + Console.WriteLine("Null partition found at idx: " + i); + } + else + { + var xPartDevice = new Partition(xSATA, xPart.StartSector, xPart.SectorCount); + BlockDevice.BlockDevice.Devices.Add(xPartDevice); + Console.WriteLine("Found partition at idx: " + i); + } + } + } + } +} From 2aba248c711dededf18a96fe8b43a49a104ba371 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 11 Dec 2017 03:49:43 +0300 Subject: [PATCH 15/85] Update Global.cs --- source/Cosmos.HAL2/Global.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 5b505e7e4..9da72451f 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -48,14 +48,14 @@ namespace Cosmos.HAL // Currently ATA won't be initialized until we find a solution for the // Two Controllers initialize bug - //if (PCI.GetDeviceClass(0x01, 0x01) != null) - //{ - // mDebugger.Send("ATA Primary Master"); - // IDE ATA1 = new IDE(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); - // mDebugger.Send("ATA Secondary Master"); - // IDE ATA2 = new IDE(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); - // //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); - //} + if (PCI.GetDeviceClass(0x01, 0x01) != null) + { + mDebugger.Send("ATA Primary Master"); + IDE ATA1 = new IDE(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); + mDebugger.Send("ATA Secondary Master"); + IDE ATA2 = new IDE(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); + //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); + } if (PCI.GetDeviceClass(0x01, 0x06) != null) { Console.WriteLine("Initializing AHCI Controller"); From d6354bff7e56c5c1d280f010946a414c2a2f198a Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 21 Dec 2017 09:55:17 +0300 Subject: [PATCH 16/85] Update IDE.cs --- source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs index aa9264ae4..231939f45 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs @@ -5,7 +5,7 @@ namespace Cosmos.HAL.Drivers.PCI.Controllers { public class IDE { - public static void InitAta(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) + public IDE(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) { var xIO = aControllerID == Ata.ControllerIdEnum.Primary ? Core.Global.BaseIOGroups.ATA1 : Core.Global.BaseIOGroups.ATA2; var xATA = new AtaPio(xIO, aControllerID, aBusPosition); From ede864f3c9e81e53c7f2efe023ac8a680f0eb01b Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:05:34 +0300 Subject: [PATCH 17/85] [SATA] Optimize methods It is better to not to put 1500 lines in class were most of the lines are bunch of duplicated lines --- source/Cosmos.HAL2/BlockDevice/Sata.cs | 1058 +++++++----------------- 1 file changed, 285 insertions(+), 773 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Sata.cs index 12175ec71..5526e364c 100644 --- a/source/Cosmos.HAL2/BlockDevice/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Sata.cs @@ -2,841 +2,353 @@ using System; using System.Collections.Generic; using Cosmos.Core; using Cosmos.Core.Memory.Old; +using Cosmos.HAL.BlockDevice.Registers; using Cosmos.Debug.Kernel; -using Cosmos.HAL.Drivers.PCI.Controllers; -namespace Cosmos.HAL.BlockDevice +namespace Cosmos.HAL.BlockDevice.Ports { - #region Registers - - //TODO: Must be struct - public class GenericRegisters + public class SATA : StoragePort { - public uint CAP; - public uint GHC; - public uint IS; - public uint PI; - public uint VS; - public uint CCC_CTL; - public uint CCC_PORTS; - public uint EM_LOC; - public uint EM_CTL; - public uint CAP2; - public uint BOHC; - public byte[] Reserved0; - public byte[] VendorSpecific; - public PortRegisters[] Ports; - } - - public class PortRegisters - { - public uint CLB; - public uint CLBU; - public uint FB; - public uint FBU; - public uint IS; - public uint IE; - public uint CMD; - public uint Reserved0; - public uint TFD; - public uint SIG; - public uint SSTS; - public uint SCTL; - public uint SERR; - public uint SACT; - public uint CI; - public uint SNTF; - public uint FBS; - public uint[] Reserved1; - public uint[] VendorSpecific; - } - - public enum FISType - { - FIS_Type_RegisterH2D = 0x27, // Register FIS: Host to Device - FIS_Type_RegisterD2H = 0x34, // Register FIS: Device to Host - FIS_Type_DMA_Activate = 0x39, // DMA Activate - FIS_Type_DMA_Setup = 0x41, // DMA Setup: Device to Host - FIS_Type_Data = 0x46, // Data FIS: Bidirectional - FIS_Type_BIST = 0x58, // BIST - FIS_Type_PIO_Setup = 0x5F, // PIO Setup: Device to Host - FIS_Type_DeviceBits = 0xA1 // Device bits - } - - public class HBACommandHeader - { - // DWord 0 - public byte CFL; // 5 bits - public byte ATAPI; // 1 bit - public byte Write; // 1 = H2D | 0 = D2H // 1bit - public byte Prefetchable; // 1 bit - - public byte Reset; // 1 bit - public byte BIST; // 1 bit - public byte ClearBusy; // 1 bit - public byte Reserved0; // 1 bit - public byte PMP; // 4 bits - - public ushort PRDTL; // Physical region descriptor table length in entries - - // DWord 1 - public uint PRDBC; // Physical region descriptor byte count transferred - - public uint CTBA; // Command table descriptor base address - public uint CTBAU; // Command table descriptor base address upper 32 bits (4 bytes) - - // Reserved1; // [4] - } - - public class HBACommandTable - { - // 0x00 - public byte CFIS; // [64] // = 64 - - // 0x40 - public byte ACMD; // [16] // = 16 + 64 = 80 - - // 0x50 - public byte Reserved; // [48] // = 48 + 80 = 128 - - public HBAPRDTEntry[] PRDTEntry; // [1] // = 44 + 128 = 172 - } - public class HBAPRDTEntry - { - public uint DBA; // Data base address - public uint DBAU; // Data base address upper 32 bits - public uint Reserved0; - - public uint DBC; // Byte count, 4M max // 22 bits (2.75 Bytes) - public uint Reserved1; // Reserved // 9 bits - public int InterruptOnCompletion; // Interrupt on completion // 1 bit - } - - public enum PortType - { - Nothing = 0x00, - SATA = 0x01, - SATAPI = 0x02, - SEMB = 0x03, - PM = 0x04 - } - - public class FISRegisterH2D - { - public byte FISType; - - //public byte Options; - // Reserved - public byte IsCommand; - public byte Command; - public byte FeatureL; - - public byte LBA0; - public byte LBA1; - public byte LBA2; - public byte Device; - - public byte LBA3; - public byte LBA4; - public byte LBA5; - public byte FeatureH; - - public byte CountL; - public byte CountH; - public byte ICC; - public byte Control; - - public byte Res2; - - public static explicit operator byte(FISRegisterH2D v) - { - byte xValue = sizeof(byte) * 16; - return xValue; - } - } - - public class FISRegisterD2H - { - public byte FISType; - - //public byte Options; - // Reserved - //public byte InterruptBit; - // Rseerved - public byte Status; - public byte Error; - - public byte LBA0; - public byte LBA1; - public byte LBA2; - public byte Device; - - public byte LBA3; - public byte LBA4; - public byte LBA5; - // Reserved - - public byte CountL; - public byte CountH; - public byte ICC; - public ushort Res2; - // Reserved - public uint Res3; - // Reserved - - public static explicit operator byte(FISRegisterD2H v) - { - byte xValue = sizeof(byte) * 15; - return xValue; - } - } - - public class FISData - { - public byte FISType; - - public byte Payload; - } - #endregion - - #region Enums - public enum DriveSignature : uint // Drive Signature to identify what drive is plugged to Port X:X - { - SATADrive = 0x00000101, - PMDrive = 0x96690101, - SATAPIDrive = 0xEB140101, - SEMBDrive = 0xC33C0101, - NullDrive = 0xFFFFFFFF - } - - public enum InterfacePowerManagementStatus : uint // SATA Status: Interface Power Management Status - { - NotPresent = 0x00, - Active = 0x01, - Partial = 0x02, - Slumber = 0x06, - DeviceSleep = 0x08 - } - - public enum CurrentInterfaceSpeedStatus : uint // SATA Status: Current Interface Speed - { - NotPresent = 0x00, - Gen1Rate = 0x01, - Gen2Rate = 0x02, - Gen3Rate = 0x03 - } - - public enum DeviceDetectionStatus : uint // SATA Status: Device Detection Status - { - NotDetected = 0x00, - DeviceDetectedNoPhy = 0x01, - DeviceDetectedWithPhy = 0x03, - PhyOffline = 0x04 - } - - public enum ATADeviceStatus : uint - { - Busy = 0x80, - DRQ = 0x08 - } - - public enum CommandAndStatus : uint - { - ICC_Reserved0 = 0x0000000F, - ICC_DevSleep = 0x00000008, - ICC_Slumber = 0x00000006, - ICC_Partial = 0x00000002, - ICC_Active = 0x00000001, - ICC_Idle = 0x00000000, - ASP = (01 << 27), - ALPE = (01 << 26), - EnableATAPILED = (01 << 25), - ATAPIDevice = (01 << 24), - APSTE = (01 << 23), - FISSwitchPort = (01 << 22), - ExternalSATAPort = (01 << 21), - ColdPresenceDetect = (01 << 20), - MPSP = (01 << 19), - HotPlugCapPort = (01 << 18), - PortMultAttach = (01 << 17), - ColdPresenceState = (01 << 16), - CMDListRunning = (01 << 15), - FISRecieveRunning = (01 << 14), - MPSS = (01 << 13), - CurrentCMDSlot = (01 << 12), - Reserved0 = (01 << 07), - FISRecieveEnable = (01 << 04), - CMDListOverride = (01 << 03), - PowerOnDevice = (01 << 02), - SpinUpDevice = (01 << 01), - StartProccess = (01 << 00), - Null = 0xFFFF - } - - public enum InterruptStatus : int - { - ColdPortDetectStatus = (01 << 31), - TaskFileErrorStatus = (01 << 30), - HostBusFatalErrorStatus = (01 << 29), - HostBusDataErrorStatus = (01 << 28), - InterfaceFatalErrorStatus = (01 << 27), - InterfaceNFatalErrorStatus = (01 << 26), - OverflowStatus = (01 << 24), - IncorrectPMStatus = (01 << 23), - PhyRdyChangeStatus = (01 << 22), - DevMechanicalPresenceStatus = (01 << 07), - PortConnectChangeStatus = (01 << 06), - DescriptorProcessed = (01 << 05), - UnknownFISInterrupt = (01 << 04), - SetDeviceBitsInterrupt = (01 << 03), - DMASetupFISInterrupt = (01 << 02), - PIOSetupFISInterrupt = (01 << 01), - D2HRegFISInterrupt = (01 << 00), - Null = 0xFFFF - } - - public enum InterruptEnable : uint - { - OverflowEnable = (01 << 24), - IncorrectPMEnable = (01 << 23), - PhyRdyChangeInterruptEnable = (01 << 22), - DevMechanicalPresenceEnable = (01 << 07), - PortChangeInterruptEnable = (01 << 06), - DescProcessedInterruptEnable = (01 << 05), - UnknownFISInterruptEnable = (01 << 04), - SetDeviceBitsInterruptEnable = (01 << 03), - DMASetupFISInterruptEnable = (01 << 02), - PIOSetupFISInterruptEnable = (01 << 01), - D2HRegFISInterruptEnable = (01 << 00), - Null = 0xFFFF - } - - public enum SATACommands : uint - { - ReadPio = AtaPio.Cmd.ReadPio, - ReadPioExt = AtaPio.Cmd.ReadPioExt, - ReadDma = AtaPio.Cmd.ReadDma, - ReadDmaExt = AtaPio.Cmd.ReadDmaExt, - WritePio = AtaPio.Cmd.WritePio, - WritePioExt = AtaPio.Cmd.WritePioExt, - WriteDma = AtaPio.Cmd.WriteDma, - WriteDmaExt = AtaPio.Cmd.WriteDmaExt, - CacheFlush = AtaPio.Cmd.CacheFlush, - CacheFlushExt = AtaPio.Cmd.CacheFlushExt, - Packet = AtaPio.Cmd.Packet, - IdentifyPacket = AtaPio.Cmd.IdentifyPacket, - Identify = AtaPio.Cmd.Identify, - Read = AtaPio.Cmd.Read, - Eject = AtaPio.Cmd.Eject - } - - public enum Bases : uint { SATA = 0x00400000 } - #endregion - - public class SATA : BlockDevice - { - private static uint mPortLocation; - private static uint[] mPorts = new uint[32]; - - private static uint mABAR; - private static MemoryBlock mSATAMemory; internal static Debugger mSATADebugger = new Debugger("HAL", "SATA"); - public static GenericRegisters mGeneric; + public override PortType mPortType => PortType.SATA; + public override string mPortName => "SATA"; + public override uint mPortNumber => mPortReg.mPortNumber; - public List SATAPorts = new List(32); + public PortRegisters mPortReg; + public Core.MemoryGroup.SATA Mem; - public static InterfacePowerManagementStatus mIPM; - public static DeviceDetectionStatus mDET; - private int xPort; - private bool is64DMA; + // Constants + public const ulong RegularSectorSize = 512UL; - #region Registers - internal class Registers - { - public static PortRegisters PortRegisters(int aPortNumber) - { - mPortLocation = 0x100 + (0x80 * (uint)aPortNumber); - PortRegisters xPortReg = new PortRegisters(); - xPortReg.CLB = mSATAMemory[mPortLocation + 0x00]; - xPortReg.CLBU = mSATAMemory[mPortLocation + 0x04]; - xPortReg.FB = mSATAMemory[mPortLocation + 0x08]; - xPortReg.FBU = mSATAMemory[mPortLocation + 0x0C]; - xPortReg.IS = mSATAMemory[mPortLocation + 0x10]; - xPortReg.IE = mSATAMemory[mPortLocation + 0x14]; - xPortReg.CMD = mSATAMemory[mPortLocation + 0x18]; - xPortReg.Reserved0 = mSATAMemory[mPortLocation + 0x1C]; - xPortReg.TFD = mSATAMemory[mPortLocation + 0x20]; - xPortReg.SIG = mSATAMemory[mPortLocation + 0x24]; - xPortReg.SSTS = mSATAMemory[mPortLocation + 0x28]; - xPortReg.SCTL = mSATAMemory[mPortLocation + 0x2C]; - xPortReg.SERR = mSATAMemory[mPortLocation + 0x30]; - xPortReg.SACT = mSATAMemory[mPortLocation + 0x34]; - xPortReg.CI = mSATAMemory[mPortLocation + 0x38]; - xPortReg.SNTF = mSATAMemory[mPortLocation + 0x3C]; - xPortReg.FBS = mSATAMemory[mPortLocation + 0x40]; - xPortReg.Reserved1 = GetValueArray(0x44, 11); - xPortReg.VendorSpecific = GetValueArray(0x70, 4); - mIPM = (InterfacePowerManagementStatus)((byte)((xPortReg.SSTS >> 8) & 0x0F)); - mDET = (DeviceDetectionStatus)((byte)(xPortReg.SSTS & 0x0F)); - return xPortReg; - } - public static PortRegisters PortRegisters(int[] aPortsArray) - { - foreach (int xPortNumber in aPortsArray) - { - mPortLocation = 0x100 + (0x80 * (uint)xPortNumber); - PortRegisters xPortReg = new PortRegisters(); - xPortReg.CLB = mSATAMemory[mPortLocation + 0x00]; - xPortReg.CLBU = mSATAMemory[mPortLocation + 0x04]; - xPortReg.FB = mSATAMemory[mPortLocation + 0x08]; - xPortReg.FBU = mSATAMemory[mPortLocation + 0x0C]; - xPortReg.IS = mSATAMemory[mPortLocation + 0x10]; - xPortReg.IE = mSATAMemory[mPortLocation + 0x14]; - xPortReg.CMD = mSATAMemory[mPortLocation + 0x18]; - xPortReg.Reserved0 = mSATAMemory[mPortLocation + 0x1C]; - xPortReg.TFD = mSATAMemory[mPortLocation + 0x20]; - xPortReg.SIG = mSATAMemory[mPortLocation + 0x24]; - xPortReg.SSTS = mSATAMemory[mPortLocation + 0x28]; - xPortReg.SCTL = mSATAMemory[mPortLocation + 0x2C]; - xPortReg.SERR = mSATAMemory[mPortLocation + 0x30]; - xPortReg.SACT = mSATAMemory[mPortLocation + 0x34]; - xPortReg.CI = mSATAMemory[mPortLocation + 0x38]; - xPortReg.SNTF = mSATAMemory[mPortLocation + 0x3C]; - xPortReg.FBS = mSATAMemory[mPortLocation + 0x40]; - xPortReg.Reserved1 = GetValueArray(0x44, 11); - xPortReg.VendorSpecific = GetValueArray(0x70, 4); - return xPortReg; - } - PortRegisters mNullPort = new PortRegisters(); - return mNullPort; - } - - /// - /// Note: This method only work when SATA is initialized! - /// - public static int GetPortNumber() - { - foreach (int mPort in mPorts) - { - if (mPort == 1) - { - return mPort; // Return mPort SATA Type - } - else - { - // If mPort's value is not 1 then it is a CD/DVD Drive Port, Port Multiplier, SEMB Port or Nothing in the Port - } - } - return -1; - } - public static uint[] GetValueArray(uint aStartAddress, int aAmount) - { - uint[] FinishedArray = new uint[aAmount]; - - int i = 0; - for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) - { - while (i < aAmount) - { - FinishedArray[i] = mSATAMemory[ui]; - i++; - break; - } - } - return FinishedArray; - } - public static byte[] GetByteValueArray(uint aStartAddress, int aAmount) - { - byte[] FinishedArray = new byte[aAmount]; - - for (uint ui = aStartAddress; ui < aAmount; ui += 0x04) - { - for (int i = 0; i < aAmount; i++) - { - FinishedArray[i] = mSATAMemory.Bytes[ui]; - } - } - return FinishedArray; - } - } - #endregion - - public SATA(uint ABAROffset) + public SATA(PortRegisters aSATAPort) { + // Check if it is really a SATA Port! + if(aSATAPort.mPortType != PortType.SATA || (aSATAPort.CMD & (1U << 24)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Error]"); + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($" 0:{aSATAPort.mPortNumber} is not a SATA port!\n"); + return; + } + + Mem = new Core.MemoryGroup.SATA(); + + mPortReg = aSATAPort; + // Setting Offset arg to Global offset - mABAR = ABAROffset; - mSATAMemory = new MemoryBlock(mABAR, 0x10FF); - - mGeneric = new GenericRegisters - { - CAP = mSATAMemory[0x00], - GHC = mSATAMemory[0x04], - IS = mSATAMemory[0x08], - PI = mSATAMemory[0x0C], - VS = mSATAMemory[0x10], - CCC_CTL = mSATAMemory[0x14], - CCC_PORTS = mSATAMemory[0x18], - EM_LOC = mSATAMemory[0x1C], - EM_CTL = mSATAMemory[0x20], - CAP2 = mSATAMemory[0x24], - BOHC = mSATAMemory[0x28], - //Reserved0 = Registers.GetByteValueArray(0x2C, 29), - //VendorSpecific = Registers.GetByteValueArray(0xA0, 20), - Ports = new PortRegisters[32] - }; - while (((mSATAMemory[0x04] >> 31) & 1) == 0) ; - mBlockSize = 512; + mBlockSize = RegularSectorSize; mBlockCount = 256; - Console.WriteLine("-- 00 --"); - SearchForDisks(mGeneric); - } - - - private void SearchForDisks(GenericRegisters aGeneric) - { - // Search for disks - var xImplementedPort = aGeneric.PI; - var xPort = 0; - var xPortType = 0U; - while(xPort < 32) - { - if ((xImplementedPort & 1) != 0) - { - PortType PortType = CheckPortType(Registers.PortRegisters(xPort)); - var xPortString = "0:" + xPort; - if (PortType == PortType.SATA) // If Port Type was SATA. - { - Console.WriteLine("SATA drive at port " + xPortString + " found"); - Console.WriteLine("SATA Drive at port " + xPortString); - PortRebase(Registers.PortRegisters(xPort), xPort); - ushort ReadedBits = new ushort(); - SATAPorts.Add(xPort); - mSATADebugger.Send("Readen bits: " + ReadedBits); - xPortType = 0x01; - } - else if (PortType == PortType.SATAPI) // If Port Type was SATAPI. - { - Console.WriteLine("SATAPI drive at port " + xPortString + " found, which is not supported yet!"); - Console.WriteLine("CD/DVD Drive at port " + xPortString + " found, which is not supported yet!"); - xPortType = 0x02; - } - else if (PortType == PortType.SEMB) // If Port Type was SEMB. - { - //Console.WriteLine("SEMB drive at port " + xPortString + " found, which is not supported yet!"); - Console.WriteLine("SEMB Drive at port " + xPortString + " found, which is not supported yet!"); - xPortType = 0x03; - } - else if (PortType == PortType.PM) // If Port Type was Port Mulitplier. - { - //Console.WriteLine("Port Multiplier drive at port " + xPortString + " found, which is not supported yet!"); - Console.WriteLine("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); - xPortType = 0x04; - } - //else if (PortType == PortType.Nothing) // If Nothing in this Port. - //else // If Implemented Port value was not zero and non of the above. - } - mPorts[xPort] = xPortType; - xImplementedPort >>= 1; - xPort++; - } - } - - private PortType CheckPortType(PortRegisters Port) - { - DriveSignature xSignature = (DriveSignature)Port.SIG; - uint xSATAStatus = Port.SSTS; - - if (mIPM != InterfacePowerManagementStatus.Active) - return PortType.Nothing; - if (mDET != DeviceDetectionStatus.DeviceDetectedWithPhy) - return PortType.Nothing; - - switch (xSignature) - { - case DriveSignature.SATAPIDrive: - return PortType.SATAPI; - case DriveSignature.SEMBDrive: - return PortType.SEMB; - case DriveSignature.PMDrive: - return PortType.PM; - case DriveSignature.NullDrive: - return PortType.Nothing; - default: - return PortType.SATA; - } - } - - public void PortRebase(PortRegisters aPort, int aPortNumber) - { - StopCMD(aPort); - - var CLBAddress = Heap.MemAlloc(1024); - var FBAddress = Heap.MemAlloc(256); - Console.WriteLine(CLBAddress.ToString()); - mSATAMemory[mPortLocation] = CLBAddress; - new MemoryBlock(mSATAMemory[mPortLocation], 1024).Fill(0); - //if(is64DMA) - //{ - // mSATAMemory[mPortLocation + 0x04] |= CLBUAddress; - // new MemoryBlock(mSATAMemory[mPortLocation + 0x04], 1024).Fill(0); - //} + SendSATACommand(ATACommands.Identify); + UInt16[] xBuffer = new UInt16[256]; + System.Threading.Thread.Sleep(1000); + Mem.DataBlock.Read16(xBuffer); - mSATAMemory[mPortLocation + 0x08] = FBAddress; - new MemoryBlock(mSATAMemory[mPortLocation + 0x08], 256).Fill(0); - //if (is64DMA) - //{ - // mSATAMemory[mPortLocation + 0x0C] |= FBUAddress; - // new MemoryBlock(mSATAMemory[mPortLocation + 0x0C], 256).Fill(0); - //} + var xBlockCount48 = (xBuffer[102] << 32 | (xBuffer[101] << 16 | xBuffer[100])) - 1; + mBlockCount = (ulong)xBlockCount48; - GetCommandHeader(aPort, aPortNumber); // Rebasing Command Header - - StartCMD(aPort); } - public static HBACommandHeader[] GetCommandHeader(PortRegisters aPort, int aPortNumber) + public void SendSATACommand(ATACommands aCommand) { - HBACommandHeader[] xCMDHeader = new HBACommandHeader[32]; - for (int i = 0; i < xCMDHeader.Length; i++) + bool isIdentify = (aCommand == ATACommands.Identify); + + mPortReg.IS = unchecked((uint)-1); + + int xSlot = FindCMDSlot(); + if (xSlot == -1) return; + + HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); + xCMDHeader.CFL = 5; + xCMDHeader.PRDTL = (ushort)((isIdentify) ? 1 : 0); + xCMDHeader.Write = 0; + + xCMDHeader.CTBA = Heap.MemAlloc(256); + + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); + + if (isIdentify) { - xCMDHeader[i] = new HBACommandHeader(); - xCMDHeader[i].PRDTL = 8; // 8 prdt entries per command table - // 256 bytes per command table, 64+16+48+16*8 - xCMDHeader[i].CTBA = Heap.MemAlloc(256); - xCMDHeader[i].CTBAU = 0; - new MemoryBlock(xCMDHeader[i].CTBA, 256).Fill(0); - var xCMDHeaderMem = new MemoryBlock(mSATAMemory[mPortLocation + 0x00], 1024); - xCMDHeaderMem[0x02] = xCMDHeader[i].PRDTL; - xCMDHeaderMem[0x08] = xCMDHeader[i].CTBA << 7; - xCMDHeaderMem[0x0C] = xCMDHeader[i].CTBAU; - } - return xCMDHeader; - } + Console.WriteLine("Identify"); + xCMDTable.PRDTEntry = new HBAPRDTEntry[xCMDHeader.PRDTL]; + for (uint i = 0; i < xCMDTable.PRDTEntry.Length; i++) + { + xCMDTable.PRDTEntry[i] = new HBAPRDTEntry(xCMDHeader.CTBA + 0x80, i); + } - public void StartCMD(PortRegisters aPort) - { - while ((mSATAMemory[mPortLocation + 0x18] & (uint)CommandAndStatus.CMDListRunning) != 0) + var BaseAddress = Mem.DataBlock.Base; + xCMDTable.PRDTEntry[xCMDTable.PRDTEntry.Length - 1].DBA = BaseAddress - 2; + xCMDTable.PRDTEntry[xCMDTable.PRDTEntry.Length - 1].DBC = 511; + xCMDTable.PRDTEntry[xCMDTable.PRDTEntry.Length - 1].InterruptOnCompletion = 0; + } + + FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) { - //Console.WriteLine("Command list is already running"); - continue; + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)aCommand, + Device = 0, + }; + + int xSpin = 0; + do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSlot < 1000000); + + mPortReg.CI = 1U << xSlot; + + while (true) + { + if ((mPortReg.CI & (1 << xSlot)) == 0) + { + break; + } + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!\n"); + Console.ResetColor(); + return; + } } - Console.WriteLine("Starting Process"); - mSATAMemory[mPortLocation + 0x18] |= (uint)CommandAndStatus.FISRecieveEnable; - mSATAMemory[mPortLocation + 0x18] |= (uint)CommandAndStatus.StartProccess; + + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!\n"); + Console.ResetColor(); + return; + } + + Console.ForegroundColor = ConsoleColor.Green; + Console.Write("\n[Success]: "); + Console.Write("Command has been sent successfully!\n"); + Console.ResetColor(); + + while (mPortReg.CI != 0) ; + + return; } - public void StopCMD(PortRegisters aPort) + public void SendSATA24Command(ATACommands aCommand, uint aStart, uint aCount) { - Console.WriteLine("Stopping Process"); - mSATAMemory[mPortLocation + 0x18] &= ~(uint)CommandAndStatus.FISRecieveEnable; - mSATAMemory[mPortLocation + 0x18] &= ~(uint)CommandAndStatus.StartProccess; + mPortReg.IS = unchecked((uint)-1); - while ((mSATAMemory[mPortLocation + 0x18] & (uint)(CommandAndStatus.FISRecieveRunning | CommandAndStatus.CMDListRunning)) != 0) ; - } + int xSlot = FindCMDSlot(); + if (xSlot == -1) return; - private bool InternalTransfer(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer, bool aWrite = false) - { - //mSATAMemory[mPortLocation + 0x10] = unchecked((uint)-1); - new MemoryBlock(mSATAMemory.Base + mPortLocation + 0x10, sizeof(uint)).Fill(0); - int xSpin = 0; // Spin lock Timeout Counter - int xSlot = FindCMDSlot(aPort); - Console.WriteLine("My Slot: " + xSlot); - if (xSlot == -1) - return false; - - HBACommandHeader xCMDHeader = GetCommandHeader(aPort, Registers.GetPortNumber())[xSlot]; - //mSATAMemory[mPortLocation + 0x00] += (uint)xSlot; - xCMDHeader.CFL = (byte)(17 / sizeof(uint)); - xCMDHeader.Write = (aWrite ? (byte)1 : (byte)0); + HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); + xCMDHeader.CFL = 5; xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); - var xCMDHeaderMem = new MemoryBlock(mSATAMemory[mPortLocation + 0x00], 1024); - xCMDHeaderMem[0x00] = (uint)xCMDHeader.PRDTL << 16; - xCMDHeaderMem[0x00] = (uint)xCMDHeader.Write << 6; - xCMDHeaderMem[0x00] = (uint)xCMDHeader.CFL << 0; + xCMDHeader.Write = 0; - Console.WriteLine(xCMDHeaderMem[0x00].ToString()); - Console.WriteLine(xCMDHeaderMem.Base.ToString()); - Console.WriteLine(xCMDHeader.CTBA.ToString()); + xCMDHeader.CTBA = Heap.MemAlloc(256); - Console.WriteLine("Before Command Table Initialization"); - HBACommandTable xCMDTable = new HBACommandTable(); // xCMDHeader.CTBA - var xCMDTableMem = new MemoryBlock(xCMDHeader.CTBA, 256); - xCMDTableMem.Fill(0, (((158 / 8) + (xCMDHeader.PRDTL - 1U)) * 24), 0); - xCMDTable.PRDTEntry = new HBAPRDTEntry[1]; - xCMDTable.PRDTEntry[0] = new HBAPRDTEntry(); - Console.WriteLine("After Command Table Initialization"); + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); - Console.WriteLine("Before MemAlloc"); - var xDataBA = Heap.MemAlloc(sizeof(ushort)); - Console.WriteLine(xDataBA); - var xDataMem = new MemoryBlock(xDataBA, sizeof(ushort)); - xDataMem[0x00] = aBuffer; - Console.WriteLine(xDataMem[0x00]); - Console.WriteLine("After MemAlloc"); - uint i = 1; - while (i - 1 < xCMDHeader.PRDTL - 1) + xCMDTable.PRDTEntry = new HBAPRDTEntry[xCMDHeader.PRDTL]; + for (uint i = 0; i < xCMDTable.PRDTEntry.Length; i++) { + xCMDTable.PRDTEntry[i] = new HBAPRDTEntry(xCMDHeader.CTBA + 0x80, i); + } - Console.WriteLine("On Loop Command Table Initialization"); - xCMDTable.PRDTEntry[i - 1].DBA = (uint)(xDataBA); - xCMDTable.PRDTEntry[i - 1].DBC = 8 * 1024 - 1; - xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion = 1; - xCMDTableMem[(0x80 * i) + 0x00] = xCMDTable.PRDTEntry[i - 1].DBA << 1; - xCMDTableMem[(0x80 * i) + 0x0C] = xCMDTable.PRDTEntry[i - 1].DBC; - xCMDTableMem[(0x80 * i) + 0x0C] = (uint)xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion << 31; - aBuffer += 4 * 1024; + uint BaseAddress = Mem.DataBlock.Base; + for (uint i = 0; i < xCMDHeader.PRDTL - 1; i++) + { + xCMDTable.PRDTEntry[i].DBA = BaseAddress; + xCMDTable.PRDTEntry[i].DBC = 8191; + xCMDTable.PRDTEntry[i].InterruptOnCompletion = 0; + BaseAddress += 8192; aCount -= 16; - i++; - } - Console.WriteLine("Last Command Table Initialization"); - - // Last entry - xCMDTable.PRDTEntry[i - 1].DBA = xDataBA; - xCMDTable.PRDTEntry[i - 1].DBC = (aCount << 9) - 1; - xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion = 1; - xCMDTableMem[(0x80 * i) + 0x00] = xCMDTable.PRDTEntry[i - 1].DBA << 1; - xCMDTableMem[(0x80 * i) + 0x0C] = xCMDTable.PRDTEntry[i - 1].DBC; - xCMDTableMem[(0x80 * i) + 0x0C] = (uint)xCMDTable.PRDTEntry[i - 1].InterruptOnCompletion << 31; - - Console.WriteLine("Setup Command FIS"); - // Setup the command - uint xCMDFISAddress = Heap.MemAlloc(0x10); - - xCMDTableMem[0x00] = (uint)xCMDFISAddress; - FISRegisterH2D xCMDFIS = new FISRegisterH2D(); - xCMDFIS.FISType = (byte)FISType.FIS_Type_RegisterH2D; - xCMDFIS.IsCommand = 1; - xCMDFIS.Command = (aWrite ? (byte)SATACommands.WriteDmaExt : (byte)SATACommands.ReadDmaExt); - - xCMDFIS.LBA0 = (byte)aStartLow; - xCMDFIS.LBA1 = (byte)(aStartLow >> 8); - xCMDFIS.LBA2 = (byte)(aStartLow >> 16); - xCMDFIS.Device = 1 << 6; // LBA Mode - - xCMDFIS.LBA3 = 0x00; - xCMDFIS.LBA4 = 0x00; - xCMDFIS.LBA5 = 0x00; - - xCMDFIS.CountL = (byte)(aCount & 0xFF); - xCMDFIS.CountH = (byte)((aCount >> 8) & 0xFF); - var xCMDFISMem = new MemoryBlock((uint)xCMDTableMem[0x00], 0x10); - Console.WriteLine("Setting values to memory offset: " + xCMDTableMem[0x00]); - - // DWord 0 - xCMDFISMem[0x00] = (byte)(xCMDFIS.FISType); // FIS Type - xCMDFISMem[0x00] = (byte)(xCMDFIS.IsCommand >> 15); // IsCommand(or)Control - xCMDFISMem[0x00] = (byte)(xCMDFIS.Command >> 16); // Command register - - // DWord 1 - xCMDFISMem[0x04] = (byte)(xCMDFIS.LBA0); // LBA Low register - xCMDFISMem[0x04] = (byte)(xCMDFIS.LBA1 >> 8); // LBA Mid register - xCMDFISMem[0x04] = (byte)(xCMDFIS.LBA2 >> 16); // LBA Hgh register - xCMDFISMem[0x04] = (byte)(xCMDFIS.Device >> 24); // Device register - - // DWord 2 - xCMDFISMem[0x08] = (byte)(xCMDFIS.LBA3); // LBA register - xCMDFISMem[0x08] = (byte)(xCMDFIS.LBA4 >> 8); // LBA register - xCMDFISMem[0x08] = (byte)(xCMDFIS.LBA5 >> 16); // LBA register - - // DWord 3 - xCMDFISMem[0x0C] = (byte)(xCMDFIS.CountL); // Count Low register - xCMDFISMem[0x0C] = (byte)(xCMDFIS.CountH); // Count Hgh register - - Console.WriteLine(Cosmos.Common.Extensions.ToHexString.ToHex(new MemoryBlock(xCMDFISAddress, 0x10)[0x00])); - - Console.WriteLine("Spinning on xSpin"); - do - { - xSpin++; - Console.WriteLine(xSpin); - } while (((mSATAMemory[mPortLocation + 0x20] & (uint)(ATADeviceStatus.Busy | ATADeviceStatus.DRQ)) > 0 && xSpin < 1000000)); - - if (xSpin == 1000000) - { - Console.WriteLine("Port timed out"); - return false; } - mSATAMemory[mPortLocation + 0x38] = (uint)(1 << xSlot); // Issue with Command + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = BaseAddress - 2; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = 512 * aCount - 1; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 0; - // Wait for Completion - do + FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) { - // If error occured - if (((mSATAMemory[mPortLocation + 0x10] >> 30) & 1) != 0) + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)aCommand, + + LBA0 = (byte)(aStart), + LBA1 = (byte)(aStart >> 8), + LBA2 = (byte)(aStart >> 16), + Device = (byte)(0x40 | ((aStart >> 24) & 0x0F)), + + CountL = (byte)(aCount & 0xFF) + }; + + int xSpin = 0; + do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSlot < 1000000); + + mPortReg.CI = 1U << xSlot; + + while (true) + { + if ((mPortReg.CI & (1 << xSlot)) == 0) { - Console.WriteLine("Write or Read Disk Error!"); - return false; + break; + } + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!\n"); + Console.ResetColor(); + return; } - } while (((mSATAMemory[mPortLocation + 0x38] >> xSlot) & 1) != 0); - - // Fill in the data - if (!aWrite) - { - aBuffer = xDataMem.Words[0x00]; } - return true; + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!\n"); + Console.ResetColor(); + return; + } + + Console.ForegroundColor = ConsoleColor.Green; + Console.Write("\n[Success]: "); + Console.Write("Command has been sent successfully!\n"); + Console.ResetColor(); + + while (mPortReg.CI != 0) ; + + return; } - public bool Read(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer) - => InternalTransfer(aPort, aStartLow, aStartHigh, aCount, aBuffer, false); + public void SendSATA48Command(ATACommands aCommand, ulong aStart, uint aCount) + { + mPortReg.IS = unchecked((uint)-1); - public bool Write(PortRegisters aPort, uint aStartLow, uint aStartHigh, uint aCount, ushort aBuffer) - => InternalTransfer(aPort, aStartLow, aStartHigh, aCount, aBuffer, true); + int xSlot = FindCMDSlot(); + if (xSlot == -1) return; + + HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); + xCMDHeader.CFL = 5; + xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); + xCMDHeader.Write = 0; - public int FindCMDSlot(PortRegisters aPort) + xCMDHeader.CTBA = Heap.MemAlloc(256); + + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); + + xCMDTable.PRDTEntry = new HBAPRDTEntry[xCMDHeader.PRDTL]; + for (uint i = 0; i < xCMDTable.PRDTEntry.Length; i++) + { + xCMDTable.PRDTEntry[i] = new HBAPRDTEntry(xCMDHeader.CTBA + 0x80, i); + } + + uint BaseAddress = Mem.DataBlock.Base; + for (uint i = 0; i < xCMDHeader.PRDTL - 1; i++) + { + xCMDTable.PRDTEntry[i].DBA = BaseAddress; + xCMDTable.PRDTEntry[i].DBC = 8191; + xCMDTable.PRDTEntry[i].InterruptOnCompletion = 0; + BaseAddress += 8192; + aCount -= 16; + } + + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = BaseAddress - 2; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = 512 * aCount - 1; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 0; + + FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) + { + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)aCommand, + + LBA0 = (byte)(aStart), + LBA1 = (byte)(aStart >> 8), + LBA2 = (byte)(aStart >> 16), + LBA3 = (byte)(aStart >> 24), + LBA4 = (byte)(aStart >> 32), + LBA5 = (byte)(aStart >> 40), + Device = 0x40, + + CountL = (byte)(aCount & 0xFF), + CountH = (byte)((aCount >> 8)) + }; + + int xSpin = 0; + do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSlot < 1000000); + + mPortReg.CI = 1U << xSlot; + + while (true) + { + if ((mPortReg.CI & (1 << xSlot)) == 0) + { + break; + } + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!\n"); + Console.ResetColor(); + return; + } + } + + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!\n"); + Console.ResetColor(); + return; + } + + Console.ForegroundColor = ConsoleColor.Green; + Console.Write("\n[Success]: "); + Console.Write("Command has been sent successfully!\n"); + Console.ResetColor(); + + while (mPortReg.CI != 0) ; + + return; + } + + public int FindCMDSlot() { // If not set in SACT and CI, the slot is free - var xSlots = (mSATAMemory[mPortLocation + 0x34] | mSATAMemory[mPortLocation + 0x38]); - //for(int i = 0; i < aPort.VendorSpecific.Length; i++) - ////mSATADebugger.SendInternalNumber(aPort.VendorSpecific[i]); - for (int i = 0; i < 32; i++) + var xSlots = (mPortReg.SACT | mPortReg.CI); + + for (int i = 1; i < 32; i++) { if ((xSlots & 1) == 0) - { return i; - } xSlots >>= 1; } - //Console.WriteLine("Cannot find free Command list Entry"); - return -1; - } - public SATA(int xPort) - { + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("\n[Error]: "); + Console.Write("Cannot find a free command slot!\n"); + Console.ResetColor(); + return -1; } public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) { - CheckDataSize(aData, aBlockCount); - if(SATAPorts.Count > 0) - { - var xPort = Registers.PortRegisters(SATAPorts[0]); - for(int i = 0; i < aData.Length; i += 2) - { - ushort xData = (ushort)((aData[i + 1] << 8) | aData[i]); - Read(xPort, (uint)aBlockNo, 0, (uint)aBlockCount, xData); - for (int ui = 0; ui < 200; ui++) ; - aData[i+0] = (byte)(xData); - aData[i+1] = (byte)(xData >> 8); - } - } + SendSATA48Command(ATACommands.ReadDmaExt, (uint)aBlockNo, (uint)aBlockCount); + System.Threading.Thread.Sleep(500); + Mem.DataBlock.Read8(aData); + foreach (byte xData in aData) + mSATADebugger.SendNumber(xData); } public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) { - CheckDataSize(aData, aBlockCount); - var xPort = Registers.PortRegisters(SATAPorts[0]); - for (int i = 0; i < aData.Length; i += 2) - { - ushort xData = (ushort)((aData[i + 1] << 8) | aData[i]); - Write(xPort, (uint)aBlockNo, 0, (uint)aBlockCount, xData); - for (int ui = 0; ui < 200; ui++) ; - } - // Might not work for some reasons :| + Mem.DataBlock.Write8(aData); + SendSATA48Command(ATACommands.WriteDmaExt, (uint)(aBlockNo), (uint)aBlockCount); + SendSATACommand(ATACommands.CacheFlush); } } } From 8cfa9c2c33a3d4537f3788c8b94826b72699e743 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:07:13 +0300 Subject: [PATCH 18/85] [AHCI] Read other ports and initialize them Currently, my driver can't read from sector :( --- .../Drivers/PCI/Controllers/AHCI.cs | 396 ++++++++++++++++-- 1 file changed, 360 insertions(+), 36 deletions(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs index c71bf35e8..5c4bfd9a0 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs @@ -1,58 +1,382 @@ using System; +using System.Collections.Generic; using Cosmos.HAL; using Cosmos.Debug.Kernel; using Cosmos.HAL.BlockDevice; +using Cosmos.HAL.BlockDevice.Ports; +using Cosmos.HAL.BlockDevice.Registers; +using Cosmos.Core; +using Cosmos.Core.Memory.Old; -namespace Cosmos.HAL.Drivers.PCI.Controllers +namespace Cosmos.HAL.BlockDevice { - public class AHCI + public class AHCI : Drivers.PCIDriver { - internal Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); + internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); + internal static PCIDevice xDevice = HAL.PCI.GetDevice(0x001, 0x0006); - public AHCI(uint aABARAddress) + private static List mPorts = new List(); + private static GenericRegisters mGeneric; + private static ulong mABAR; + + // Capabilities + #region Capabilities + private static bool Supports64bitAddressing; + private static bool SupportsNativeCommandQueuing; + private static bool SupportsSNotificationRegister; + private static bool SupportsMechanicalPresenceSwitch; + private static bool SupportsStaggeredSpinup; + private static bool SupportsAggressiveLinkPowerManagement; + private static bool SupportsActivityLED; + private static bool SupportsCommandListOverride; + private static uint InterfaceSpeedSupport; + private static bool SupportsAHCIModeOnly; + private static bool SupportsPortMutliplier; + private static bool FISBasedSwitchingSupported; + private static bool PIOMultipleDRQBlock; + private static bool SlumberStateCapable; + private static bool PartialStateCapable; + private static uint NumOfCommandSlots; + private static bool CommandCompletionCoalsecingSupported; + private static bool EnclosureManagementSupported; + private static bool SupportsExternalSATA; + private static uint NumOfPorts; + #endregion + + // Constants + public const ulong RegularSectorSize = 512UL; + + // Informations + public string SerialNo; + public string Version { - var xSATA = new SATA(aABARAddress); - var xMBRData = new byte[512]; - Console.WriteLine("Before"); - xSATA.ReadBlock(0UL, 1U, xMBRData); - Console.WriteLine(xMBRData[0]); - Console.WriteLine(xMBRData[1]); - Console.WriteLine(xMBRData[2]); - Console.WriteLine(xMBRData[3]); - Console.WriteLine(xMBRData[4]); - Console.WriteLine("Done reading"); - var xMBR = new MBR(xMBRData); + get => ((byte)mGeneric.AHCIVersion >> 24) + (byte)(mGeneric.AHCIVersion >> 16) + "." + (byte)(mGeneric.AHCIVersion >> 8) + ((byte)(mGeneric.AHCIVersion) > 0 ? "." + (byte)mGeneric.AHCIVersion : ""); + } - if (xMBR.EBRLocation != 0) + internal static void InitDriver() + { + if (xDevice != null) { - // EBR Detected! - var xEBRData = new byte[512]; - xSATA.ReadBlock(xMBR.EBRLocation, 1U, xEBRData); - var xEBR = new EBR(xEBRData); - for (int i = 0; i < xEBR.Partitions.Count; i++) - { - //var xPart = xEBR.Partitions[i]; - //var xPartDevice = new Partition(xSATA, xPart.StartSector, xPart.SectorCount); - //Devices.Add(xPartDevice); - } + AHCI Driver = new AHCI(xDevice); } + } - mAHCIDebugger.Send("Number of MBR partitions found: "); - mAHCIDebugger.SendNumber(xMBR.Partitions.Count); - for (int i = 0; i < xMBR.Partitions.Count; i++) + internal override PCIDevice GetDevice() => xDevice; + + public AHCI(PCIDevice aAHCIDevice) + { + aAHCIDevice.EnableBusMaster(true); + aAHCIDevice.EnableMemory(true); + + mABAR = aAHCIDevice.BaseAddressBar[5].BaseAddress; + mGeneric = new GenericRegisters(aAHCIDevice.BaseAddressBar[5].BaseAddress); + mGeneric.GlobalHostControl |= (1U << 31); + + GetCapabilities(); + mPorts.Capacity = (int)NumOfPorts; + GetPorts(); + + foreach(StoragePort xPort in mPorts) { - var xPart = xMBR.Partitions[i]; - if (xPart == null) + if(xPort.mPortType == PortType.SATA) { - Console.WriteLine("Null partition found at idx: " + i); + mAHCIDebugger.Send($"{xPort.mPortName} Port 0:{xPort.mPortNumber}"); + var xMBRData = new byte[512]; + xPort.ReadBlock(0UL, 1U, xMBRData); + var xMBR = new MBR(xMBRData); + + if (xMBR.EBRLocation != 0) + { + // EBR Detected! + mAHCIDebugger.Send("EBR Detected within MBR code"); + var xEBRData = new byte[512]; + xPort.ReadBlock(xMBR.EBRLocation, 1U, xEBRData); + var xEBR = new EBR(xEBRData); + for (int i = 0; i < xEBR.Partitions.Count; i++) + { + //var xPart = xEBR.Partitions[i]; + //var xPartDevice = new Partition(xSATA, xPart.StartSector, xPart.SectorCount); + //Devices.Add(xPartDevice); + } + } + + mAHCIDebugger.Send($"Number of MBR partitions found on port 0:{xPort.mPortNumber}: "); + mAHCIDebugger.SendNumber(xMBR.Partitions.Count); + for (int i = 0; i < xMBR.Partitions.Count; i++) + { + var xPart = xMBR.Partitions[i]; + if (xPart == null) + { + Console.WriteLine("Null partition found at idx: " + i); + } + else + { + var xPartDevice = new Partition(xPort, xPart.StartSector, xPart.SectorCount); + BlockDevice.Devices.Add(xPartDevice); + Console.WriteLine("Found partition at idx: " + i); + } + } } - else + else if (xPort.mPortType == PortType.SATAPI) { - var xPartDevice = new Partition(xSATA, xPart.StartSector, xPart.SectorCount); - BlockDevice.BlockDevice.Devices.Add(xPartDevice); - Console.WriteLine("Found partition at idx: " + i); + mAHCIDebugger.Send($"{xPort.mPortName} Port 0:{xPort.mPortNumber}"); + } } } + + private void Wait(int microsecondsTimeout) + { + byte xVoid; + for (int i = 0; i < microsecondsTimeout; i++) + { + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; + } + } + + private void GetCapabilities() + { + NumOfPorts = mGeneric.Capabilities & 0x1F; + SupportsExternalSATA = Convert.ToBoolean(mGeneric.Capabilities >> 5 & 1); + EnclosureManagementSupported = Convert.ToBoolean(mGeneric.Capabilities >> 6 & 1); + CommandCompletionCoalsecingSupported = Convert.ToBoolean(mGeneric.Capabilities >> 7 & 1); + NumOfCommandSlots = mGeneric.Capabilities >> 8 & 0x1F; + PartialStateCapable = Convert.ToBoolean(mGeneric.Capabilities >> 13 & 1); + SlumberStateCapable = Convert.ToBoolean(mGeneric.Capabilities >> 14 & 1); + PIOMultipleDRQBlock = Convert.ToBoolean(mGeneric.Capabilities >> 15 & 1); + FISBasedSwitchingSupported = Convert.ToBoolean(mGeneric.Capabilities >> 16 & 1); + SupportsPortMutliplier = Convert.ToBoolean(mGeneric.Capabilities >> 17 & 1); + SupportsAHCIModeOnly = Convert.ToBoolean(mGeneric.Capabilities >> 18 & 1); + InterfaceSpeedSupport = mGeneric.Capabilities >> 20 & 0x0F; + SupportsCommandListOverride = Convert.ToBoolean(mGeneric.Capabilities >> 24 & 1); + SupportsActivityLED = Convert.ToBoolean(mGeneric.Capabilities >> 25 & 1); + SupportsAggressiveLinkPowerManagement = Convert.ToBoolean(mGeneric.Capabilities >> 26 & 1); + SupportsStaggeredSpinup = Convert.ToBoolean(mGeneric.Capabilities >> 27 & 1); + SupportsMechanicalPresenceSwitch = Convert.ToBoolean(mGeneric.Capabilities >> 28 & 1); + SupportsSNotificationRegister = Convert.ToBoolean(mGeneric.Capabilities >> 29 & 1); + SupportsNativeCommandQueuing = Convert.ToBoolean(mGeneric.Capabilities >> 30 & 1); + Supports64bitAddressing = Convert.ToBoolean(mGeneric.Capabilities >> 31 & 1); + } + + private void GetPorts() + { + // Search for disks + var xImplementedPort = mGeneric.ImplementedPorts; + var xPort = 0; + while (xPort < NumOfPorts) + { + if ((xImplementedPort & 1) != 0) + { + PortRegisters xPortReg = new PortRegisters((uint)mABAR + 0x100 + (uint)(0x80 * xPort), (uint)xPort); + PortType PortType = CheckPortType(xPortReg); + xPortReg.mPortType = PortType; + var xPortString = "0:" + ((xPort.ToString().Length <= 1) ? xPort.ToString().PadLeft(1, '0') : xPort.ToString()); + if (PortType == PortType.SATA) // If Port Type was SATA. + { + mAHCIDebugger.Send("SATA"); + Console.WriteLine("Initializing Port " + xPortString + " with type SATA"); + UInt16[] xSectorData = new UInt16[256]; + PortRebase(xPortReg, (uint)xPort); + SATA xSATAPort = new SATA(xPortReg); + mPorts.Add(xSATAPort); + } + else if (PortType == PortType.SATAPI) // If Port Type was SATAPI. + { + mAHCIDebugger.Send("SATAPI"); + Console.WriteLine("Initializing Port " + xPortString + " with type Serial ATAPI"); + //PortRebase(xPortReg, (uint)xPort); + //SATAPI xSATAPIPort = new SATAPI(xPortReg); + //mPorts.Add(xSATAPIPort); + } + else if (PortType == PortType.SEMB) // If Port Type was SEMB. + { + //Console.WriteLine("SEMB drive at port " + xPortString + " found, which is not supported yet!"); + Console.WriteLine("SEMB Drive at port " + xPortString + " found, which is not supported yet!"); + } + else if (PortType == PortType.PM) // If Port Type was Port Mulitplier. + { + //Console.WriteLine("Port Multiplier drive at port " + xPortString + " found, which is not supported yet!"); + Console.WriteLine("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); + } + else if (PortType == PortType.Nothing) + mAHCIDebugger.Send("No drive found at port: " + xPortString); + else + mAHCIDebugger.Send("Unknown drive found with signature: 0x" + xPortReg.SIG);// If Implemented Port value was not zero and non of the above. + } + xImplementedPort >>= 1; + xPort++; + } + } + + private PortType CheckPortType(PortRegisters aPort) + { + var xIPM = (InterfacePowerManagementStatus)((aPort.SSTS >> 8) & 0x0F); + var xSPD = (CurrentInterfaceSpeedStatus)((aPort.SSTS >> 4) & 0x0F); + var xDET = (DeviceDetectionStatus)(aPort.SSTS & 0x0F); + var xSignature = aPort.SIG; + //var LBALow = (byte)(Port.SIG >> 08); + //var LBAMedium = (byte)(Port.SIG >> 16); + //var LBAHigh = (byte)(Port.SIG >> 24); + + if (xIPM != InterfacePowerManagementStatus.Active) + return PortType.Nothing; + if (xDET != DeviceDetectionStatus.DeviceDetectedWithPhy) + return PortType.Nothing; + + switch (xSignature >> 16) + { + case 0xEB14: return PortType.SATAPI; + case 0xC33C: return PortType.SEMB; + case 0x9669: return PortType.PM; + case 0xFFFF: return PortType.Nothing; + default: return PortType.SATA; + } + } + + private void PortRebase(PortRegisters aPort, uint aPortNumber) + { + mAHCIDebugger.Send("Stop"); + if (!StopCMD(aPort)) aPort.SCTL = 1; + + //Check for Command Process + mAHCIDebugger.SendNumber((aPort.CMD & 1)); + mAHCIDebugger.SendNumber((aPort.CMD >> 4) & 1); + mAHCIDebugger.SendNumber((aPort.CMD >> 14) & 1); + mAHCIDebugger.SendNumber((aPort.CMD >> 15) & 1); + + mAHCIDebugger.Send("CLB"); + ulong mCLBAddress = Heap.MemAlloc(1024); + aPort.CLB = (uint)mCLBAddress & 0xFFFFFFFF; + //aPort.CLBU = (uint)((mCLBAddress >> 32)) & 0xFFFFFFFF; + //if(is64DMA) + //{ + // mSATAMemory[mPortLocation + 0x04] |= CLBUAddress; + // new MemoryBlock(mSATAMemory[mPortLocation + 0x04], 1024).Fill(0); + //} + mAHCIDebugger.SendNumber((aPort.CMD & 1)); + mAHCIDebugger.SendNumber((aPort.CMD >> 4) & 1); + mAHCIDebugger.SendNumber((aPort.CMD >> 14) & 1); + mAHCIDebugger.SendNumber((aPort.CMD >> 15) & 1); + mAHCIDebugger.Send("FB"); + var mFBAddress = Heap.MemAlloc(256); + aPort.FB = mFBAddress; + + aPort.SERR = 1; + aPort.IS = 0; + aPort.IE = 0; + //aPort.FBU = 0; + new MemoryBlock(aPort.CLB, 1024).Fill(0); + new MemoryBlock(aPort.FB, 256).Fill(0); + //if (is64DMA) + //{ + // mSATAMemory[mPortLocation + 0x0C] |= FBUAddress; + // new MemoryBlock(mSATAMemory[mPortLocation + 0x0C], 256).Fill(0); + //} + + mAHCIDebugger.Send("GetCommandHeader"); + GetCommandHeader(aPort); // Rebasing Command Header + + mAHCIDebugger.Send("Start"); + StartCMD(aPort); + mAHCIDebugger.SendNumber((aPort.CMD & 1)); + mAHCIDebugger.SendNumber((aPort.CMD >> 4) & 1); + mAHCIDebugger.SendNumber((aPort.CMD >> 14) & 1); + mAHCIDebugger.SendNumber((aPort.CMD >> 15) & 1); + aPort.IS = 0; + aPort.IE = 0xFFFFFFFF; + mAHCIDebugger.Send("Finished!"); + } + + private static HBACommandHeader[] GetCommandHeader(PortRegisters aPort) + { + var xCTBAAddress = Heap.MemAlloc(256); + HBACommandHeader[] xCMDHeader = new HBACommandHeader[32]; + for (uint i = 0; i < xCMDHeader.Length; i++) + { + xCMDHeader[i] = new HBACommandHeader(aPort.CLB, i) + { + PRDTL = 8, // 8 prdt entries per command table + // 256 bytes per command table, 64+16+48+16*8 + CTBA = xCTBAAddress + (256 * i), + //TODO: Use the below register as the upper base address if HBA + // supports S64A (64-bit Addressing) + CTBAU = 0 + }; + new MemoryBlock(xCMDHeader[i].CTBA, 256).Fill(0); + } + return xCMDHeader; + } + + private void StartCMD(PortRegisters aPort) + { + int xSpin; + for (xSpin = 0; xSpin < 101; xSpin++) + { + if ((aPort.CMD & (uint)CommandAndStatus.CMDListRunning) == 0) break; + Wait(5000); + } + if (xSpin == 101) return; + + aPort.CMD |= (1 << 4); + aPort.CMD |= (1 << 0); + } + + private bool StopCMD(PortRegisters aPort) + { + int xSpin; + aPort.CMD &= ~(1U << 0); //Bit 0 + + for (xSpin = 0; xSpin < 101; xSpin++) + { + if ((aPort.CMD & (uint)CommandAndStatus.CMDListRunning) == 0) break; + Wait(5000); + } + if (xSpin == 101) return false; + + for (xSpin = 0; xSpin < 101; xSpin++) + { + if ((aPort.CI == 0)) break; + Wait(50); + } + if (xSpin == 101) return false; + + aPort.CMD &= ~(1U << 4); //Bit 4 + + if (SupportsCommandListOverride) + { + if ((aPort.TFD & (uint)ATADeviceStatus.Busy) != 0) + { + aPort.CMD |= (1U << 3); + } + } + + for (xSpin = 0; xSpin < 101; xSpin++) + { + if ((aPort.CMD & (uint)CommandAndStatus.CMDListRunning) == 0 && + (aPort.CMD & (uint)CommandAndStatus.FISRecieveRunning) == 0 && + (aPort.CMD & (uint)CommandAndStatus.StartProccess) == 0 && + (aPort.CMD & (uint)CommandAndStatus.FISRecieveEnable) == 0) break; + Wait(5000); + } + if (xSpin == 101) + { + if (SupportsCommandListOverride) + aPort.CMD |= (1U << 3); + else + aPort.CMD &= ~(1U << 3); + return false; + } + + return true; + } } } From d3c76735261af411a8d5b49265358da1218a6b77 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:12:06 +0300 Subject: [PATCH 19/85] [AHCI] Remove debug messages --- .../Drivers/PCI/Controllers/AHCI.cs | 47 +++---------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs index 5c4bfd9a0..a79046117 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs @@ -80,7 +80,7 @@ namespace Cosmos.HAL.BlockDevice { if(xPort.mPortType == PortType.SATA) { - mAHCIDebugger.Send($"{xPort.mPortName} Port 0:{xPort.mPortNumber}"); + mAHCIDebugger.Send($"{xPort.mPortName} Port [0:{xPort.mPortNumber}]"); var xMBRData = new byte[512]; xPort.ReadBlock(0UL, 1U, xMBRData); var xMBR = new MBR(xMBRData); @@ -88,7 +88,6 @@ namespace Cosmos.HAL.BlockDevice if (xMBR.EBRLocation != 0) { // EBR Detected! - mAHCIDebugger.Send("EBR Detected within MBR code"); var xEBRData = new byte[512]; xPort.ReadBlock(xMBR.EBRLocation, 1U, xEBRData); var xEBR = new EBR(xEBRData); @@ -100,7 +99,7 @@ namespace Cosmos.HAL.BlockDevice } } - mAHCIDebugger.Send($"Number of MBR partitions found on port 0:{xPort.mPortNumber}: "); + mAHCIDebugger.Send($"Number of MBR partitions in port [0:{xPort.mPortNumber}]: "); mAHCIDebugger.SendNumber(xMBR.Partitions.Count); for (int i = 0; i < xMBR.Partitions.Count; i++) { @@ -120,7 +119,7 @@ namespace Cosmos.HAL.BlockDevice else if (xPort.mPortType == PortType.SATAPI) { mAHCIDebugger.Send($"{xPort.mPortName} Port 0:{xPort.mPortNumber}"); - + // TODO: Implement ISO-9660 or UDF and Fix SATAPI } } } @@ -182,7 +181,6 @@ namespace Cosmos.HAL.BlockDevice var xPortString = "0:" + ((xPort.ToString().Length <= 1) ? xPort.ToString().PadLeft(1, '0') : xPort.ToString()); if (PortType == PortType.SATA) // If Port Type was SATA. { - mAHCIDebugger.Send("SATA"); Console.WriteLine("Initializing Port " + xPortString + " with type SATA"); UInt16[] xSectorData = new UInt16[256]; PortRebase(xPortReg, (uint)xPort); @@ -199,12 +197,10 @@ namespace Cosmos.HAL.BlockDevice } else if (PortType == PortType.SEMB) // If Port Type was SEMB. { - //Console.WriteLine("SEMB drive at port " + xPortString + " found, which is not supported yet!"); Console.WriteLine("SEMB Drive at port " + xPortString + " found, which is not supported yet!"); } else if (PortType == PortType.PM) // If Port Type was Port Mulitplier. { - //Console.WriteLine("Port Multiplier drive at port " + xPortString + " found, which is not supported yet!"); Console.WriteLine("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); } else if (PortType == PortType.Nothing) @@ -247,53 +243,24 @@ namespace Cosmos.HAL.BlockDevice mAHCIDebugger.Send("Stop"); if (!StopCMD(aPort)) aPort.SCTL = 1; - //Check for Command Process - mAHCIDebugger.SendNumber((aPort.CMD & 1)); - mAHCIDebugger.SendNumber((aPort.CMD >> 4) & 1); - mAHCIDebugger.SendNumber((aPort.CMD >> 14) & 1); - mAHCIDebugger.SendNumber((aPort.CMD >> 15) & 1); - - mAHCIDebugger.Send("CLB"); ulong mCLBAddress = Heap.MemAlloc(1024); aPort.CLB = (uint)mCLBAddress & 0xFFFFFFFF; - //aPort.CLBU = (uint)((mCLBAddress >> 32)) & 0xFFFFFFFF; - //if(is64DMA) - //{ - // mSATAMemory[mPortLocation + 0x04] |= CLBUAddress; - // new MemoryBlock(mSATAMemory[mPortLocation + 0x04], 1024).Fill(0); - //} - mAHCIDebugger.SendNumber((aPort.CMD & 1)); - mAHCIDebugger.SendNumber((aPort.CMD >> 4) & 1); - mAHCIDebugger.SendNumber((aPort.CMD >> 14) & 1); - mAHCIDebugger.SendNumber((aPort.CMD >> 15) & 1); - mAHCIDebugger.Send("FB"); + var mFBAddress = Heap.MemAlloc(256); - aPort.FB = mFBAddress; + aPort.FB = (uint)mFBAddress & 0xFFFFFFFF; aPort.SERR = 1; aPort.IS = 0; aPort.IE = 0; - //aPort.FBU = 0; + new MemoryBlock(aPort.CLB, 1024).Fill(0); new MemoryBlock(aPort.FB, 256).Fill(0); - //if (is64DMA) - //{ - // mSATAMemory[mPortLocation + 0x0C] |= FBUAddress; - // new MemoryBlock(mSATAMemory[mPortLocation + 0x0C], 256).Fill(0); - //} - - mAHCIDebugger.Send("GetCommandHeader"); + GetCommandHeader(aPort); // Rebasing Command Header - mAHCIDebugger.Send("Start"); StartCMD(aPort); - mAHCIDebugger.SendNumber((aPort.CMD & 1)); - mAHCIDebugger.SendNumber((aPort.CMD >> 4) & 1); - mAHCIDebugger.SendNumber((aPort.CMD >> 14) & 1); - mAHCIDebugger.SendNumber((aPort.CMD >> 15) & 1); aPort.IS = 0; aPort.IE = 0xFFFFFFFF; - mAHCIDebugger.Send("Finished!"); } private static HBACommandHeader[] GetCommandHeader(PortRegisters aPort) From bd093db90578c15ab3a4114e94f7d34835b172c7 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:44:02 +0300 Subject: [PATCH 20/85] [Global] Initialize all drivers when they exists --- source/Cosmos.HAL2/Global.cs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 9da72451f..7e3d6bd4d 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -43,28 +43,12 @@ namespace Cosmos.HAL Console.WriteLine("Starting ACPI"); mDebugger.Send("ACPI Init"); ACPI.Start(); + + IDE.InitDriver(); + AHCI.InitDriver(); + //EHCI.InitDriver(); mDebugger.Send("Done initializing Cosmos.HAL.Global"); - - // Currently ATA won't be initialized until we find a solution for the - // Two Controllers initialize bug - if (PCI.GetDeviceClass(0x01, 0x01) != null) - { - mDebugger.Send("ATA Primary Master"); - IDE ATA1 = new IDE(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); - mDebugger.Send("ATA Secondary Master"); - IDE ATA2 = new IDE(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); - //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); - } - if (PCI.GetDeviceClass(0x01, 0x06) != null) - { - Console.WriteLine("Initializing AHCI Controller"); - AHCI xAHCI = new AHCI(PCI.GetDeviceClass(0x01, 0x06).BaseAddressBar[5].BaseAddress); - } - else if (PCI.GetDeviceClass(0x01, 0x01) == null) - { - Console.Write("Booting without ATA Initialization"); - } } From 7eda5cd571f3833a46b11e371748ce4ed5409dfb Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:46:43 +0300 Subject: [PATCH 21/85] [IDE] Initializer --- .../Drivers/PCI/Controllers/IDE.cs | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs index 231939f45..0b2a20748 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs @@ -1,28 +1,43 @@ using System; using Cosmos.HAL.BlockDevice; -namespace Cosmos.HAL.Drivers.PCI.Controllers +namespace Cosmos.HAL.BlockDevice { public class IDE { - public IDE(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) + private static PCIDevice xDevice = HAL.PCI.GetDeviceClass(0x01, 0x01); + + internal static void InitDriver() { + if (xDevice == null) return; + Console.WriteLine("ATA Primary Master"); + Initialize(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); + //Console.WriteLine("ATA Primary Slave"); + //Initialize(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Slave); + Console.WriteLine("ATA Secondary Master"); + Initialize(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); + //Console.WriteLine("ATA Secondary Slave"); + //Initialize(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Slave); + } + + private static void Initialize(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) + { + if (aControllerID == Ata.ControllerIdEnum.Primary && aBusPosition == Ata.BusPositionEnum.Master) + else if (aControllerID == Ata.ControllerIdEnum.Secondary && aBusPosition == Ata.BusPositionEnum.Master) + else if (aControllerID == Ata.ControllerIdEnum.Primary && aBusPosition == Ata.BusPositionEnum.Slave) + else if (aControllerID == Ata.ControllerIdEnum.Secondary && aBusPosition == Ata.BusPositionEnum.Master) + var xIO = aControllerID == Ata.ControllerIdEnum.Primary ? Core.Global.BaseIOGroups.ATA1 : Core.Global.BaseIOGroups.ATA2; var xATA = new AtaPio(xIO, aControllerID, aBusPosition); - if (xATA.DriveType == AtaPio.SpecLevel.Null) - { - return; - } + if (xATA.DriveType == AtaPio.SpecLevel.Null) return; if (xATA.DriveType == AtaPio.SpecLevel.ATA) { - BlockDevice.BlockDevice.Devices.Add(xATA); + BlockDevice.Devices.Add(xATA); Ata.AtaDebugger.Send("ATA device with speclevel ATA found."); } - else + else if (xATA.DriveType != (AtaPio.SpecLevel)1) { - //Ata.AtaDebugger.Send("ATA device with spec level " + (int)xATA.DriveType + - // " found, which is not supported!"); - return; + Ata.AtaDebugger.Send("ATA device with speclevel " + (byte)xATA.DriveType + " found, which is not supported yet!"); } var xMbrData = new byte[512]; xATA.ReadBlock(0UL, 1U, xMbrData); @@ -46,7 +61,7 @@ namespace Cosmos.HAL.Drivers.PCI.Controllers // TODO Change this to foreach when foreach is supported Ata.AtaDebugger.Send("Number of MBR partitions found:"); Ata.AtaDebugger.SendNumber(xMBR.Partitions.Count); - for (int i = 0; i < xMBR.Partitions.Count; i++) + for(int i = 0; i < xMBR.Partitions.Count; i++) { var xPart = xMBR.Partitions[i]; if (xPart == null) @@ -56,8 +71,8 @@ namespace Cosmos.HAL.Drivers.PCI.Controllers else { var xPartDevice = new Partition(xATA, xPart.StartSector, xPart.SectorCount); - BlockDevice.BlockDevice.Devices.Add(xPartDevice); - Console.WriteLine("Found partition at idx" + i); + BlockDevice.Devices.Add(xPartDevice); + Console.WriteLine("Found partition at idx: " + i); } } } From 677a6ab28abd623bc4e104e495b33c1894a30004 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:48:40 +0300 Subject: [PATCH 22/85] [AHCI] Remove Future class --- source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs index a79046117..31808d8c3 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs @@ -10,10 +10,10 @@ using Cosmos.Core.Memory.Old; namespace Cosmos.HAL.BlockDevice { - public class AHCI : Drivers.PCIDriver + public class AHCI { internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); - internal static PCIDevice xDevice = HAL.PCI.GetDevice(0x001, 0x0006); + internal static PCIDevice xDevice = HAL.PCI.GetDevice(0x01, 0x06); private static List mPorts = new List(); private static GenericRegisters mGeneric; From 6b5c7658fa24a5d025e89ec175bc5217b4576e25 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:50:05 +0300 Subject: [PATCH 23/85] [AHCI] Change file's path --- .../Cosmos.HAL2/{Drivers/PCI/Controllers => BlockDevices}/AHCI.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/{Drivers/PCI/Controllers => BlockDevices}/AHCI.cs (100%) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs b/source/Cosmos.HAL2/BlockDevices/AHCI.cs similarity index 100% rename from source/Cosmos.HAL2/Drivers/PCI/Controllers/AHCI.cs rename to source/Cosmos.HAL2/BlockDevices/AHCI.cs From 7e65827386abd8298534bcf0a910097cd24b4f0f Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:51:08 +0300 Subject: [PATCH 24/85] [IDE] Change file's path --- .../Cosmos.HAL2/{Drivers/PCI/Controllers => BlockDevices}/IDE.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/{Drivers/PCI/Controllers => BlockDevices}/IDE.cs (100%) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs b/source/Cosmos.HAL2/BlockDevices/IDE.cs similarity index 100% rename from source/Cosmos.HAL2/Drivers/PCI/Controllers/IDE.cs rename to source/Cosmos.HAL2/BlockDevices/IDE.cs From 317e634a950ea94ccc288d29b6dfb333a432b7c6 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:51:42 +0300 Subject: [PATCH 25/85] [AHC] Change file's path --- source/Cosmos.HAL2/{BlockDevices => BlockDevice}/AHCI.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/{BlockDevices => BlockDevice}/AHCI.cs (100%) diff --git a/source/Cosmos.HAL2/BlockDevices/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs similarity index 100% rename from source/Cosmos.HAL2/BlockDevices/AHCI.cs rename to source/Cosmos.HAL2/BlockDevice/AHCI.cs From d942cc4c2e4e087503ff29e434e13ab6d191a845 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:52:45 +0300 Subject: [PATCH 26/85] [IDE] Change file's path --- source/Cosmos.HAL2/{BlockDevices => BlockDevice}/IDE.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/{BlockDevices => BlockDevice}/IDE.cs (100%) diff --git a/source/Cosmos.HAL2/BlockDevices/IDE.cs b/source/Cosmos.HAL2/BlockDevice/IDE.cs similarity index 100% rename from source/Cosmos.HAL2/BlockDevices/IDE.cs rename to source/Cosmos.HAL2/BlockDevice/IDE.cs From 055b13498cf1240778b60d2788533e2957f45489 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:53:18 +0300 Subject: [PATCH 27/85] [Sata] Change file's path --- source/Cosmos.HAL2/BlockDevice/{ => Ports}/Sata.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/Cosmos.HAL2/BlockDevice/{ => Ports}/Sata.cs (100%) diff --git a/source/Cosmos.HAL2/BlockDevice/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs similarity index 100% rename from source/Cosmos.HAL2/BlockDevice/Sata.cs rename to source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs From e3930ac08fca2fe0d2adb41ebf8306933c8a8e1e Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:54:31 +0300 Subject: [PATCH 28/85] [AHCI] AHCI Registers --- .../BlockDevice/Registers/AHCIRegs.cs | 968 ++++++++++++++++++ 1 file changed, 968 insertions(+) create mode 100644 source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs diff --git a/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs b/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs new file mode 100644 index 000000000..3c2ff546e --- /dev/null +++ b/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs @@ -0,0 +1,968 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Cosmos.Core; + +namespace Cosmos.HAL.BlockDevice.Registers +{ + // Registers + public class GenericRegisters + { + private MemoryBlock xBlock; + private uint xAddress; + public GenericRegisters(uint aAddress) + { + xAddress = aAddress; + xBlock = new MemoryBlock(aAddress, 0x100); + } + + public uint Capabilities + { + get { return xBlock[0x00]; } + set { xBlock[0x00] = value; } + } + + public uint GlobalHostControl + { + get { return xBlock[0x04]; } + set { xBlock[0x04] = value; } + } + public uint InterruptStatus + { + get { return xBlock[0x08]; } + set { xBlock[0x08] = value; } + } + + public uint ImplementedPorts + { + get { return xBlock[0x0C]; } + set { xBlock[0x0C] = value; } + } + + public uint AHCIVersion + { + get { return xBlock[0x10]; } + set { xBlock[0x10] = value; } + } + + public uint CCC_Control + { + get { return xBlock[0x14]; } + set { xBlock[0x14] = value; } + } + + public uint CCC_Ports + { + get { return xBlock[0x18]; } + set { xBlock[0x18] = value; } + } + + public uint EM_Location + { + get { return xBlock[0x1C]; } + set { xBlock[0x1C] = value; } + } + + public uint EM_Control + { + get { return xBlock[0x20]; } + set { xBlock[0x20] = value; } + } + + public uint ExtendedCapabilities + { + get { return xBlock[0x24]; } + set { xBlock[0x24] = value; } + } + + public uint BIOSHandOffStatus + { + get { return xBlock[0x28]; } + set { xBlock[0x28] = value; } + } + } + + public class PortRegisters + { + private MemoryBlock xBlock; + private uint xAddress; + public uint mPortNumber; + public PortType mPortType = PortType.Nothing; + public bool Active; + public PortRegisters(uint aAddress, uint aPortNumber) + { + xAddress = aAddress; + mPortNumber = aPortNumber; + xBlock = new MemoryBlock(aAddress, 0x80); + Active = false; + } + + public uint CLB + { + get { return xBlock[0x00]; } + set { xBlock[0x00] = value; } + } + + public uint CLBU + { + get { return xBlock[0x04]; } + set { xBlock[0x04] = value; } + } + + public uint FB + { + get { return xBlock[0x08]; } + set { xBlock[0x08] = value; } + } + + public uint FBU + { + get { return xBlock[0x0C]; } + set { xBlock[0x0C] = value; } + } + + public uint IS + { + get { return xBlock[0x10]; } + set { xBlock[0x10] = value; } + } + + public uint IE + { + get { return xBlock[0x14]; } + set { xBlock[0x14] = value; } + } + + public uint CMD + { + get { return xBlock[0x18]; } + set { xBlock[0x18] = value; } + } + + public uint Reserved + { + get { return xBlock[0x1C]; } + } + + public uint TFD + { + get { return xBlock[0x20]; } + set { xBlock[0x20] = value; } + } + + public uint SIG + { + get { return xBlock[0x24]; } + set { xBlock[0x24] = value; } + } + + public uint SSTS + { + get { return xBlock[0x28]; } + set { xBlock[0x28] = value; } + } + + public uint SCTL + { + get { return xBlock[0x2C]; } + set { xBlock[0x2C] = value; } + } + + public uint SERR + { + get { return xBlock[0x30]; } + set { xBlock[0x30] = value; } + } + + public uint SACT + { + get { return xBlock[0x34]; } + set { xBlock[0x34] = value; } + } + + public uint CI + { + get { return xBlock[0x38]; } + set { xBlock[0x38] = value; } + } + + public uint SNTF + { + get { return xBlock[0x3C]; } + set { xBlock[0x3C] = value; } + } + + public uint FBS + { + get { return xBlock[0x40]; } + set { xBlock[0x40] = value; } + } + + public uint DEVSLP + { + get { return xBlock[0x44]; } + set { xBlock[0x44] = value; } + } + } + + // Command List + public class HBACommandHeader + { + private MemoryBlock xBlock; + private uint xAddress;// + private uint xSlot; + public HBACommandHeader(uint aAddress, uint aSlot) + { + xAddress = aAddress; + xSlot = aSlot; + xBlock = new MemoryBlock(aAddress + (0x20 * aSlot), 0x20); + xBlock.Fill(0); + } + + public byte CFL + { + get { return (byte)(xBlock.Bytes[0x00] & 0x1F); } + set { xBlock.Bytes[0x00] = value; } + } + public byte ATAPI + { + get { return (byte)((xBlock.Bytes[0x00] >> 5) & 1); } + set { xBlock.Bytes[0x00] |= (byte)(value << 5); } + } + public byte Write + { + get { return (byte)((xBlock.Bytes[0x00] >> 6) & 1); } + set { xBlock.Bytes[0x00] |= (byte)(value << 6); } + } + public byte Prefetchable + { + get { return (byte)((xBlock.Bytes[0x00] >> 7) & 1); } + set { xBlock.Bytes[0x00] |= (byte)(value << 7); } + } + public byte Reset + { + get { return (byte)((xBlock.Bytes[0x01]) & 1); } + set { xBlock.Bytes[0x01] |= (byte)(value); } + } + public byte BIST + { + get { return (byte)((xBlock.Bytes[0x01] >> 1) & 1); } + set { xBlock.Bytes[0x01] |= (byte)(value << 1); } + } + public byte ClearBusy + { + get { return (byte)((xBlock.Bytes[0x01] >> 2) & 1); } + set { xBlock.Bytes[0x01] |= (byte)(value << 2); } + } + public byte Reserved + { + get { return (byte)((xBlock.Bytes[0x01] >> 3) & 1); } + } + public byte PMP + { + get { return (byte)((xBlock.Bytes[0x01] >> 4) & 0x0F); } + set { xBlock.Bytes[0x01] = (byte)(value << 4); } + } + public ushort PRDTL + { + get { return (ushort)(xBlock.Words[0x02] & 0xFFFF); } + set { xBlock.Words[0x02] = (ushort)(value); } + } + + public uint PRDBC + { + get { return xBlock[0x04]; } + set { xBlock[0x04] = value; } + } + + public uint CTBA + { + get { return xBlock[0x08] >> 7; } + set { xBlock[0x08] = (value << 7); } + } + + public uint CTBAU + { + get { return xBlock[0x0C]; } + set { xBlock[0x0C] = value; } + } + + public uint Reserved1 + { + get { return xBlock[0x10]; } + } + + public uint Reserved2 + { + get { return xBlock[0x14]; } + } + + public uint Reserved3 + { + get { return xBlock[0x18]; } + } + + public uint Reserved4 + { + get { return xBlock[0x1C]; } + } + } + + public class HBACommandTable + { + private MemoryBlock xBlock; + private uint xAddress; + private uint xSlot; + public HBACommandTable(uint aAddress, uint aSlot) + { + xAddress = aAddress; + xSlot = aSlot; + xBlock = new MemoryBlock(aAddress + (256 * xSlot), 0x80); + xBlock.Fill(0); + } + + public uint CFIS + { + get { return xAddress; } + } + + public uint ACMD + { + get { return xAddress + 0x40; } + } + + public uint Reserved + { + get { return xBlock[0x50]; } + } + + public HBAPRDTEntry[] PRDTEntry; + } + + public class HBAPRDTEntry + { + private MemoryBlock xBlock; + private uint xAddress; + private uint xEntry; + public HBAPRDTEntry(uint aAddress, uint aEntry) + { + xAddress = aAddress; + xEntry = aEntry; + xBlock = new MemoryBlock(aAddress + (0x10 * xEntry), 0x10); + xBlock.Fill(0); + } + + public uint DBA + { + get { return xBlock[0x00] >> 1; } + set { xBlock[0x00] = (uint)(value << 1); } + } + + public uint DBAU + { + get { return xBlock[0x04]; } + set { xBlock[0x04] = value; } + } + + public uint Reserved + { + get { return xBlock[0x08]; } + } + + public uint DBC + { + get { return xBlock[0x0C] & 0x3FFFFF; } + set { xBlock[0x0C] = value; } + } + public uint Reserved1 + { + get { return xBlock[0x0E] << 6; } + } + public byte InterruptOnCompletion + { + get { return (byte)(xBlock.Bytes[0x0F] >> 7); } + set { xBlock.Bytes[0x0F] |= (byte)(value << 7); } + } + } + + // FISes + public class FISRegisterH2D + { + private MemoryBlock xBlock; + private uint xAddress; + public FISRegisterH2D(uint aAddress) + { + xAddress = aAddress; + xBlock = new MemoryBlock(aAddress, 20); + xBlock.Fill(0); + } + + public byte FISType + { + get { return (byte)(xBlock.Bytes[0x00]); } + set { xBlock.Bytes[0x00] = value; } + } + + public byte IsCommand + { + get { return (byte)((xBlock.Bytes[0x01] >> 7)); } + set { xBlock.Bytes[0x01] |= (byte)(value << 7); } + } + public byte Command + { + get { return xBlock.Bytes[0x02]; } + set { xBlock.Bytes[0x02] = value; } + } + public byte FeatureLow + { + get { return xBlock.Bytes[0x03]; } + set { xBlock.Bytes[0x03] = value; } + } + + public byte LBA0 + { + get { return xBlock.Bytes[0x04]; } + set { xBlock.Bytes[0x04] = value; } + } + public byte LBA1 + { + get { return xBlock.Bytes[0x05]; } + set { xBlock.Bytes[0x05] = value; } + } + public byte LBA2 + { + get { return xBlock.Bytes[0x06]; } + set { xBlock.Bytes[0x06] = value; } + } + public byte Device + { + get { return xBlock.Bytes[0x07]; } + set { xBlock.Bytes[0x07] = value; } + } + + public byte LBA3 + { + get { return xBlock.Bytes[0x08]; } + set { xBlock.Bytes[0x08] = value; } + } + public byte LBA4 + { + get { return xBlock.Bytes[0x09]; } + set { xBlock.Bytes[0x09] = value; } + } + public byte LBA5 + { + get { return xBlock.Bytes[0x0A]; } + set { xBlock.Bytes[0x0A] = value; } + } + public byte FeatureHigh + { + get { return xBlock.Bytes[0x0B]; } + set { xBlock.Bytes[0x0B] = value; } + } + + public byte CountL + { + get { return xBlock.Bytes[0x0C]; } + set { xBlock.Bytes[0x0C] = value; } + } + public byte CountH + { + get { return xBlock.Bytes[0x0D]; } + set { xBlock.Bytes[0x0D] = value; } + } + public byte ICC + { + get { return xBlock.Bytes[0x0E]; } + set { xBlock.Bytes[0x0E] = value; } + } + public byte Control + { + get { return xBlock.Bytes[0x0F]; } + set { xBlock.Bytes[0x0F] = value; } + } + + public byte Reserved1 + { + get { return xBlock.Bytes[0x10]; } + } + public byte Reserved2 + { + get { return xBlock.Bytes[0x11]; } + } + public byte Reserved3 + { + get { return xBlock.Bytes[0x12]; } + } + public byte Reserved4 + { + get { return xBlock.Bytes[0x13]; } + } + } + + public class FISRegisterD2H + { + private MemoryBlock xBlock; + private uint xAddress; + public FISRegisterD2H(uint aAddress) + { + xAddress = aAddress; + xBlock = new MemoryBlock(aAddress, 20); + } + + public FISType FISType + { + get { return (FISType)xBlock.Bytes[0x00]; } + set { xBlock.Bytes[0x00] = (byte)value; } + } + public byte PortMultiplier + { + get { return (byte)(xBlock.Bytes[0x00] << 8); } + set { xBlock.Bytes[0x00] = (byte)value; } + } + public byte Reserved + { + get { return (byte)(xBlock.Bytes[0x00] << 12); } + } + public byte InterruptBit + { + get { return (byte)(xBlock.Bytes[0x00] << 14); } + set { xBlock.Bytes[0x00] = (byte)(value << 14); } + } + public byte Reserved1 + { + get { return (byte)(xBlock.Bytes[0x00] << 15); } + } + + public byte Status + { + get { return (byte)(xBlock.Bytes[0x00] << 16); } + set { xBlock.Bytes[0x00] = (byte)(value << 16); } + } + public byte Error + { + get { return (byte)(xBlock.Bytes[0x00] << 24); } + set { xBlock.Bytes[0x00] = (byte)(value << 24); } + } + + public byte LBA0 + { + get { return xBlock.Bytes[0x04]; } + set { xBlock.Bytes[0x04] = value; } + } + public byte LBA1 + { + get { return (byte)(xBlock.Bytes[0x04] << 8); } + set { xBlock.Bytes[0x04] = (byte)(value << 8); } + } + public byte LBA2 + { + get { return (byte)(xBlock.Bytes[0x04] << 16); } + set { xBlock.Bytes[0x04] = (byte)(value << 16); } + } + public byte Device + { + get { return (byte)(xBlock.Bytes[0x04] << 24); } + set { xBlock.Bytes[0x04] = (byte)(value << 24); } + } + + public byte LBA3 + { + get { return xBlock.Bytes[0x08]; } + set { xBlock.Bytes[0x08] = value; } + } + public byte LBA4 + { + get { return (byte)(xBlock.Bytes[0x08] << 8); } + set { xBlock.Bytes[0x08] = (byte)(value << 8); } + } + public byte LBA5 + { + get { return (byte)(xBlock.Bytes[0x08] << 16); } + set { xBlock.Bytes[0x08] = (byte)(value << 16); } + } + public byte Reserved2 + { + get { return (byte)(xBlock.Bytes[0x08] << 24); } + } + + public byte CountL + { + get { return xBlock.Bytes[0x0C]; } + set { xBlock.Bytes[0x0C] = value; } + } + public byte CountH + { + get { return (byte)(xBlock.Bytes[0x0C] << 8); } + set { xBlock.Bytes[0x0C] = (byte)(value << 8); } + } + public byte Reserved3 + { + get { return (byte)(xBlock.Bytes[0x0C] << 16); } + } + public byte Reserved4 + { + get { return (byte)(xBlock.Bytes[0x0C] << 24); } + } + + public byte Reserved5 + { + get { return xBlock.Bytes[0x10]; } + } + public byte Reserved6 + { + get { return xBlock.Bytes[0x11]; } + } + + public byte Reserved7 + { + get { return xBlock.Bytes[0x12]; } + } + public byte Reserved8 + { + get { return xBlock.Bytes[0x13]; } + } + } + + public class FISPIOSetup + { + private static MemoryBlock xBlock; + private static uint xAddress; + private static uint xDataSize; + public static FISPIOSetup GetFIS(uint aAddress) + { + xAddress = aAddress; + xBlock = new MemoryBlock(xAddress + 0x20, 0x14); + return new FISPIOSetup(); + } + + public byte FISType + { + get { return xBlock.Bytes[0x00]; } + set { xBlock.Bytes[0x00] = value; } + } + public byte PortMultiplier + { + get { return (byte)(xBlock.Bytes[0x01] & 0x0F); } + set { xBlock.Bytes[0x01] = value; } + } + public byte Reserved + { + get { return (byte)((xBlock.Bytes[0x01] >> 4) & 1); } + } + public byte DataTransferDir + { + get { return (byte)((xBlock.Bytes[0x01] >> 5) & 1); } + set { xBlock.Bytes[0x01] |= (byte)((value) << 5); } + } + public byte InterruptBit + { + get { return (byte)((xBlock.Bytes[0x01] >> 6) & 1); } + set { xBlock.Bytes[0x01] |= (byte)((value) << 6); } + } + public byte Reserved1 + { + get { return (byte)((xBlock.Bytes[0x01] >> 7) & 1); } + } + + public byte Status + { + get { return xBlock.Bytes[0x02]; } + set { xBlock.Bytes[0x02] = value; } + } + public byte Error + { + get { return xBlock.Bytes[0x03]; } + set { xBlock.Bytes[0x03] = value; } + } + + public byte LBA0 + { + get { return xBlock.Bytes[0x04]; } + set { xBlock.Bytes[0x04] = value; } + } + public byte LBA1 + { + get { return xBlock.Bytes[0x05]; } + set { xBlock.Bytes[0x05] = value; } + } + public byte LBA2 + { + get { return xBlock.Bytes[0x06]; } + set { xBlock.Bytes[0x06] = value; } + } + public byte Device + { + get { return xBlock.Bytes[0x07]; } + set { xBlock.Bytes[0x07] = value; } + } + + public byte LBA3 + { + get { return xBlock.Bytes[0x08]; } + set { xBlock.Bytes[0x08] = value; } + } + public byte LBA4 + { + get { return xBlock.Bytes[0x09]; } + set { xBlock.Bytes[0x09] = value; } + } + public byte LBA5 + { + get { return xBlock.Bytes[0x0A]; } + set { xBlock.Bytes[0x0A] = value; } + } + public byte Reserved2 // FeatureL in other Fis types + { + get { return xBlock.Bytes[0x0B]; } + set { xBlock.Bytes[0x0B] = value; } + } + + public byte CountLow + { + get { return xBlock.Bytes[0x0C]; } + set { xBlock.Bytes[0x0C] = value; } + } + public byte CountHigh + { + get { return xBlock.Bytes[0x0D]; } + set { xBlock.Bytes[0x0D] = value; } + } + public byte Reserved3 // ICC in other Fis types + { + get { return xBlock.Bytes[0x0E]; } + set { xBlock.Bytes[0x0E] = value; } + } + public byte E_Status + { + get { return xBlock.Bytes[0x0F]; } + set { xBlock.Bytes[0x0F] = value; } + } + + public ushort DataCount + { + get { return xBlock.Words[0x10]; } + set { xBlock.Words[0x10] = value; } + } + public byte Reserved4 + { + get { return xBlock.Bytes[0x12]; } + set { xBlock.Bytes[0x12] = value; } + } + public byte Reserved5 + { + get { return xBlock.Bytes[0x13]; } + set { xBlock.Bytes[0x13] = value; } + } + } + + public class FISData + { + private static MemoryBlock xBlock; + private static uint xAddress; + private static uint xDataSize; + public static FISData GetFIS(uint aAddress, uint aDataSize) + { + xAddress = aAddress; + xDataSize = aDataSize; + xBlock = new MemoryBlock(xAddress, 4 + (4 * aDataSize)); + return new FISData(); + } + + public byte FISType + { + get { return xBlock.Bytes[0x00]; } + set { xBlock.Bytes[0x00] = value; } + } + public byte PortMultiplier + { + get { return (byte)((xBlock.Bytes[0x01]) & 0x0F); } + set { xBlock.Bytes[0x01] = value; } + } + public byte Reserved + { + get { return (byte)(((xBlock.Bytes[0x01]) >> 4) & 0x0F); } + } + public byte Reserved1 + { + get { return xBlock.Bytes[0x02]; } + } + public byte Reserved2 + { + get { return xBlock.Bytes[0x03]; } + } + + public uint[] Data + { + get + { + UInt32[] xResult = new UInt32[xDataSize]; + for (int i = 0; i < xResult.Length; i++) + { + xResult[i] = xBlock[(uint)(0x04 * i)]; + } + return xResult; + } + } + } + + // Enums + public enum PortType + { + Nothing = 0x00, + SATA = 0x01, + SATAPI = 0x02, + SEMB = 0x03, + PM = 0x04 + } + + public enum FISType + { + FIS_Type_RegisterH2D = 0x27, // Register FIS: Host to Device + FIS_Type_RegisterD2H = 0x34, // Register FIS: Device to Host + FIS_Type_DMA_Activate = 0x39, // DMA Activate + FIS_Type_DMA_Setup = 0x41, // DMA Setup: Device to Host + FIS_Type_Data = 0x46, // Data FIS: Bidirectional + FIS_Type_BIST = 0x58, // BIST + FIS_Type_PIO_Setup = 0x5F, // PIO Setup: Device to Host + FIS_Type_DeviceBits = 0xA1 // Device bits + } + + public enum FISSize : byte + { + //FISRegisterH2D = Marshal.SizeOf(FISRegisterH2D); + FISRegisterH2D = 40 / sizeof(uint) + } + + public enum DriveSignature : uint // Drive Signature to identify what drive is plugged to Port X:X + { + SATADrive = 0x00000101, + PMDrive = 0x96690101, + SATAPIDrive = 0xEB140101, + SEMBDrive = 0xC33C0101, + NullDrive = 0xFFFFFFFF + } + + public enum InterfacePowerManagementStatus : uint // SATA Status: Interface Power Management Status + { + NotPresent = 0x00, + Active = 0x01, + Partial = 0x02, + Slumber = 0x06, + DeviceSleep = 0x08 + } + + public enum CurrentInterfaceSpeedStatus : uint // SATA Status: Current Interface Speed + { + NotPresent = 0x00, + Gen1Rate = 0x01, + Gen2Rate = 0x02, + Gen3Rate = 0x03 + } + + public enum DeviceDetectionStatus : uint // SATA Status: Device Detection Status + { + NotDetected = 0x00, + DeviceDetectedNoPhy = 0x01, + DeviceDetectedWithPhy = 0x03, + PhyOffline = 0x04 + } + + public enum ATADeviceStatus : uint + { + Busy = 0x80, + DRQ = 0x08 + } + + public enum CommandAndStatus : uint + { + ICC_Reserved0 = 0x0000000F, + ICC_DevSleep = 0x00000008, + ICC_Slumber = 0x00000006, + ICC_Partial = 0x00000002, + ICC_Active = 0x00000001, + ICC_Idle = 0x00000000, + ASP = (01 << 27), + ALPE = (01 << 26), + EnableATAPILED = (01 << 25), + ATAPIDevice = (01 << 24), + APSTE = (01 << 23), + FISSwitchPort = (01 << 22), + ExternalSATAPort = (01 << 21), + ColdPresenceDetect = (01 << 20), + MPSP = (01 << 19), + HotPlugCapPort = (01 << 18), + PortMultAttach = (01 << 17), + ColdPresenceState = (01 << 16), + CMDListRunning = (01 << 15), + FISRecieveRunning = (01 << 14), + MPSS = (01 << 13), + CurrentCMDSlot = (01 << 12), + Reserved0 = (01 << 07), + FISRecieveEnable = (01 << 04), + CMDListOverride = (01 << 03), + PowerOnDevice = (01 << 02), + SpinUpDevice = (01 << 01), + StartProccess = (01 << 00), + Null = 0xFFFF + } + + public enum InterruptStatus : int + { + ColdPortDetectStatus = (01 << 31), + TaskFileErrorStatus = (01 << 30), + HostBusFatalErrorStatus = (01 << 29), + HostBusDataErrorStatus = (01 << 28), + InterfaceFatalErrorStatus = (01 << 27), + InterfaceNFatalErrorStatus = (01 << 26), + OverflowStatus = (01 << 24), + IncorrectPMStatus = (01 << 23), + PhyRdyChangeStatus = (01 << 22), + DevMechanicalPresenceStatus = (01 << 07), + PortConnectChangeStatus = (01 << 06), + DescriptorProcessed = (01 << 05), + UnknownFISInterrupt = (01 << 04), + SetDeviceBitsInterrupt = (01 << 03), + DMASetupFISInterrupt = (01 << 02), + PIOSetupFISInterrupt = (01 << 01), + D2HRegFISInterrupt = (01 << 00), + Null = 0xFFFF + } + + public enum InterruptEnable : uint + { + OverflowEnable = (01 << 24), + IncorrectPMEnable = (01 << 23), + PhyRdyChangeInterruptEnable = (01 << 22), + DevMechanicalPresenceEnable = (01 << 07), + PortChangeInterruptEnable = (01 << 06), + DescProcessedInterruptEnable = (01 << 05), + UnknownFISInterruptEnable = (01 << 04), + SetDeviceBitsInterruptEnable = (01 << 03), + DMASetupFISInterruptEnable = (01 << 02), + PIOSetupFISInterruptEnable = (01 << 01), + D2HRegFISInterruptEnable = (01 << 00), + Null = 0xFFFF + } + + public enum ATACommands : byte + { + ReadDma = 0xC8, + ReadDmaExt = 0x25, + WriteDma = 0xCA, + WriteDmaExt = 0x35, + CacheFlush = 0xE7, + CacheFlushExt = 0xEA, + Packet = 0xA0, + IdentifyPacket = 0xA1, + IdentifyDMA = 0xEE, + Identify = 0xEC, + Read = 0xA8, + Eject = 0x1B + } + + public enum Bases : uint + { + SATA = 0x00400000 + } +} From d479b71f3e1880d6617db72350fd4418f8900f0a Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:55:31 +0300 Subject: [PATCH 29/85] [Satapi] Beta Port Driver --- .../Cosmos.HAL2/BlockDevice/Ports/Satapi.cs | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs new file mode 100644 index 000000000..cf3f58d62 --- /dev/null +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Cosmos.Core.Memory.Old; +using Cosmos.HAL.BlockDevice.Registers; + +namespace Cosmos.HAL.BlockDevice.Ports +{ + public class Satapi : StoragePort + { + public Debug.Kernel.Debugger mSATAPIDebugger = new Debug.Kernel.Debugger("HAL", "SATAPI"); + + public PortRegisters mPortReg; + + public override PortType mPortType => PortType.SATAPI; + public override string mPortName => "SATAPI"; + public override uint mPortNumber => mPortReg.mPortNumber; + + public SATAPI(PortRegisters aSATAPIPort) + { + + // Check if it is really a SATAPI Port! + if (aSATAPIPort.mPortType != PortType.SATAPI || (aSATAPIPort.CMD & (1U << 24)) == 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Error]"); + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($" 0:{aSATAPIPort.mPortNumber} is not a SATAPI port!"); + return; + } + mSATAPIDebugger.Send("SATAPI Constructor"); + + mPortReg = aSATAPIPort; + + mBlockSize = 2048; + } + + public void SendSATAPICommand(ATACommands aCommand, uint aStart, uint aCount) + { + mPortReg.IS = unchecked((uint)-1); + + int xSlot = FindCMDSlot(mPortReg); + if (xSlot == -1) return; + + HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); + xCMDHeader.CFL = 5; + xCMDHeader.ATAPI = 1; + xCMDHeader.PRDTL = 0; + xCMDHeader.Write = 0; + xCMDHeader.ClearBusy = 1; + + xCMDHeader.CTBA = Heap.MemAlloc(256) + (uint)(256 * xSlot); + + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); + + FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) + { + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)ATACommands.Packet, + Device = 0 + }; + + byte[] xATAPICMD = new byte[12]; + xATAPICMD[0] = (byte)aCommand; + xATAPICMD[2] = (byte)((aStart >> 0x18) & 0xFF); + xATAPICMD[3] = (byte)((aStart >> 0x10) & 0xFF); + xATAPICMD[4] = (byte)((aStart >> 0x08) & 0xFF); + xATAPICMD[5] = (byte)((aStart >> 0x00) & 0xFF); + xATAPICMD[9] = (byte)(aCount); + for (uint i = 0; i < xATAPICMD.Length; i++) + new Core.MemoryBlock(xCMDTable.ACMD, 12).Bytes[i] = xATAPICMD[i]; + + int xSpin = 0; + do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSpin < 1000000); + + if (xSpin == 1000000) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("\n[Error]: "); + Console.Write("Port timed out!"); + Console.ResetColor(); + return; + }; + + mPortReg.CI = 1U; + + while(true) + { + if((mPortReg.CI & (1 << xSlot)) == 0) + { + break; + } + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!"); + Console.ResetColor(); + return; + } + } + + if ((mPortReg.IS & (1 << 30)) != 0) + { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.Write("\n[Fatal]: "); + Console.Write("Fatal error occurred while sending command!"); + Console.ResetColor(); + return; + } + + Console.ForegroundColor = ConsoleColor.Green; + Console.Write("\n[Success]: "); + Console.Write("Command has been sent successfully!"); + Console.ResetColor(); + + return; + } + + public int FindCMDSlot(PortRegisters aPort) + { + // If not set in SACT and CI, the slot is free + var xSlots = (aPort.SACT | aPort.CI); + + for (int i = 1; i < 32; i++) + { + if ((xSlots & 1) == 0) + return i; + xSlots >>= 1; + } + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("\n[Error]: "); + Console.Write("Cannot find a free command slot!"); + Console.ResetColor(); + return -1; + } + + public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) + { + SendSATAPICommand(ATACommands.Read, (uint)aBlockNo, (uint)aBlockCount); + } + + public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) + { + + } + } +} From 49f59bbceffc7729bf5aee2897de8cf67404500b Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 06:56:52 +0300 Subject: [PATCH 30/85] (Needed) Read and Write Buffer Methods --- source/Cosmos.Core/MemoryBlock.cs | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index c9022e8e8..de4a4bf6f 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -102,6 +102,44 @@ namespace Cosmos.Core { throw new Exception("TODO"); } + + #region ReadWrite + public unsafe void Read8(Byte[] aBuffer) + { + for (int i = 0; i < aBuffer.Length; i++) + aBuffer[i] = (*(Byte*)(Base + i)); + } + + public unsafe void Write8(Byte[] aBuffer) + { + for (int i = 0; i < aBuffer.Length; i++) + (*(Byte*)(Base + i)) = aBuffer[i]; + } + + public unsafe void Read16(UInt16[] aBuffer) + { + for (int i = 0; i < aBuffer.Length; i++) + aBuffer[i] = (*(UInt16*)(Base + i)); + } + + public unsafe void Write16(UInt16[] aBuffer) + { + for (int i = 0; i < aBuffer.Length; i++) + (*(UInt16*)(Base + i)) = aBuffer[i]; + } + + public unsafe void Read32(UInt32[] aBuffer) + { + for (int i = 0; i < aBuffer.Length; i++) + aBuffer[i] = (*(UInt32*)(Base + i)); + } + + public unsafe void Write32(UInt32[] aBuffer) + { + for (int i = 0; i < aBuffer.Length; i++) + (*(UInt32*)(Base + i)) = aBuffer[i]; + } + #endregion ReadWrite } public class MemoryBlock08 From 09a9104b31114a9396f771bfdb0dbeb6cdd247cb Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:03:19 +0300 Subject: [PATCH 31/85] Update PCI.cs --- source/Cosmos.HAL2/PCI.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Cosmos.HAL2/PCI.cs b/source/Cosmos.HAL2/PCI.cs index b8a9416c2..d549d627c 100644 --- a/source/Cosmos.HAL2/PCI.cs +++ b/source/Cosmos.HAL2/PCI.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Text; From 7da6c03dc7cb1096ee03c5b4a2e0f0b4d1d58e1a Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:04:28 +0300 Subject: [PATCH 32/85] Update PCI.cs --- source/Cosmos.HAL2/PCI.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Cosmos.HAL2/PCI.cs b/source/Cosmos.HAL2/PCI.cs index d549d627c..b8a9416c2 100644 --- a/source/Cosmos.HAL2/PCI.cs +++ b/source/Cosmos.HAL2/PCI.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Text; From 5b4b3d8caedd8f3b5bf9aa7c222c792acff1f32b Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:10:53 +0300 Subject: [PATCH 33/85] [IDE] Fix --- source/Cosmos.HAL2/BlockDevice/IDE.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/IDE.cs b/source/Cosmos.HAL2/BlockDevice/IDE.cs index 0b2a20748..b5b364d16 100644 --- a/source/Cosmos.HAL2/BlockDevice/IDE.cs +++ b/source/Cosmos.HAL2/BlockDevice/IDE.cs @@ -22,11 +22,6 @@ namespace Cosmos.HAL.BlockDevice private static void Initialize(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) { - if (aControllerID == Ata.ControllerIdEnum.Primary && aBusPosition == Ata.BusPositionEnum.Master) - else if (aControllerID == Ata.ControllerIdEnum.Secondary && aBusPosition == Ata.BusPositionEnum.Master) - else if (aControllerID == Ata.ControllerIdEnum.Primary && aBusPosition == Ata.BusPositionEnum.Slave) - else if (aControllerID == Ata.ControllerIdEnum.Secondary && aBusPosition == Ata.BusPositionEnum.Master) - var xIO = aControllerID == Ata.ControllerIdEnum.Primary ? Core.Global.BaseIOGroups.ATA1 : Core.Global.BaseIOGroups.ATA2; var xATA = new AtaPio(xIO, aControllerID, aBusPosition); if (xATA.DriveType == AtaPio.SpecLevel.Null) return; From cf9e11c4de06a1391d19bd9895faae4e0b6db9e5 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:18:12 +0300 Subject: [PATCH 34/85] [StoragePort] Init. --- .../Cosmos.HAL2/BlockDevice/Ports/StoragePort.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 source/Cosmos.HAL2/BlockDevice/Ports/StoragePort.cs diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/StoragePort.cs b/source/Cosmos.HAL2/BlockDevice/Ports/StoragePort.cs new file mode 100644 index 000000000..5bb31c5c2 --- /dev/null +++ b/source/Cosmos.HAL2/BlockDevice/Ports/StoragePort.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Cosmos.HAL.BlockDevice.Registers; + +namespace Cosmos.HAL.BlockDevice.Ports +{ + public abstract class StoragePort : BlockDevice + { + public abstract PortType mPortType { get; } + public abstract string mPortName { get; } + public abstract uint mPortNumber { get; } + } +} From 1085d86546cfbb80ce082d35e88d8669c176162a Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:22:20 +0300 Subject: [PATCH 35/85] [Global] Fix --- source/Cosmos.HAL2/Global.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 7e3d6bd4d..6ab841147 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -2,7 +2,6 @@ using System; using Cosmos.Core; using Cosmos.Debug.Kernel; using Cosmos.HAL.BlockDevice; -using Cosmos.HAL.Drivers.PCI.Controllers; namespace Cosmos.HAL { From a9e2e35803e660d43a5dae81648d2198a48e3580 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:23:51 +0300 Subject: [PATCH 36/85] [AHCI] Fix. --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 31808d8c3..6a0478916 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -61,7 +61,7 @@ namespace Cosmos.HAL.BlockDevice } } - internal override PCIDevice GetDevice() => xDevice; + internal PCIDevice GetDevice() => xDevice; public AHCI(PCIDevice aAHCIDevice) { From c5725c18307abf89e64ff8b2d385b150734738ac Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:25:34 +0300 Subject: [PATCH 37/85] [Satapi] Fix. --- source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs index cf3f58d62..af89e4b49 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs @@ -16,7 +16,7 @@ namespace Cosmos.HAL.BlockDevice.Ports public override string mPortName => "SATAPI"; public override uint mPortNumber => mPortReg.mPortNumber; - public SATAPI(PortRegisters aSATAPIPort) + public Satapi(PortRegisters aSATAPIPort) { // Check if it is really a SATAPI Port! From 9f21ed4af070a71afe65db831fb5fc5ff088cbb1 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:30:38 +0300 Subject: [PATCH 38/85] [AHCIMemGroup] Init. --- source/Cosmos.Core/MemoryGroup/AHCI.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 source/Cosmos.Core/MemoryGroup/AHCI.cs diff --git a/source/Cosmos.Core/MemoryGroup/AHCI.cs b/source/Cosmos.Core/MemoryGroup/AHCI.cs new file mode 100644 index 000000000..33e326d84 --- /dev/null +++ b/source/Cosmos.Core/MemoryGroup/AHCI.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cosmos.Core.MemoryGroup +{ + public class AHCI + { + public MemoryBlock DataBlock; + + public AHCI(uint aSectorSize) + { + DataBlock = new Core.MemoryBlock(0x00400000, aSectorSize * 256) + DataBlock.Fill(0); + } + } +} From fb3d7accf18825f74b0da439e9d0d92eb244a7e0 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:32:03 +0300 Subject: [PATCH 39/85] [Sata] Fix. --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index 5526e364c..24ffeaad4 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -16,7 +16,7 @@ namespace Cosmos.HAL.BlockDevice.Ports public override uint mPortNumber => mPortReg.mPortNumber; public PortRegisters mPortReg; - public Core.MemoryGroup.SATA Mem; + public Core.MemoryGroup.AHCI Mem; // Constants public const ulong RegularSectorSize = 512UL; @@ -33,7 +33,7 @@ namespace Cosmos.HAL.BlockDevice.Ports return; } - Mem = new Core.MemoryGroup.SATA(); + Mem = new Core.MemoryGroup.AHCI(); mPortReg = aSATAPort; From 8d40fc24b7350c61582045f3b00f93eb3f8ac372 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:40:15 +0300 Subject: [PATCH 40/85] [AHCIMemGroup] Fix. --- source/Cosmos.Core/MemoryGroup/AHCI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.Core/MemoryGroup/AHCI.cs b/source/Cosmos.Core/MemoryGroup/AHCI.cs index 33e326d84..9f8ddab52 100644 --- a/source/Cosmos.Core/MemoryGroup/AHCI.cs +++ b/source/Cosmos.Core/MemoryGroup/AHCI.cs @@ -10,7 +10,7 @@ namespace Cosmos.Core.MemoryGroup public AHCI(uint aSectorSize) { - DataBlock = new Core.MemoryBlock(0x00400000, aSectorSize * 256) + DataBlock = new Core.MemoryBlock(0x00400000, aSectorSize * 256); DataBlock.Fill(0); } } From e26837420b0f8f71f3ce61a662a07d454c98dcea Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:45:11 +0300 Subject: [PATCH 41/85] [PCIDevice] Add EnableBusMaster --- source/Cosmos.HAL2/PCIDevice.cs | 90 +++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 source/Cosmos.HAL2/PCIDevice.cs diff --git a/source/Cosmos.HAL2/PCIDevice.cs b/source/Cosmos.HAL2/PCIDevice.cs new file mode 100644 index 000000000..b8a9416c2 --- /dev/null +++ b/source/Cosmos.HAL2/PCIDevice.cs @@ -0,0 +1,90 @@ +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 Devices; + + public static uint Count + { + get { return (uint)Devices.Count; } + } + + public static void Setup() + { + Devices = new List(); + 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); + } + } + } + + 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; + } + } +} From 1b7abb133b1c024a192a2858fa71b49a92e3ff43 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:45:58 +0300 Subject: [PATCH 42/85] Update PCIDevice.cs --- source/Cosmos.HAL2/PCIDevice.cs | 390 +++++++++++++++++++++++++++----- 1 file changed, 331 insertions(+), 59 deletions(-) diff --git a/source/Cosmos.HAL2/PCIDevice.cs b/source/Cosmos.HAL2/PCIDevice.cs index b8a9416c2..6419beceb 100644 --- a/source/Cosmos.HAL2/PCIDevice.cs +++ b/source/Cosmos.HAL2/PCIDevice.cs @@ -2,89 +2,361 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using Cosmos.Core.IOGroup; +using Cosmos.Common.Extensions; using Cosmos.Debug.Kernel; namespace Cosmos.HAL { - public class PCI + public class PCIDevice { - private static List Devices; - public static uint Count + #region Enums + public enum PCIHeaderType : byte { - get { return (uint)Devices.Count; } + Normal = 0x00, + Bridge = 0x01, + Cardbus = 0x02 + }; + + public enum PCIBist : byte + { + CocdMask = 0x0f, + Start = 0x40, + Capable = 0x80 + }; + + public enum PCIInterruptPIN : byte + { + None = 0x00, + INTA = 0x01, + INTB = 0x02, + INTC = 0x03, + INTD = 0x04 + }; + + public enum Config : byte + { + VendorID = 0, DeviceID = 2, + Command = 4, Status = 6, + RevisionID = 8, ProgIF = 9, SubClass = 10, Class = 11, + CacheLineSize = 12, LatencyTimer = 13, HeaderType = 14, BIST = 15, + BAR0 = 16, + BAR1 = 20, + PrimaryBusNo = 24, SecondaryBusNo = 25, SubBusNo = 26, SecondarLT = 27, + IOBase = 28, IOLimit = 29, SecondaryStatus = 30, + MemoryBase = 32, MemoryLimit = 34, + PrefMemoryBase = 36, PrefMemoryLimit = 38, + PrefBase32Upper = 40, + PrefLimit32upper = 44, + PrefBase16Upper = 48, PrefLimit16upper = 50, + CapabilityPointer = 52, Reserved = 53, + ExpROMBaseAddress = 56, + InterruptLine = 60, InterruptPIN = 61, BridgeControl = 62 + }; + #endregion + + public readonly uint bus; + public readonly uint slot; + public readonly uint function; + + public readonly ushort VendorID; + public readonly ushort DeviceID; + + public readonly ushort Command; + public readonly ushort Status; + + public readonly byte RevisionID; + public readonly byte ProgIF; + public readonly byte Subclass; + public readonly byte ClassCode; + public readonly byte SecondaryBusNumber; + + public readonly bool DeviceExists; + + public readonly PCIHeaderType HeaderType; + public readonly PCIBist BIST; + public readonly PCIInterruptPIN InterruptPIN; + + public const ushort ConfigAddressPort = 0xCF8; + public const ushort ConfigDataPort = 0xCFC; + + public PCIBaseAddressBar[] BaseAddressBar; + + protected static Core.IOGroup.PCI IO = new Core.IOGroup.PCI(); + + public PCIDevice(uint bus, uint slot, uint function) + { + this.bus = bus; + this.slot = slot; + this.function = function; + + VendorID = ReadRegister16((byte)Config.VendorID); + DeviceID = ReadRegister16((byte)Config.DeviceID); + + Command = ReadRegister16((byte)Config.Command); + Status = ReadRegister16((byte)Config.Status); + + + RevisionID = ReadRegister8((byte)Config.RevisionID); + ProgIF = ReadRegister8((byte)Config.ProgIF); + Subclass = ReadRegister8((byte)Config.SubClass); + ClassCode = ReadRegister8((byte)Config.Class); + SecondaryBusNumber = ReadRegister8((byte)Config.SecondaryBusNo); + + HeaderType = (PCIHeaderType)ReadRegister8((byte)Config.HeaderType); + BIST = (PCIBist)ReadRegister8((byte)Config.BIST); + InterruptPIN = (PCIInterruptPIN)ReadRegister8((byte)Config.InterruptPIN); + + DeviceExists = (uint)VendorID != 0xFFFF && (uint)DeviceID != 0xFFFF; + if (HeaderType == PCIHeaderType.Normal) + { + BaseAddressBar = new PCIBaseAddressBar[6]; + BaseAddressBar[0] = new PCIBaseAddressBar(ReadRegister32(0x10)); + BaseAddressBar[1] = new PCIBaseAddressBar(ReadRegister32(0x14)); + BaseAddressBar[2] = new PCIBaseAddressBar(ReadRegister32(0x18)); + BaseAddressBar[3] = new PCIBaseAddressBar(ReadRegister32(0x1C)); + BaseAddressBar[4] = new PCIBaseAddressBar(ReadRegister32(0x20)); + BaseAddressBar[5] = new PCIBaseAddressBar(ReadRegister32(0x24)); + } } - public static void Setup() + public static ushort GetHeaderType(ushort Bus, ushort Slot, ushort Function) { - Devices = new List(); - if ((PCIDevice.GetHeaderType(0x0, 0x0, 0x0) & 0x80) == 0) + UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0xE & 0xFC; + IO.ConfigAddressPort.DWord = xAddr; + return (byte)(IO.ConfigDataPort.DWord >> ((0xE % 4) * 8) & 0xFF); + } + + public static UInt16 GetVendorID(ushort Bus, ushort Slot, ushort Function) + { + UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0x0 & 0xFC; + IO.ConfigAddressPort.DWord = xAddr; + return (UInt16)(IO.ConfigDataPort.DWord >> ((0x0 % 4) * 8) & 0xFFFF); + } + + #region IOReadWrite + protected byte ReadRegister8(byte aRegister) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + return (byte)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFF); + } + + protected void WriteRegister8(byte aRegister, byte value) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + IO.ConfigDataPort.Byte = value; + } + + protected UInt16 ReadRegister16(byte aRegister) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + return (UInt16)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFFFF); + } + + protected void WriteRegister16(byte aRegister, ushort value) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + IO.ConfigDataPort.Word = value; + } + + protected UInt32 ReadRegister32(byte aRegister) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + return IO.ConfigDataPort.DWord; + } + + protected void WriteRegister32(byte aRegister, uint value) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + IO.ConfigDataPort.DWord = value; + } + #endregion + + protected static UInt32 GetAddressBase(uint aBus, uint aSlot, uint aFunction) + { + return 0x80000000 | (aBus << 16) | ((aSlot & 0x1F) << 11) | ((aFunction & 0x07) << 8); + } + + public void EnableMemory(bool enable) + { + UInt16 command = ReadRegister16(0x04); + + UInt16 flags = 0x0007; + + if (enable) + command |= flags; + else + command &= (ushort)~flags; + + WriteRegister16(0x04, command); + } + + public void EnableBusMaster(bool enable) + { + UInt16 command = ReadRegister16(0x04); + + UInt16 flags = (1 << 2); + + if (enable) + command |= flags; + else + command &= (ushort)~flags; + + WriteRegister16(0x04, command); + } + + public class DeviceClass + { + public static string GetString(PCIDevice device) { - CheckBus(0x0); + switch (device.VendorID) + { + case 0x1022: //AMD + switch (device.DeviceID) + { + case 0x2000: + return "AMD PCnet LANCE PCI Ethernet Controller"; + } + break; + case 0x104B: //Sony + switch (device.DeviceID) + { + case 0x1040: + return "Mylex BT958 SCSI Host Adaptor"; + } + break; + case 0x1274: //Ensoniq + switch (device.DeviceID) + { + case 0x1371: + return "Ensoniq AudioPCI"; + } + break; + case 0x15AD: //VMware + switch (device.DeviceID) + { + case 0x0405: + return "VMware NVIDIA 9500MGS"; + case 0x0770: + return "VMware Standard Enhanced PCI to USB Host Controller"; + case 0x0790: + return "VMware 6.0 Virtual USB 2.0 Host Controller"; + case 0x07A0: + return "VMware PCI Express Root Port"; + } + break; + case 0x8086: //Intel + switch (device.DeviceID) + { + case 0x7190: + return "Intel 440BX/ZX AGPset Host Bridge"; + case 0x7191: + return "Intel 440BX/ZX AGPset PCI-to-PCI bridge"; + case 0x7110: + return "Intel PIIX4/4E/4M ISA Bridge"; + case 0x7112: + return "Intel PIIX4/4E/4M USB Interface"; + } + break; + } + + switch (device.ClassCode) + { + //case 0x00: + // return "Any device"; + case 0x01: + return "Mass Storage Controller"; + case 0x02: + return "Network Controller"; + case 0x03: + return "Display Controller"; + case 0x04: + return "Multimedia Controller"; + case 0x05: + return "Memory Controller"; + case 0x06: + return "Bridge Device"; + case 0x07: + return "Simple Communication Controller"; + case 0x08: + return "Base System Peripheral"; + case 0x09: + return "Input Device"; + case 0x0A: + return "Docking Station"; + case 0x0B: + return "Processor"; + case 0x0C: + return "Serial Bus Controller"; + case 0x0D: + return "Wireless Controller"; + case 0x0E: + return "Intelligent I/O Controller"; + case 0x0F: + return "Satellite Communication Controller"; + case 0x10: + return "Encryption/Decryption Controller"; + case 0x11: + return "Data Acquisition and Signal Processing Controller"; + //case 0xFF: + // return "Unkown device"; + } + return "ClassCode: " + device.ClassCode + " Subclass: " + device.Subclass + " ProgIF: " + device.ProgIF; + } + } + + private static string ToHex(uint aNumber, byte aBits) + { + return "0x" + aNumber.ToHex(aBits / 4); + } + } + + public class PCIBaseAddressBar + { + private uint baseAddress = 0; + private ushort prefetchable = 0; + private ushort type = 0; + private bool isIO = false; + + public PCIBaseAddressBar(uint raw) + { + isIO = (raw & 0x01) == 1; + + if (isIO) + { + baseAddress = raw & 0xFFFFFFFC; } else { - for (ushort fn = 0; fn < 8; fn++) + type = (ushort)((raw >> 1) & 0x03); + prefetchable = (ushort)((raw >> 3) & 0x01); + switch (type) { - if (PCIDevice.GetVendorID(0x0, 0x0, fn) != 0xFFFF) + case 0x00: + baseAddress = raw & 0xFFFFFFF0; + break; + case 0x01: + baseAddress = raw & 0xFFFFFFF0; break; - - CheckBus(fn); } } } - private static void CheckBus(ushort xBus) + public uint BaseAddress { - 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)); - } - } - } + get { return baseAddress; } } - private static void CheckFunction(PCIDevice xPCIDevice) + public bool IsIO { - 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; + get { return isIO; } } } } From 5ae1780b48e10f2695dd949ba34eb9f246564730 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 07:46:45 +0300 Subject: [PATCH 43/85] [AHCI] Fix. --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index 24ffeaad4..5ca8f8022 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -33,7 +33,7 @@ namespace Cosmos.HAL.BlockDevice.Ports return; } - Mem = new Core.MemoryGroup.AHCI(); + Mem = new Core.MemoryGroup.AHCI(RegularSectorSize); mPortReg = aSATAPort; From a5ee5501d0276ae702ff96b1197f14a6501c99db Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 16:19:52 +0300 Subject: [PATCH 44/85] [Sata] Fix. --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index 5ca8f8022..bd80b4f96 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -33,7 +33,7 @@ namespace Cosmos.HAL.BlockDevice.Ports return; } - Mem = new Core.MemoryGroup.AHCI(RegularSectorSize); + Mem = new Core.MemoryGroup.AHCI((uint)RegularSectorSize); mPortReg = aSATAPort; From 30572e9e90ade11dc43039c35f6120c65afe5970 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 16:23:35 +0300 Subject: [PATCH 45/85] Not important --- source/Cosmos.HAL2/PCIDevice.cs | 362 -------------------------------- 1 file changed, 362 deletions(-) delete mode 100644 source/Cosmos.HAL2/PCIDevice.cs diff --git a/source/Cosmos.HAL2/PCIDevice.cs b/source/Cosmos.HAL2/PCIDevice.cs deleted file mode 100644 index 6419beceb..000000000 --- a/source/Cosmos.HAL2/PCIDevice.cs +++ /dev/null @@ -1,362 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Cosmos.Core.IOGroup; -using Cosmos.Common.Extensions; -using Cosmos.Debug.Kernel; - -namespace Cosmos.HAL -{ - public class PCIDevice - { - - #region Enums - public enum PCIHeaderType : byte - { - Normal = 0x00, - Bridge = 0x01, - Cardbus = 0x02 - }; - - public enum PCIBist : byte - { - CocdMask = 0x0f, - Start = 0x40, - Capable = 0x80 - }; - - public enum PCIInterruptPIN : byte - { - None = 0x00, - INTA = 0x01, - INTB = 0x02, - INTC = 0x03, - INTD = 0x04 - }; - - public enum Config : byte - { - VendorID = 0, DeviceID = 2, - Command = 4, Status = 6, - RevisionID = 8, ProgIF = 9, SubClass = 10, Class = 11, - CacheLineSize = 12, LatencyTimer = 13, HeaderType = 14, BIST = 15, - BAR0 = 16, - BAR1 = 20, - PrimaryBusNo = 24, SecondaryBusNo = 25, SubBusNo = 26, SecondarLT = 27, - IOBase = 28, IOLimit = 29, SecondaryStatus = 30, - MemoryBase = 32, MemoryLimit = 34, - PrefMemoryBase = 36, PrefMemoryLimit = 38, - PrefBase32Upper = 40, - PrefLimit32upper = 44, - PrefBase16Upper = 48, PrefLimit16upper = 50, - CapabilityPointer = 52, Reserved = 53, - ExpROMBaseAddress = 56, - InterruptLine = 60, InterruptPIN = 61, BridgeControl = 62 - }; - #endregion - - public readonly uint bus; - public readonly uint slot; - public readonly uint function; - - public readonly ushort VendorID; - public readonly ushort DeviceID; - - public readonly ushort Command; - public readonly ushort Status; - - public readonly byte RevisionID; - public readonly byte ProgIF; - public readonly byte Subclass; - public readonly byte ClassCode; - public readonly byte SecondaryBusNumber; - - public readonly bool DeviceExists; - - public readonly PCIHeaderType HeaderType; - public readonly PCIBist BIST; - public readonly PCIInterruptPIN InterruptPIN; - - public const ushort ConfigAddressPort = 0xCF8; - public const ushort ConfigDataPort = 0xCFC; - - public PCIBaseAddressBar[] BaseAddressBar; - - protected static Core.IOGroup.PCI IO = new Core.IOGroup.PCI(); - - public PCIDevice(uint bus, uint slot, uint function) - { - this.bus = bus; - this.slot = slot; - this.function = function; - - VendorID = ReadRegister16((byte)Config.VendorID); - DeviceID = ReadRegister16((byte)Config.DeviceID); - - Command = ReadRegister16((byte)Config.Command); - Status = ReadRegister16((byte)Config.Status); - - - RevisionID = ReadRegister8((byte)Config.RevisionID); - ProgIF = ReadRegister8((byte)Config.ProgIF); - Subclass = ReadRegister8((byte)Config.SubClass); - ClassCode = ReadRegister8((byte)Config.Class); - SecondaryBusNumber = ReadRegister8((byte)Config.SecondaryBusNo); - - HeaderType = (PCIHeaderType)ReadRegister8((byte)Config.HeaderType); - BIST = (PCIBist)ReadRegister8((byte)Config.BIST); - InterruptPIN = (PCIInterruptPIN)ReadRegister8((byte)Config.InterruptPIN); - - DeviceExists = (uint)VendorID != 0xFFFF && (uint)DeviceID != 0xFFFF; - if (HeaderType == PCIHeaderType.Normal) - { - BaseAddressBar = new PCIBaseAddressBar[6]; - BaseAddressBar[0] = new PCIBaseAddressBar(ReadRegister32(0x10)); - BaseAddressBar[1] = new PCIBaseAddressBar(ReadRegister32(0x14)); - BaseAddressBar[2] = new PCIBaseAddressBar(ReadRegister32(0x18)); - BaseAddressBar[3] = new PCIBaseAddressBar(ReadRegister32(0x1C)); - BaseAddressBar[4] = new PCIBaseAddressBar(ReadRegister32(0x20)); - BaseAddressBar[5] = new PCIBaseAddressBar(ReadRegister32(0x24)); - } - } - - public static ushort GetHeaderType(ushort Bus, ushort Slot, ushort Function) - { - UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0xE & 0xFC; - IO.ConfigAddressPort.DWord = xAddr; - return (byte)(IO.ConfigDataPort.DWord >> ((0xE % 4) * 8) & 0xFF); - } - - public static UInt16 GetVendorID(ushort Bus, ushort Slot, ushort Function) - { - UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0x0 & 0xFC; - IO.ConfigAddressPort.DWord = xAddr; - return (UInt16)(IO.ConfigDataPort.DWord >> ((0x0 % 4) * 8) & 0xFFFF); - } - - #region IOReadWrite - protected byte ReadRegister8(byte aRegister) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - return (byte)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFF); - } - - protected void WriteRegister8(byte aRegister, byte value) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - IO.ConfigDataPort.Byte = value; - } - - protected UInt16 ReadRegister16(byte aRegister) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - return (UInt16)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFFFF); - } - - protected void WriteRegister16(byte aRegister, ushort value) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - IO.ConfigDataPort.Word = value; - } - - protected UInt32 ReadRegister32(byte aRegister) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - return IO.ConfigDataPort.DWord; - } - - protected void WriteRegister32(byte aRegister, uint value) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - IO.ConfigDataPort.DWord = value; - } - #endregion - - protected static UInt32 GetAddressBase(uint aBus, uint aSlot, uint aFunction) - { - return 0x80000000 | (aBus << 16) | ((aSlot & 0x1F) << 11) | ((aFunction & 0x07) << 8); - } - - public void EnableMemory(bool enable) - { - UInt16 command = ReadRegister16(0x04); - - UInt16 flags = 0x0007; - - if (enable) - command |= flags; - else - command &= (ushort)~flags; - - WriteRegister16(0x04, command); - } - - public void EnableBusMaster(bool enable) - { - UInt16 command = ReadRegister16(0x04); - - UInt16 flags = (1 << 2); - - if (enable) - command |= flags; - else - command &= (ushort)~flags; - - WriteRegister16(0x04, command); - } - - public class DeviceClass - { - public static string GetString(PCIDevice device) - { - switch (device.VendorID) - { - case 0x1022: //AMD - switch (device.DeviceID) - { - case 0x2000: - return "AMD PCnet LANCE PCI Ethernet Controller"; - } - break; - case 0x104B: //Sony - switch (device.DeviceID) - { - case 0x1040: - return "Mylex BT958 SCSI Host Adaptor"; - } - break; - case 0x1274: //Ensoniq - switch (device.DeviceID) - { - case 0x1371: - return "Ensoniq AudioPCI"; - } - break; - case 0x15AD: //VMware - switch (device.DeviceID) - { - case 0x0405: - return "VMware NVIDIA 9500MGS"; - case 0x0770: - return "VMware Standard Enhanced PCI to USB Host Controller"; - case 0x0790: - return "VMware 6.0 Virtual USB 2.0 Host Controller"; - case 0x07A0: - return "VMware PCI Express Root Port"; - } - break; - case 0x8086: //Intel - switch (device.DeviceID) - { - case 0x7190: - return "Intel 440BX/ZX AGPset Host Bridge"; - case 0x7191: - return "Intel 440BX/ZX AGPset PCI-to-PCI bridge"; - case 0x7110: - return "Intel PIIX4/4E/4M ISA Bridge"; - case 0x7112: - return "Intel PIIX4/4E/4M USB Interface"; - } - break; - } - - switch (device.ClassCode) - { - //case 0x00: - // return "Any device"; - case 0x01: - return "Mass Storage Controller"; - case 0x02: - return "Network Controller"; - case 0x03: - return "Display Controller"; - case 0x04: - return "Multimedia Controller"; - case 0x05: - return "Memory Controller"; - case 0x06: - return "Bridge Device"; - case 0x07: - return "Simple Communication Controller"; - case 0x08: - return "Base System Peripheral"; - case 0x09: - return "Input Device"; - case 0x0A: - return "Docking Station"; - case 0x0B: - return "Processor"; - case 0x0C: - return "Serial Bus Controller"; - case 0x0D: - return "Wireless Controller"; - case 0x0E: - return "Intelligent I/O Controller"; - case 0x0F: - return "Satellite Communication Controller"; - case 0x10: - return "Encryption/Decryption Controller"; - case 0x11: - return "Data Acquisition and Signal Processing Controller"; - //case 0xFF: - // return "Unkown device"; - } - return "ClassCode: " + device.ClassCode + " Subclass: " + device.Subclass + " ProgIF: " + device.ProgIF; - } - } - - private static string ToHex(uint aNumber, byte aBits) - { - return "0x" + aNumber.ToHex(aBits / 4); - } - } - - public class PCIBaseAddressBar - { - private uint baseAddress = 0; - private ushort prefetchable = 0; - private ushort type = 0; - private bool isIO = false; - - public PCIBaseAddressBar(uint raw) - { - isIO = (raw & 0x01) == 1; - - if (isIO) - { - baseAddress = raw & 0xFFFFFFFC; - } - else - { - type = (ushort)((raw >> 1) & 0x03); - prefetchable = (ushort)((raw >> 3) & 0x01); - switch (type) - { - case 0x00: - baseAddress = raw & 0xFFFFFFF0; - break; - case 0x01: - baseAddress = raw & 0xFFFFFFF0; - break; - } - } - } - - public uint BaseAddress - { - get { return baseAddress; } - } - - public bool IsIO - { - get { return isIO; } - } - } -} From 098963a1ffdaad3e16dce2d50e287dfc4713792b Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 16:24:04 +0300 Subject: [PATCH 46/85] [PciDevice] Add EnableBusMaster --- source/Cosmos.HAL2/PciDevice.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/source/Cosmos.HAL2/PciDevice.cs b/source/Cosmos.HAL2/PciDevice.cs index 572a6c928..6419beceb 100644 --- a/source/Cosmos.HAL2/PciDevice.cs +++ b/source/Cosmos.HAL2/PciDevice.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -198,6 +198,20 @@ namespace Cosmos.HAL WriteRegister16(0x04, command); } + public void EnableBusMaster(bool enable) + { + UInt16 command = ReadRegister16(0x04); + + UInt16 flags = (1 << 2); + + if (enable) + command |= flags; + else + command &= (ushort)~flags; + + WriteRegister16(0x04, command); + } + public class DeviceClass { public static string GetString(PCIDevice device) @@ -345,4 +359,4 @@ namespace Cosmos.HAL get { return isIO; } } } -} \ No newline at end of file +} From ed760098147c7b5741a81bbf485415d01fbebffd Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 22 Dec 2017 16:41:30 +0300 Subject: [PATCH 47/85] [AHCI] Replace "Convert.ToBoolean(byte)" with byte == 1 --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 6a0478916..1cd5b45aa 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -145,25 +145,25 @@ namespace Cosmos.HAL.BlockDevice private void GetCapabilities() { NumOfPorts = mGeneric.Capabilities & 0x1F; - SupportsExternalSATA = Convert.ToBoolean(mGeneric.Capabilities >> 5 & 1); - EnclosureManagementSupported = Convert.ToBoolean(mGeneric.Capabilities >> 6 & 1); - CommandCompletionCoalsecingSupported = Convert.ToBoolean(mGeneric.Capabilities >> 7 & 1); + SupportsExternalSATA = (mGeneric.Capabilities >> 5 & 1) == 1; + EnclosureManagementSupported = (mGeneric.Capabilities >> 6 & 1) == 1; + CommandCompletionCoalsecingSupported = (mGeneric.Capabilities >> 7 & 1) == 1; NumOfCommandSlots = mGeneric.Capabilities >> 8 & 0x1F; - PartialStateCapable = Convert.ToBoolean(mGeneric.Capabilities >> 13 & 1); - SlumberStateCapable = Convert.ToBoolean(mGeneric.Capabilities >> 14 & 1); - PIOMultipleDRQBlock = Convert.ToBoolean(mGeneric.Capabilities >> 15 & 1); - FISBasedSwitchingSupported = Convert.ToBoolean(mGeneric.Capabilities >> 16 & 1); - SupportsPortMutliplier = Convert.ToBoolean(mGeneric.Capabilities >> 17 & 1); - SupportsAHCIModeOnly = Convert.ToBoolean(mGeneric.Capabilities >> 18 & 1); + PartialStateCapable = (mGeneric.Capabilities >> 13 & 1) == 1; + SlumberStateCapable = (mGeneric.Capabilities >> 14 & 1) == 1; + PIOMultipleDRQBlock = (mGeneric.Capabilities >> 15 & 1) == 1; + FISBasedSwitchingSupported = (mGeneric.Capabilities >> 16 & 1) == 1; + SupportsPortMutliplier = (mGeneric.Capabilities >> 17 & 1) == 1; + SupportsAHCIModeOnly = (mGeneric.Capabilities >> 18 & 1) == 1; InterfaceSpeedSupport = mGeneric.Capabilities >> 20 & 0x0F; - SupportsCommandListOverride = Convert.ToBoolean(mGeneric.Capabilities >> 24 & 1); - SupportsActivityLED = Convert.ToBoolean(mGeneric.Capabilities >> 25 & 1); - SupportsAggressiveLinkPowerManagement = Convert.ToBoolean(mGeneric.Capabilities >> 26 & 1); - SupportsStaggeredSpinup = Convert.ToBoolean(mGeneric.Capabilities >> 27 & 1); - SupportsMechanicalPresenceSwitch = Convert.ToBoolean(mGeneric.Capabilities >> 28 & 1); - SupportsSNotificationRegister = Convert.ToBoolean(mGeneric.Capabilities >> 29 & 1); - SupportsNativeCommandQueuing = Convert.ToBoolean(mGeneric.Capabilities >> 30 & 1); - Supports64bitAddressing = Convert.ToBoolean(mGeneric.Capabilities >> 31 & 1); + SupportsCommandListOverride = (mGeneric.Capabilities >> 24 & 1) == 1; + SupportsActivityLED = (mGeneric.Capabilities >> 25 & 1) == 1; + SupportsAggressiveLinkPowerManagement = (mGeneric.Capabilities >> 26 & 1) == 1; + SupportsStaggeredSpinup = (mGeneric.Capabilities >> 27 & 1) == 1; + SupportsMechanicalPresenceSwitch = (mGeneric.Capabilities >> 28 & 1) == 1; + SupportsSNotificationRegister = (mGeneric.Capabilities >> 29 & 1) == 1; + SupportsNativeCommandQueuing = (mGeneric.Capabilities >> 30 & 1) == 1; + Supports64bitAddressing = (mGeneric.Capabilities >> 31 & 1) == 1; } private void GetPorts() From d4b4bd4d287359e6230aa7c9592b763888f108e9 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 08:33:29 +0300 Subject: [PATCH 48/85] [AHCI] First working AHCI Controller! --- source/Cosmos.Core/MemoryGroup/AHCI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.Core/MemoryGroup/AHCI.cs b/source/Cosmos.Core/MemoryGroup/AHCI.cs index 9f8ddab52..271adcc90 100644 --- a/source/Cosmos.Core/MemoryGroup/AHCI.cs +++ b/source/Cosmos.Core/MemoryGroup/AHCI.cs @@ -10,7 +10,7 @@ namespace Cosmos.Core.MemoryGroup public AHCI(uint aSectorSize) { - DataBlock = new Core.MemoryBlock(0x00400000, aSectorSize * 256); + DataBlock = new Core.MemoryBlock(0x0046C000, aSectorSize * 256); DataBlock.Fill(0); } } From 96a35b2b6aa9efdc1f286c83bc8be7334f932aff Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 08:40:29 +0300 Subject: [PATCH 49/85] [AHCI] First working AHCI Controller --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 169 +++++++++++++++---------- 1 file changed, 99 insertions(+), 70 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 1cd5b45aa..cd260aa7f 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -10,10 +10,10 @@ using Cosmos.Core.Memory.Old; namespace Cosmos.HAL.BlockDevice { - public class AHCI + public class AHCI : Drivers.PCIDriver { internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); - internal static PCIDevice xDevice = HAL.PCI.GetDevice(0x01, 0x06); + internal static PCIDevice xDevice = HAL.PCI.GetDevice(0x001, 0x0006); private static List mPorts = new List(); private static GenericRegisters mGeneric; @@ -55,16 +55,16 @@ namespace Cosmos.HAL.BlockDevice internal static void InitDriver() { - if (xDevice != null) - { - AHCI Driver = new AHCI(xDevice); - } + + if (xDevice == null) return; + AHCI Driver = new AHCI(xDevice); } - internal PCIDevice GetDevice() => xDevice; + internal override PCIDevice GetDevice() => xDevice; public AHCI(PCIDevice aAHCIDevice) { + mAHCIDebugger.Send("Something wrong!"); aAHCIDevice.EnableBusMaster(true); aAHCIDevice.EnableMemory(true); @@ -80,7 +80,7 @@ namespace Cosmos.HAL.BlockDevice { if(xPort.mPortType == PortType.SATA) { - mAHCIDebugger.Send($"{xPort.mPortName} Port [0:{xPort.mPortNumber}]"); + mAHCIDebugger.Send($"{xPort.mPortName} Port 0:{xPort.mPortNumber}"); var xMBRData = new byte[512]; xPort.ReadBlock(0UL, 1U, xMBRData); var xMBR = new MBR(xMBRData); @@ -88,6 +88,7 @@ namespace Cosmos.HAL.BlockDevice if (xMBR.EBRLocation != 0) { // EBR Detected! + mAHCIDebugger.Send("EBR Detected within MBR code"); var xEBRData = new byte[512]; xPort.ReadBlock(xMBR.EBRLocation, 1U, xEBRData); var xEBR = new EBR(xEBRData); @@ -99,7 +100,7 @@ namespace Cosmos.HAL.BlockDevice } } - mAHCIDebugger.Send($"Number of MBR partitions in port [0:{xPort.mPortNumber}]: "); + mAHCIDebugger.Send($"Number of MBR partitions found on port 0:{xPort.mPortNumber} "); mAHCIDebugger.SendNumber(xMBR.Partitions.Count); for (int i = 0; i < xMBR.Partitions.Count; i++) { @@ -119,16 +120,50 @@ namespace Cosmos.HAL.BlockDevice else if (xPort.mPortType == PortType.SATAPI) { mAHCIDebugger.Send($"{xPort.mPortName} Port 0:{xPort.mPortNumber}"); - // TODO: Implement ISO-9660 or UDF and Fix SATAPI + + // Just to test Read Sector! + + //byte[] xMBRData = new byte[512]; + //xPort.ReadBlock(0UL, 1U, xMBRData); + //MBR xMBR = new MBR(xMBRData); + + //mAHCIDebugger.Send($"Number of corrupted MBR partitions found on port 0:{xPort.mPortNumber} "); + //mAHCIDebugger.SendNumber(xMBR.Partitions.Count); + //for (int i = 0; i < xMBR.Partitions.Count; i++) + //{ + // var xPart = xMBR.Partitions[i]; + // if (xPart == null) + // { + // Console.WriteLine("Null partition found at idx: " + i); + // } + // else + // { + // var xPartDevice = new Partition(xPort, xPart.StartSector, xPart.SectorCount); + // BlockDevice.Devices.Add(xPartDevice); + // Console.WriteLine("Found corrupted partition at idx: " + i); + // } + //} } } } - private void Wait(int microsecondsTimeout) + public static void HBAReset() + { + mGeneric.GlobalHostControl = 1; + uint HR = 0; + do + { + Wait(1); + HR = mGeneric.GlobalHostControl & 1; + } while (HR != 0); + } + + public static void Wait(int microsecondsTimeout) { byte xVoid; for (int i = 0; i < microsecondsTimeout; i++) { + // Random IOPort xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; xVoid = Core.Global.BaseIOGroups.TextScreen.Data1.Byte; @@ -144,26 +179,26 @@ namespace Cosmos.HAL.BlockDevice private void GetCapabilities() { - NumOfPorts = mGeneric.Capabilities & 0x1F; - SupportsExternalSATA = (mGeneric.Capabilities >> 5 & 1) == 1; - EnclosureManagementSupported = (mGeneric.Capabilities >> 6 & 1) == 1; - CommandCompletionCoalsecingSupported = (mGeneric.Capabilities >> 7 & 1) == 1; - NumOfCommandSlots = mGeneric.Capabilities >> 8 & 0x1F; - PartialStateCapable = (mGeneric.Capabilities >> 13 & 1) == 1; - SlumberStateCapable = (mGeneric.Capabilities >> 14 & 1) == 1; - PIOMultipleDRQBlock = (mGeneric.Capabilities >> 15 & 1) == 1; - FISBasedSwitchingSupported = (mGeneric.Capabilities >> 16 & 1) == 1; - SupportsPortMutliplier = (mGeneric.Capabilities >> 17 & 1) == 1; - SupportsAHCIModeOnly = (mGeneric.Capabilities >> 18 & 1) == 1; - InterfaceSpeedSupport = mGeneric.Capabilities >> 20 & 0x0F; - SupportsCommandListOverride = (mGeneric.Capabilities >> 24 & 1) == 1; - SupportsActivityLED = (mGeneric.Capabilities >> 25 & 1) == 1; + NumOfPorts = mGeneric.Capabilities & 0x1F; + SupportsExternalSATA = (mGeneric.Capabilities >> 5 & 1) == 1; + EnclosureManagementSupported = (mGeneric.Capabilities >> 6 & 1) == 1; + CommandCompletionCoalsecingSupported = (mGeneric.Capabilities >> 7 & 1) == 1; + NumOfCommandSlots = mGeneric.Capabilities >> 8 & 0x1F; + PartialStateCapable = (mGeneric.Capabilities >> 13 & 1) == 1; + SlumberStateCapable = (mGeneric.Capabilities >> 14 & 1) == 1; + PIOMultipleDRQBlock = (mGeneric.Capabilities >> 15 & 1) == 1; + FISBasedSwitchingSupported = (mGeneric.Capabilities >> 16 & 1) == 1; + SupportsPortMutliplier = (mGeneric.Capabilities >> 17 & 1) == 1; + SupportsAHCIModeOnly = (mGeneric.Capabilities >> 18 & 1) == 1; + InterfaceSpeedSupport = mGeneric.Capabilities >> 20 & 0x0F; + SupportsCommandListOverride = (mGeneric.Capabilities >> 24 & 1) == 1; + SupportsActivityLED = (mGeneric.Capabilities >> 25 & 1) == 1; SupportsAggressiveLinkPowerManagement = (mGeneric.Capabilities >> 26 & 1) == 1; - SupportsStaggeredSpinup = (mGeneric.Capabilities >> 27 & 1) == 1; - SupportsMechanicalPresenceSwitch = (mGeneric.Capabilities >> 28 & 1) == 1; - SupportsSNotificationRegister = (mGeneric.Capabilities >> 29 & 1) == 1; - SupportsNativeCommandQueuing = (mGeneric.Capabilities >> 30 & 1) == 1; - Supports64bitAddressing = (mGeneric.Capabilities >> 31 & 1) == 1; + SupportsStaggeredSpinup = (mGeneric.Capabilities >> 27 & 1) == 1; + SupportsMechanicalPresenceSwitch = (mGeneric.Capabilities >> 28 & 1) == 1; + SupportsSNotificationRegister = (mGeneric.Capabilities >> 29 & 1) == 1; + SupportsNativeCommandQueuing = (mGeneric.Capabilities >> 30 & 1) == 1; + Supports64bitAddressing = (mGeneric.Capabilities >> 31 & 1) == 1; } private void GetPorts() @@ -171,45 +206,40 @@ namespace Cosmos.HAL.BlockDevice // Search for disks var xImplementedPort = mGeneric.ImplementedPorts; var xPort = 0; - while (xPort < NumOfPorts) + for(; xPort < 32; xPort++) { if ((xImplementedPort & 1) != 0) { - PortRegisters xPortReg = new PortRegisters((uint)mABAR + 0x100 + (uint)(0x80 * xPort), (uint)xPort); + PortRegisters xPortReg = new PortRegisters((uint)mABAR + 0x100, (uint)xPort); PortType PortType = CheckPortType(xPortReg); xPortReg.mPortType = PortType; var xPortString = "0:" + ((xPort.ToString().Length <= 1) ? xPort.ToString().PadLeft(1, '0') : xPort.ToString()); - if (PortType == PortType.SATA) // If Port Type was SATA. + if (PortType == PortType.SATA) // If Port type was SATA. { - Console.WriteLine("Initializing Port " + xPortString + " with type SATA"); - UInt16[] xSectorData = new UInt16[256]; + mAHCIDebugger.Send("Initializing Port " + xPortString + " with type SATA"); PortRebase(xPortReg, (uint)xPort); - SATA xSATAPort = new SATA(xPortReg); + var xSATAPort = new SATA(xPortReg); mPorts.Add(xSATAPort); } - else if (PortType == PortType.SATAPI) // If Port Type was SATAPI. + else if (PortType == PortType.SATAPI) // If Port type was SATAPI. { - mAHCIDebugger.Send("SATAPI"); - Console.WriteLine("Initializing Port " + xPortString + " with type Serial ATAPI"); + mAHCIDebugger.Send("Initializing Port " + xPortString + " with type Serial ATAPI"); //PortRebase(xPortReg, (uint)xPort); - //SATAPI xSATAPIPort = new SATAPI(xPortReg); + //var xSATAPIPort = new SATAPI(xPortReg); //mPorts.Add(xSATAPIPort); } - else if (PortType == PortType.SEMB) // If Port Type was SEMB. + else if (PortType == PortType.SEMB) // If Port type was SEMB. { - Console.WriteLine("SEMB Drive at port " + xPortString + " found, which is not supported yet!"); + mAHCIDebugger.Send("SEMB Drive at port " + xPortString + " found, which is not supported yet!"); } - else if (PortType == PortType.PM) // If Port Type was Port Mulitplier. + else if (PortType == PortType.PM) // If Port type was Port Mulitplier. { - Console.WriteLine("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); + mAHCIDebugger.Send("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); } - else if (PortType == PortType.Nothing) - mAHCIDebugger.Send("No drive found at port: " + xPortString); - else + else if (PortType != PortType.Nothing) mAHCIDebugger.Send("Unknown drive found with signature: 0x" + xPortReg.SIG);// If Implemented Port value was not zero and non of the above. } xImplementedPort >>= 1; - xPort++; } } @@ -219,10 +249,8 @@ namespace Cosmos.HAL.BlockDevice var xSPD = (CurrentInterfaceSpeedStatus)((aPort.SSTS >> 4) & 0x0F); var xDET = (DeviceDetectionStatus)(aPort.SSTS & 0x0F); var xSignature = aPort.SIG; - //var LBALow = (byte)(Port.SIG >> 08); - //var LBAMedium = (byte)(Port.SIG >> 16); - //var LBAHigh = (byte)(Port.SIG >> 24); + // Check if not reading wrong data! if (xIPM != InterfacePowerManagementStatus.Active) return PortType.Nothing; if (xDET != DeviceDetectionStatus.DeviceDetectedWithPhy) @@ -241,49 +269,47 @@ namespace Cosmos.HAL.BlockDevice private void PortRebase(PortRegisters aPort, uint aPortNumber) { mAHCIDebugger.Send("Stop"); - if (!StopCMD(aPort)) aPort.SCTL = 1; + if (!StopCMD(aPort)) SATA.PortReset(aPort); - ulong mCLBAddress = Heap.MemAlloc(1024); - aPort.CLB = (uint)mCLBAddress & 0xFFFFFFFF; - - var mFBAddress = Heap.MemAlloc(256); - aPort.FB = (uint)mFBAddress & 0xFFFFFFFF; + aPort.CLB = (uint)Base.AHCI + (0x400 * aPortNumber); + aPort.FB = (uint)Base.AHCI + 0x8000 + (0x100 * aPortNumber); aPort.SERR = 1; aPort.IS = 0; aPort.IE = 0; - + new MemoryBlock(aPort.CLB, 1024).Fill(0); new MemoryBlock(aPort.FB, 256).Fill(0); - - GetCommandHeader(aPort); // Rebasing Command Header - StartCMD(aPort); + GetCommandHeader(aPort); // Rebase Command header + + if (!StartCMD(aPort)) SATA.PortReset(aPort); + aPort.IS = 0; aPort.IE = 0xFFFFFFFF; + + mAHCIDebugger.Send("Finished!"); } private static HBACommandHeader[] GetCommandHeader(PortRegisters aPort) { - var xCTBAAddress = Heap.MemAlloc(256); HBACommandHeader[] xCMDHeader = new HBACommandHeader[32]; for (uint i = 0; i < xCMDHeader.Length; i++) { xCMDHeader[i] = new HBACommandHeader(aPort.CLB, i) { - PRDTL = 8, // 8 prdt entries per command table - // 256 bytes per command table, 64+16+48+16*8 - CTBA = xCTBAAddress + (256 * i), - //TODO: Use the below register as the upper base address if HBA - // supports S64A (64-bit Addressing) + PRDTL = 8, + + CTBA = (uint)(Base.AHCI + 0xA000) + (0x2000 * aPort.mPortNumber) + (0x100 * i), + CTBAU = 0 }; - new MemoryBlock(xCMDHeader[i].CTBA, 256).Fill(0); + new MemoryBlock(xCMDHeader[i].CTBA, 0x100).Fill(0); } return xCMDHeader; } - private void StartCMD(PortRegisters aPort) + private bool StartCMD(PortRegisters aPort) { int xSpin; for (xSpin = 0; xSpin < 101; xSpin++) @@ -291,12 +317,15 @@ namespace Cosmos.HAL.BlockDevice if ((aPort.CMD & (uint)CommandAndStatus.CMDListRunning) == 0) break; Wait(5000); } - if (xSpin == 101) return; + if (xSpin == 101) return false; aPort.CMD |= (1 << 4); aPort.CMD |= (1 << 0); + + return true; } + // Thanks to Microsoft for the detailed info about stopping command process! private bool StopCMD(PortRegisters aPort) { int xSpin; From 3f10ebc961edd6dba7f266e729216561829bfc7f Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 08:46:36 +0300 Subject: [PATCH 50/85] [AHCI] First working AHCI Controller --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 353 +++++++++---------- 1 file changed, 172 insertions(+), 181 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index bd80b4f96..c15baabc8 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -21,242 +21,208 @@ namespace Cosmos.HAL.BlockDevice.Ports // Constants public const ulong RegularSectorSize = 512UL; + // Properties + private string mSerialNo; + private string mFirmwareRev; + private string mModelNo; + + public string SerialNo { get => mSerialNo; } + public string FirmwareRev { get => mFirmwareRev; } + public string ModelNo { get => mModelNo; } + public SATA(PortRegisters aSATAPort) { // Check if it is really a SATA Port! - if(aSATAPort.mPortType != PortType.SATA || (aSATAPort.CMD & (1U << 24)) != 0) + if (aSATAPort.mPortType != PortType.SATA || (aSATAPort.CMD & (1U << 24)) != 0) { Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Error]"); + Console.Write("[Error]"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($" 0:{aSATAPort.mPortNumber} is not a SATA port!\n"); return; } - Mem = new Core.MemoryGroup.AHCI((uint)RegularSectorSize); + Mem = new Core.MemoryGroup.AHCI(); mPortReg = aSATAPort; // Setting Offset arg to Global offset mBlockSize = RegularSectorSize; - mBlockCount = 256; - SendSATACommand(ATACommands.Identify); + // TODO: Use SendSATACommand(ATACommands.Identify) and copy the useful isIdentify if's from SendSATA28Command + // But make sure that isIdentify returns the exact value (true if the command is identify + // or false if not identify). + SendSATA28Command((ATACommands)0x00, 0, 0); UInt16[] xBuffer = new UInt16[256]; - System.Threading.Thread.Sleep(1000); Mem.DataBlock.Read16(xBuffer); - var xBlockCount48 = (xBuffer[102] << 32 | (xBuffer[101] << 16 | xBuffer[100])) - 1; - mBlockCount = (ulong)xBlockCount48; + mSerialNo = GetString(xBuffer, 10, 20); + mFirmwareRev = GetString(xBuffer, 23, 8); + mModelNo = GetString(xBuffer, 27, 40); + + mBlockCount = ((UInt32)xBuffer[61] << 16 | xBuffer[60]) - 1; } public void SendSATACommand(ATACommands aCommand) { - bool isIdentify = (aCommand == ATACommands.Identify); - - mPortReg.IS = unchecked((uint)-1); + mPortReg.IS = 0xFFFF; int xSlot = FindCMDSlot(); if (xSlot == -1) return; - + HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); xCMDHeader.CFL = 5; - xCMDHeader.PRDTL = (ushort)((isIdentify) ? 1 : 0); + xCMDHeader.PRDTL = 1; xCMDHeader.Write = 0; - - xCMDHeader.CTBA = Heap.MemAlloc(256); - HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); - - if (isIdentify) - { - Console.WriteLine("Identify"); - xCMDTable.PRDTEntry = new HBAPRDTEntry[xCMDHeader.PRDTL]; - for (uint i = 0; i < xCMDTable.PRDTEntry.Length; i++) - { - xCMDTable.PRDTEntry[i] = new HBAPRDTEntry(xCMDHeader.CTBA + 0x80, i); - } + xCMDHeader.CTBA = (uint)((uint)(Base.AHCI + 0xA000) + (0x2000 * mPortNumber) + (0x100 * xSlot)); - var BaseAddress = Mem.DataBlock.Base; - xCMDTable.PRDTEntry[xCMDTable.PRDTEntry.Length - 1].DBA = BaseAddress - 2; - xCMDTable.PRDTEntry[xCMDTable.PRDTEntry.Length - 1].DBC = 511; - xCMDTable.PRDTEntry[xCMDTable.PRDTEntry.Length - 1].InterruptOnCompletion = 0; - } + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, xCMDHeader.PRDTL); + uint DataBaseAddress = Mem.DataBlock.Base; + xCMDTable.PRDTEntry[0].DBA = DataBaseAddress; + xCMDTable.PRDTEntry[0].DBC = 511; + xCMDTable.PRDTEntry[0].InterruptOnCompletion = 1; + FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) { FISType = (byte)FISType.FIS_Type_RegisterH2D, IsCommand = 1, Command = (byte)aCommand, - Device = 0, + Device = 0 }; - int xSpin = 0; - do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSlot < 1000000); + while ((mPortReg.TFD & 0x88) != 0) ; - mPortReg.CI = 1U << xSlot; + mPortReg.CI = 1U; while (true) { - if ((mPortReg.CI & (1 << xSlot)) == 0) - { - break; - } + if ((mPortReg.CI & (1 << xSlot)) == 0) break; if ((mPortReg.IS & (1 << 30)) != 0) { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!\n"); - Console.ResetColor(); + mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); + PortReset(mPortReg); return; } } - if ((mPortReg.IS & (1 << 30)) != 0) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!\n"); - Console.ResetColor(); - return; - } - - Console.ForegroundColor = ConsoleColor.Green; - Console.Write("\n[Success]: "); - Console.Write("Command has been sent successfully!\n"); - Console.ResetColor(); - - while (mPortReg.CI != 0) ; + //Console.ForegroundColor = ConsoleColor.Green; + //Console.Write("[Success]: "); + //Console.Write("Command has been sent successfully!\n"); + //Console.ResetColor(); return; } - public void SendSATA24Command(ATACommands aCommand, uint aStart, uint aCount) + public void SendSATA28Command(ATACommands aCommand, uint aStart, uint aCount) { - mPortReg.IS = unchecked((uint)-1); + bool isIdentify = false; + if (aStart == 0 && aCount == 0) isIdentify = true; + mPortReg.IS = 0xFFFF; + int xSlot = FindCMDSlot(); if (xSlot == -1) return; - + HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); xCMDHeader.CFL = 5; - xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); + xCMDHeader.PRDTL = 1; xCMDHeader.Write = 0; + + xCMDHeader.CTBA = (uint)((uint)(Base.AHCI + 0xA000) + (0x2000 * mPortNumber) + (0x100 * xSlot)); - xCMDHeader.CTBA = Heap.MemAlloc(256); + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, xCMDHeader.PRDTL); - HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); + uint DataBaseAddress = Mem.DataBlock.Base; - xCMDTable.PRDTEntry = new HBAPRDTEntry[xCMDHeader.PRDTL]; - for (uint i = 0; i < xCMDTable.PRDTEntry.Length; i++) + // Last entry + if (isIdentify) { - xCMDTable.PRDTEntry[i] = new HBAPRDTEntry(xCMDHeader.CTBA + 0x80, i); + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = DataBaseAddress; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = 511; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 1; + } + else + { + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = DataBaseAddress; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = aCount * 512 - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 1; } - uint BaseAddress = Mem.DataBlock.Base; - for (uint i = 0; i < xCMDHeader.PRDTL - 1; i++) + if (isIdentify) { - xCMDTable.PRDTEntry[i].DBA = BaseAddress; - xCMDTable.PRDTEntry[i].DBC = 8191; - xCMDTable.PRDTEntry[i].InterruptOnCompletion = 0; - BaseAddress += 8192; - aCount -= 16; + FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) + { + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)ATACommands.Identify, + Device = 0 + }; } - - xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = BaseAddress - 2; - xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = 512 * aCount - 1; - xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 0; - - FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) + else { - FISType = (byte)FISType.FIS_Type_RegisterH2D, - IsCommand = 1, - Command = (byte)aCommand, + FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) + { + FISType = (byte)FISType.FIS_Type_RegisterH2D, + IsCommand = 1, + Command = (byte)aCommand, - LBA0 = (byte)(aStart), - LBA1 = (byte)(aStart >> 8), - LBA2 = (byte)(aStart >> 16), - Device = (byte)(0x40 | ((aStart >> 24) & 0x0F)), + LBA0 = (byte)((aStart) & 0xFF), + LBA1 = (byte)((aStart >> 8) & 0xFF), + LBA2 = (byte)((aStart >> 16) & 0xFF), + Device = (byte)(0x40 | ((aStart >> 24) & 0x0F)), - CountL = (byte)(aCount & 0xFF) - }; - - int xSpin = 0; - do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSlot < 1000000); - - mPortReg.CI = 1U << xSlot; + CountL = (byte)(aCount & 0xFF) + }; + } + + while ((mPortReg.TFD & 0x88) != 0); + + mPortReg.CI = 1U; while (true) { - if ((mPortReg.CI & (1 << xSlot)) == 0) - { - break; - } + if ((mPortReg.CI & (1 << xSlot)) == 0) break; if ((mPortReg.IS & (1 << 30)) != 0) { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!\n"); - Console.ResetColor(); + mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); + PortReset(mPortReg); return; } } - - if ((mPortReg.IS & (1 << 30)) != 0) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!\n"); - Console.ResetColor(); - return; - } - - Console.ForegroundColor = ConsoleColor.Green; - Console.Write("\n[Success]: "); - Console.Write("Command has been sent successfully!\n"); - Console.ResetColor(); - - while (mPortReg.CI != 0) ; + + //Console.ForegroundColor = ConsoleColor.Green; + //Console.Write("[Success]: "); + //Console.Write("Command has been sent successfully!\n"); + //Console.ResetColor(); return; } public void SendSATA48Command(ATACommands aCommand, ulong aStart, uint aCount) { - mPortReg.IS = unchecked((uint)-1); + mPortReg.IS = 0xFFFF; int xSlot = FindCMDSlot(); if (xSlot == -1) return; HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); xCMDHeader.CFL = 5; - xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); + xCMDHeader.PRDTL = 1; xCMDHeader.Write = 0; - xCMDHeader.CTBA = Heap.MemAlloc(256); + xCMDHeader.CTBA = (uint)((uint)(Base.AHCI + 0xA000) + (0x2000 * mPortNumber) + (0x100 * xSlot)); - HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, xCMDHeader.PRDTL); - xCMDTable.PRDTEntry = new HBAPRDTEntry[xCMDHeader.PRDTL]; - for (uint i = 0; i < xCMDTable.PRDTEntry.Length; i++) - { - xCMDTable.PRDTEntry[i] = new HBAPRDTEntry(xCMDHeader.CTBA + 0x80, i); - } + uint DataBaseAddress = Mem.DataBlock.Base; - uint BaseAddress = Mem.DataBlock.Base; - for (uint i = 0; i < xCMDHeader.PRDTL - 1; i++) - { - xCMDTable.PRDTEntry[i].DBA = BaseAddress; - xCMDTable.PRDTEntry[i].DBC = 8191; - xCMDTable.PRDTEntry[i].InterruptOnCompletion = 0; - BaseAddress += 8192; - aCount -= 16; - } - - xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = BaseAddress - 2; - xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = 512 * aCount - 1; - xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 0; + // Last entry + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = DataBaseAddress; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = (aCount * 512) - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 1; FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) { @@ -264,64 +230,74 @@ namespace Cosmos.HAL.BlockDevice.Ports IsCommand = 1, Command = (byte)aCommand, - LBA0 = (byte)(aStart), - LBA1 = (byte)(aStart >> 8), - LBA2 = (byte)(aStart >> 16), - LBA3 = (byte)(aStart >> 24), - LBA4 = (byte)(aStart >> 32), - LBA5 = (byte)(aStart >> 40), - Device = 0x40, + LBA0 = (byte)((aStart >> 00) & 0xFF), + LBA1 = (byte)((aStart >> 08) & 0xFF), + LBA2 = (byte)((aStart >> 16) & 0xFF), + LBA3 = (byte)((aStart >> 24) & 0xFF), + LBA4 = (byte)((aStart >> 32) & 0xFF), + LBA5 = (byte)((aStart >> 40) & 0xFF), + + Device = 1 << 6, CountL = (byte)(aCount & 0xFF), - CountH = (byte)((aCount >> 8)) + CountH = (byte)((aCount >> 8) & 0xFF) }; + + while ((mPortReg.TFD & 0x88) != 0) ; - int xSpin = 0; - do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSlot < 1000000); - - mPortReg.CI = 1U << xSlot; + mPortReg.CI = 1U; while (true) { - if ((mPortReg.CI & (1 << xSlot)) == 0) - { - break; - } + if ((mPortReg.CI & (1 << xSlot)) == 0) break; if ((mPortReg.IS & (1 << 30)) != 0) { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!\n"); - Console.ResetColor(); + mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); + PortReset(mPortReg); return; } } - if ((mPortReg.IS & (1 << 30)) != 0) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!\n"); - Console.ResetColor(); - return; - } - - Console.ForegroundColor = ConsoleColor.Green; - Console.Write("\n[Success]: "); - Console.Write("Command has been sent successfully!\n"); - Console.ResetColor(); - - while (mPortReg.CI != 0) ; - + //Console.ForegroundColor = ConsoleColor.Green; + //Console.Write("[Success]: "); + //Console.Write("Command has been sent successfully!\n"); + //Console.ResetColor(); return; } - public int FindCMDSlot() + public static void PortReset(PortRegisters aPort) + { + // TODO: Make a connection between AHCI Methods and SATA + + // Semi-StopCMD() + aPort.CMD &= ~(1U << 0); + int i; + for(i = 0; i <= 50; i++) + { + if ((aPort.CMD & (1 << 0)) == 0) break; + AHCI.Wait(10000); + } + if (i == 101) AHCI.HBAReset(); + + aPort.SCTL = 1; + AHCI.Wait(1000); + aPort.SCTL &= ~(1U << 0); + + while ((aPort.SSTS & 0x0F) != 3) ; + + aPort.SERR = 1; + + while ((aPort.SCTL & 0x0F) != 0) ; + } + + private void HBAReset() => AHCI.HBAReset(); + + private int FindCMDSlot() { // If not set in SACT and CI, the slot is free var xSlots = (mPortReg.SACT | mPortReg.CI); - for (int i = 1; i < 32; i++) + for (int i = 0; i < 32; i++) { if ((xSlots & 1) == 0) return i; @@ -329,19 +305,34 @@ namespace Cosmos.HAL.BlockDevice.Ports } Console.ForegroundColor = ConsoleColor.Red; - Console.Write("\n[Error]: "); + Console.Write("[Error]: "); Console.Write("Cannot find a free command slot!\n"); Console.ResetColor(); return -1; } + protected string GetString(UInt16[] aBuffer, int aIndexStart, int aStringLength) + { + // Would be nice to convert to byte[] and use + // new string(ASCIIEncoding.ASCII.GetChars(xBytes)); + // But it requires some code Cosmos doesnt support yet + var xChars = new char[aStringLength]; + for (int i = 0; i < aStringLength / 2; i++) + { + UInt16 xChar = aBuffer[aIndexStart + i]; + xChars[i * 2] = (char)(xChar >> 8); + xChars[i * 2 + 1] = (char)xChar; + } + return new string(xChars); + } + + // BlockDevice Methods public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) { + //CheckDataSize(aData, aBlockCount); + //CheckBlockNo(aBlockNo, aBlockCount); SendSATA48Command(ATACommands.ReadDmaExt, (uint)aBlockNo, (uint)aBlockCount); - System.Threading.Thread.Sleep(500); Mem.DataBlock.Read8(aData); - foreach (byte xData in aData) - mSATADebugger.SendNumber(xData); } public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) From 46e1392d99df3cdba74f7ca5b4f207b9d662848e Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 08:52:46 +0300 Subject: [PATCH 51/85] [AHCI] First working AHCI Controller --- .../Cosmos.HAL2/BlockDevice/Ports/Satapi.cs | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs index af89e4b49..e41d05968 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs @@ -3,10 +3,11 @@ using System.Collections.Generic; using System.Text; using Cosmos.Core.Memory.Old; using Cosmos.HAL.BlockDevice.Registers; +using Cosmos.Core; namespace Cosmos.HAL.BlockDevice.Ports { - public class Satapi : StoragePort + public class SATAPI : StoragePort { public Debug.Kernel.Debugger mSATAPIDebugger = new Debug.Kernel.Debugger("HAL", "SATAPI"); @@ -16,7 +17,7 @@ namespace Cosmos.HAL.BlockDevice.Ports public override string mPortName => "SATAPI"; public override uint mPortNumber => mPortReg.mPortNumber; - public Satapi(PortRegisters aSATAPIPort) + public SATAPI(PortRegisters aSATAPIPort) { // Check if it is really a SATAPI Port! @@ -45,20 +46,34 @@ namespace Cosmos.HAL.BlockDevice.Ports HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot); xCMDHeader.CFL = 5; xCMDHeader.ATAPI = 1; - xCMDHeader.PRDTL = 0; + xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1); xCMDHeader.Write = 0; - xCMDHeader.ClearBusy = 1; - xCMDHeader.CTBA = Heap.MemAlloc(256) + (uint)(256 * xSlot); + xCMDHeader.CTBA = Heap.MemAlloc(128 + ((uint)xCMDHeader.PRDTL) * 16); - HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot); + HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, xCMDHeader.PRDTL); + + uint DataBaseAddress = 0x0046C000; + for (int i = 0; i < xCMDHeader.PRDTL - 1; i++) + { + xCMDTable.PRDTEntry[i].DBA = DataBaseAddress; + xCMDTable.PRDTEntry[i].DBC = 8 * 1024 - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1; + DataBaseAddress += 8 * 1024; // 4K words + aCount -= 16; // 16 sectors + } + + // Last entry + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = DataBaseAddress; + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = aCount * 512 - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 1; FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS) { FISType = (byte)FISType.FIS_Type_RegisterH2D, IsCommand = 1, Command = (byte)ATACommands.Packet, - Device = 0 + Device = 1 << 4 }; byte[] xATAPICMD = new byte[12]; @@ -139,6 +154,12 @@ namespace Cosmos.HAL.BlockDevice.Ports public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) { SendSATAPICommand(ATACommands.Read, (uint)aBlockNo, (uint)aBlockCount); + byte[] xByte = new byte[512]; + new MemoryBlock(0x0046C000, 512).Read8(xByte); + for (int i = 0; i < 512; i++) + { + Console.Write(xByte[i]); + } } public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) From 3a1b260aa9423312c0979d3c6884147ad9c148d5 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 08:58:36 +0300 Subject: [PATCH 52/85] [AHCI] First working AHCI Controller --- .../BlockDevice/Registers/AHCIRegs.cs | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs b/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs index 3c2ff546e..f1e3c89da 100644 --- a/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs +++ b/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs @@ -5,6 +5,10 @@ using Cosmos.Core; namespace Cosmos.HAL.BlockDevice.Registers { + public enum Base : uint + { + AHCI = 0x00400000 + } // Registers public class GenericRegisters { @@ -93,7 +97,7 @@ namespace Cosmos.HAL.BlockDevice.Registers { xAddress = aAddress; mPortNumber = aPortNumber; - xBlock = new MemoryBlock(aAddress, 0x80); + xBlock = new MemoryBlock(aAddress + (0x80 * mPortNumber), 0x80); Active = false; } @@ -215,7 +219,7 @@ namespace Cosmos.HAL.BlockDevice.Registers { xAddress = aAddress; xSlot = aSlot; - xBlock = new MemoryBlock(aAddress + (0x20 * aSlot), 0x20); + xBlock = new MemoryBlock(aAddress + (32 * aSlot), 0x20); xBlock.Fill(0); } @@ -265,8 +269,8 @@ namespace Cosmos.HAL.BlockDevice.Registers } public ushort PRDTL { - get { return (ushort)(xBlock.Words[0x02] & 0xFFFF); } - set { xBlock.Words[0x02] = (ushort)(value); } + get { return xBlock.Words[0x02]; } + set { xBlock.Words[0x02] = value; } } public uint PRDBC @@ -277,8 +281,8 @@ namespace Cosmos.HAL.BlockDevice.Registers public uint CTBA { - get { return xBlock[0x08] >> 7; } - set { xBlock[0x08] = (value << 7); } + get { return xBlock[0x08]; } + set { xBlock[0x08] = value; } } public uint CTBAU @@ -312,13 +316,16 @@ namespace Cosmos.HAL.BlockDevice.Registers { private MemoryBlock xBlock; private uint xAddress; - private uint xSlot; - public HBACommandTable(uint aAddress, uint aSlot) + public HBACommandTable(uint aAddress, uint aPRDTCount) { xAddress = aAddress; - xSlot = aSlot; - xBlock = new MemoryBlock(aAddress + (256 * xSlot), 0x80); + xBlock = new MemoryBlock(aAddress, 0x80); xBlock.Fill(0); + PRDTEntry = new HBAPRDTEntry[aPRDTCount]; + for(uint i = 0; i < aPRDTCount; i++) + { + PRDTEntry[i] = new HBAPRDTEntry(aAddress + 0x80, i); + } } public uint CFIS @@ -354,8 +361,8 @@ namespace Cosmos.HAL.BlockDevice.Registers public uint DBA { - get { return xBlock[0x00] >> 1; } - set { xBlock[0x00] = (uint)(value << 1); } + get { return xBlock[0x00]; } + set { xBlock[0x00] = value; } } public uint DBAU @@ -381,7 +388,7 @@ namespace Cosmos.HAL.BlockDevice.Registers public byte InterruptOnCompletion { get { return (byte)(xBlock.Bytes[0x0F] >> 7); } - set { xBlock.Bytes[0x0F] |= (byte)(value << 7); } + set { xBlock.Bytes[0x0F] = (byte)(value << 7); } } } @@ -406,7 +413,7 @@ namespace Cosmos.HAL.BlockDevice.Registers public byte IsCommand { get { return (byte)((xBlock.Bytes[0x01] >> 7)); } - set { xBlock.Bytes[0x01] |= (byte)(value << 7); } + set { xBlock.Bytes[0x01] = (byte)(value << 7); } } public byte Command { From 1f623d8726dca2a8ea3c1b4ddaded212824bf3aa Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 09:00:39 +0300 Subject: [PATCH 53/85] [AHCI] First working AHCI Controller --- source/Cosmos.HAL2/BlockDevice/IDE.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/IDE.cs b/source/Cosmos.HAL2/BlockDevice/IDE.cs index b5b364d16..caff66e2c 100644 --- a/source/Cosmos.HAL2/BlockDevice/IDE.cs +++ b/source/Cosmos.HAL2/BlockDevice/IDE.cs @@ -9,15 +9,17 @@ namespace Cosmos.HAL.BlockDevice internal static void InitDriver() { - if (xDevice == null) return; - Console.WriteLine("ATA Primary Master"); - Initialize(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); - //Console.WriteLine("ATA Primary Slave"); - //Initialize(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Slave); - Console.WriteLine("ATA Secondary Master"); - Initialize(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); - //Console.WriteLine("ATA Secondary Slave"); - //Initialize(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Slave); + if (xDevice != null) + { + Console.WriteLine("ATA Primary Master"); + Initialize(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); + //Console.WriteLine("ATA Primary Slave"); + //Initialize(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Slave); + Console.WriteLine("ATA Secondary Master"); + Initialize(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); + //Console.WriteLine("ATA Secondary Slave"); + //Initialize(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Slave); + } } private static void Initialize(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) From 52122643f65f3d4de46036c9f28dd1c95e8dd94c Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 09:01:19 +0300 Subject: [PATCH 54/85] [AHCI] First working AHCI Controller --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index cd260aa7f..6fed22c85 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -56,8 +56,7 @@ namespace Cosmos.HAL.BlockDevice internal static void InitDriver() { - if (xDevice == null) return; - AHCI Driver = new AHCI(xDevice); + if (xDevice != null) AHCI Driver = new AHCI(xDevice); } internal override PCIDevice GetDevice() => xDevice; From bacd3f4d379350f3a22bee3fe6297a1045b81896 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 09:51:42 +0300 Subject: [PATCH 55/85] Fix --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 6fed22c85..f3f8d2b8a 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -10,7 +10,7 @@ using Cosmos.Core.Memory.Old; namespace Cosmos.HAL.BlockDevice { - public class AHCI : Drivers.PCIDriver + public class AHCI { internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); internal static PCIDevice xDevice = HAL.PCI.GetDevice(0x001, 0x0006); @@ -59,7 +59,7 @@ namespace Cosmos.HAL.BlockDevice if (xDevice != null) AHCI Driver = new AHCI(xDevice); } - internal override PCIDevice GetDevice() => xDevice; + internal PCIDevice GetDevice() => xDevice; public AHCI(PCIDevice aAHCIDevice) { From 509727750953b6b41a9298f0e1d8fd41c9c4903d Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 18:53:43 +0300 Subject: [PATCH 56/85] [AHCI] First working AHCI Controller --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index c15baabc8..aebc7e656 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -42,7 +42,7 @@ namespace Cosmos.HAL.BlockDevice.Ports return; } - Mem = new Core.MemoryGroup.AHCI(); + Mem = new Core.MemoryGroup.AHCI((uint)RegularSectorSize); mPortReg = aSATAPort; From 155d3b3dae1c9a5bb7a02ca1aaa67b7e9d54378e Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 19:10:26 +0300 Subject: [PATCH 57/85] [AHCI] First working AHCI Controller --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index f3f8d2b8a..71d6c53af 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -56,7 +56,10 @@ namespace Cosmos.HAL.BlockDevice internal static void InitDriver() { - if (xDevice != null) AHCI Driver = new AHCI(xDevice); + if (xDevice != null) + { + AHCI Driver = new AHCI(xDevice); + } } internal PCIDevice GetDevice() => xDevice; From a0530f1eb4ee53d25c90c395680be269c109f181 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 20:36:06 +0300 Subject: [PATCH 58/85] [AHCI] First working AHCI Controller --- source/Cosmos.HAL2/BlockDevice/IDE.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/IDE.cs b/source/Cosmos.HAL2/BlockDevice/IDE.cs index caff66e2c..3c632b1a5 100644 --- a/source/Cosmos.HAL2/BlockDevice/IDE.cs +++ b/source/Cosmos.HAL2/BlockDevice/IDE.cs @@ -26,15 +26,16 @@ namespace Cosmos.HAL.BlockDevice { var xIO = aControllerID == Ata.ControllerIdEnum.Primary ? Core.Global.BaseIOGroups.ATA1 : Core.Global.BaseIOGroups.ATA2; var xATA = new AtaPio(xIO, aControllerID, aBusPosition); - if (xATA.DriveType == AtaPio.SpecLevel.Null) return; - if (xATA.DriveType == AtaPio.SpecLevel.ATA) + if (xATA.DriveType == AtaPio.SpecLevel.Null) + return; + else if (xATA.DriveType == AtaPio.SpecLevel.ATA) { BlockDevice.Devices.Add(xATA); Ata.AtaDebugger.Send("ATA device with speclevel ATA found."); } - else if (xATA.DriveType != (AtaPio.SpecLevel)1) + else if (xATA.DriveType == AtaPio.SpecLevel.ATAPI) { - Ata.AtaDebugger.Send("ATA device with speclevel " + (byte)xATA.DriveType + " found, which is not supported yet!"); + Ata.AtaDebugger.Send("ATA device with speclevel ATAPI found, which is not supported yet!"); } var xMbrData = new byte[512]; xATA.ReadBlock(0UL, 1U, xMbrData); From 49890772b0dcff51bf1499c5f00b5856564af5a4 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 20:44:24 +0300 Subject: [PATCH 59/85] Update Sata.cs --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index aebc7e656..8157b9892 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -304,10 +304,10 @@ namespace Cosmos.HAL.BlockDevice.Ports xSlots >>= 1; } - Console.ForegroundColor = ConsoleColor.Red; - Console.Write("[Error]: "); - Console.Write("Cannot find a free command slot!\n"); - Console.ResetColor(); + //Console.ForegroundColor = ConsoleColor.Red; + //Console.Write("[Error]: "); + //Console.Write("Cannot find a free command slot!\n"); + //Console.ResetColor(); return -1; } From 47205dc1441e64ec2eb7a7d14ffd46d639df8491 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 25 Dec 2017 21:17:34 +0300 Subject: [PATCH 60/85] Nit: blank space --- source/Cosmos.Core/MemoryBlock.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index de4a4bf6f..c2b8b67a8 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -238,6 +238,5 @@ namespace Cosmos.Core (*(UInt32*)(Base + aByteOffset)) = value; } } - } } From 00115ea2d9f221c830648044fd494ef4b884cca4 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Tue, 26 Dec 2017 01:19:54 +0300 Subject: [PATCH 61/85] Final fix; --- source/Cosmos.HAL2/BlockDevice/IDE.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Cosmos.HAL2/BlockDevice/IDE.cs b/source/Cosmos.HAL2/BlockDevice/IDE.cs index 3c632b1a5..a721bbcac 100644 --- a/source/Cosmos.HAL2/BlockDevice/IDE.cs +++ b/source/Cosmos.HAL2/BlockDevice/IDE.cs @@ -36,6 +36,7 @@ namespace Cosmos.HAL.BlockDevice else if (xATA.DriveType == AtaPio.SpecLevel.ATAPI) { Ata.AtaDebugger.Send("ATA device with speclevel ATAPI found, which is not supported yet!"); + return; } var xMbrData = new byte[512]; xATA.ReadBlock(0UL, 1U, xMbrData); From a8b46bdb6dff3285d6aed19020559b502ebebccb Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 28 Dec 2017 22:56:06 +0300 Subject: [PATCH 62/85] Update MemoryBlock.cs --- source/Cosmos.Core/MemoryBlock.cs | 38 ------------------------------- 1 file changed, 38 deletions(-) diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index c2b8b67a8..012ddf36c 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -102,44 +102,6 @@ namespace Cosmos.Core { throw new Exception("TODO"); } - - #region ReadWrite - public unsafe void Read8(Byte[] aBuffer) - { - for (int i = 0; i < aBuffer.Length; i++) - aBuffer[i] = (*(Byte*)(Base + i)); - } - - public unsafe void Write8(Byte[] aBuffer) - { - for (int i = 0; i < aBuffer.Length; i++) - (*(Byte*)(Base + i)) = aBuffer[i]; - } - - public unsafe void Read16(UInt16[] aBuffer) - { - for (int i = 0; i < aBuffer.Length; i++) - aBuffer[i] = (*(UInt16*)(Base + i)); - } - - public unsafe void Write16(UInt16[] aBuffer) - { - for (int i = 0; i < aBuffer.Length; i++) - (*(UInt16*)(Base + i)) = aBuffer[i]; - } - - public unsafe void Read32(UInt32[] aBuffer) - { - for (int i = 0; i < aBuffer.Length; i++) - aBuffer[i] = (*(UInt32*)(Base + i)); - } - - public unsafe void Write32(UInt32[] aBuffer) - { - for (int i = 0; i < aBuffer.Length; i++) - (*(UInt32*)(Base + i)) = aBuffer[i]; - } - #endregion ReadWrite } public class MemoryBlock08 From 9825304b06bb0d9f14ac8197b1fc2123aa0c508e Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 28 Dec 2017 22:56:52 +0300 Subject: [PATCH 63/85] Update MemoryBlock.cs --- source/Cosmos.Core/MemoryBlock.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index 012ddf36c..4b9d95059 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -200,5 +200,6 @@ namespace Cosmos.Core (*(UInt32*)(Base + aByteOffset)) = value; } } + } } From c44a4fedfe3ee87761bad85f748aae386ae8100f Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 28 Dec 2017 22:57:11 +0300 Subject: [PATCH 64/85] Update MemoryBlock.cs --- source/Cosmos.Core/MemoryBlock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index 4b9d95059..c9022e8e8 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -200,6 +200,6 @@ namespace Cosmos.Core (*(UInt32*)(Base + aByteOffset)) = value; } } - + } } From 9bb48ca0c2a5e8f4c4af014a08d7aa4158035155 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 28 Dec 2017 23:42:59 +0300 Subject: [PATCH 65/85] Convert Class, Subclass, ProgIF, Vendor, Device to Enums --- source/Cosmos.HAL2/PCI.cs | 89 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/source/Cosmos.HAL2/PCI.cs b/source/Cosmos.HAL2/PCI.cs index b8a9416c2..88bcd0e75 100644 --- a/source/Cosmos.HAL2/PCI.cs +++ b/source/Cosmos.HAL2/PCI.cs @@ -6,6 +6,70 @@ using Cosmos.Debug.Kernel; namespace Cosmos.HAL { + public enum ClassID + { + PCIDevice_2_0 = 0x00, + MassStorageController = 0x01, + NetworkController = 0x02, + DisplayController = 0x03, + MultimediaDevice = 0x04, + MemoryController = 0x05, + BridgeDevice = 0x06, + SimpleCommController = 0x07, + BaseSystemPreiph = 0x08, + InputDevice = 0x09, + DockingStations = 0x0A, + Proccesors = 0x0B, + SerialBusController = 0x0C, + WirelessController = 0x0D, + InteligentController = 0x0E, + SateliteCommController = 0x0F, + EncryptionController = 0x10, + SignalProcessingController = 0x11, + ProcessingAccelerators = 0x12, + NonEssentialInstsrumentation = 0x13, + Coprocessor = 0x40, + Unclassified = 0xFF + } + + public enum SubclassID + { + // MassStorageController: + SCSIStorageController = 0x00, + IDEInterface = 0x01, + FloppyDiskController = 0x02, + IPIBusController = 0x03, + RAIDController = 0x04, + ATAController = 0x05, + SATAController = 0x06, + SASController = 0x07, + NVMController = 0x08, + UnknownMassStorage = 0x09, + } + + public enum ProgramIF + { + // MassStorageController: + SATA_VendorSpecific = 0x00, + SATA_AHCI = 0x01, + SATA_SerialStorageBus = 0x02, + SAS_SerialStorageBus = 0x01, + NVM_NVMHCI = 0x01, + NVM_NVMExpress = 0x02 + } + + public enum VendorID + { + Intel = 0x8086, + AMD = 0x0438, + VMWare = 0x15AD + } + + public enum DeviceID + { + SVGAIIAdapter = 0x0405 + } + public class PCI { private static List Devices; @@ -61,12 +125,13 @@ namespace Cosmos.HAL CheckBus(xPCIDevice.SecondaryBusNumber); } - public static PCIDevice GetDevice(ushort VendorID, ushort DeviceID) + public static PCIDevice GetDevice(VendorID aVendorID, DeviceID aDeviceID) { for (int i = 0; i < Devices.Count; i++) { var xDevice = Devices[i]; - if (xDevice.VendorID == VendorID && xDevice.DeviceID == DeviceID) + if ((VendorID)xDevice.VendorID == aVendorID && + (DeviceID)xDevice.DeviceID == aDeviceID) { return Devices[i]; } @@ -74,12 +139,28 @@ namespace Cosmos.HAL return null; } - public static PCIDevice GetDeviceClass(ushort Class, ushort SubClass) + public static PCIDevice GetDeviceClass(ClassID Class, SubclassID SubClass) { for (int i = 0; i < Devices.Count; i++) { var xDevice = Devices[i]; - if (xDevice.ClassCode == Class && xDevice.Subclass == SubClass) + if ((ClassID)xDevice.ClassCode == Class && + (SubclassID)xDevice.Subclass == SubClass) + { + return Devices[i]; + } + } + return null; + } + + public static PCIDevice GetDeviceClass(ClassID aClass, SubclassID aSubClass, ProgramIF aProgIF) + { + for (int i = 0; i < Devices.Count; i++) + { + var xDevice = Devices[i]; + if ((ClassID)xDevice.ClassCode == aClass && + (SubclassID)xDevice.Subclass == aSubClass && + (ProgramIF)xDevice.ProgIF == aProgIF) { return Devices[i]; } From cc326d0ce2fefead8b4e4437d81bda3dfc1eb197 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 28 Dec 2017 23:44:05 +0300 Subject: [PATCH 66/85] Update AHCI.cs --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 71d6c53af..68580e37a 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -66,13 +66,12 @@ namespace Cosmos.HAL.BlockDevice public AHCI(PCIDevice aAHCIDevice) { - mAHCIDebugger.Send("Something wrong!"); aAHCIDevice.EnableBusMaster(true); aAHCIDevice.EnableMemory(true); mABAR = aAHCIDevice.BaseAddressBar[5].BaseAddress; mGeneric = new GenericRegisters(aAHCIDevice.BaseAddressBar[5].BaseAddress); - mGeneric.GlobalHostControl |= (1U << 31); + mGeneric.GlobalHostControl |= (1U << 31); // Enable AHCI GetCapabilities(); mPorts.Capacity = (int)NumOfPorts; From c06a9324e3149521bdb0db9ad7f9b64e71c7f9a6 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 28 Dec 2017 23:46:42 +0300 Subject: [PATCH 67/85] Update IDE.cs --- source/Cosmos.HAL2/BlockDevice/IDE.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/IDE.cs b/source/Cosmos.HAL2/BlockDevice/IDE.cs index a721bbcac..87c874314 100644 --- a/source/Cosmos.HAL2/BlockDevice/IDE.cs +++ b/source/Cosmos.HAL2/BlockDevice/IDE.cs @@ -5,7 +5,8 @@ namespace Cosmos.HAL.BlockDevice { public class IDE { - private static PCIDevice xDevice = HAL.PCI.GetDeviceClass(0x01, 0x01); + private static PCIDevice xDevice = HAL.PCI.GetDeviceClass(HAL.ClassID.MassStorageController, + HAL.SubclassID.IDEInterface); internal static void InitDriver() { From a8f6141192028dead657d85763c521de3d8aeb80 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 28 Dec 2017 23:49:05 +0300 Subject: [PATCH 68/85] Update AHCI.cs --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 68580e37a..811e73fe9 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -13,7 +13,9 @@ namespace Cosmos.HAL.BlockDevice public class AHCI { internal static Debugger mAHCIDebugger = new Debugger("HAL", "AHCI"); - internal static PCIDevice xDevice = HAL.PCI.GetDevice(0x001, 0x0006); + internal static PCIDevice xDevice = HAL.PCI.GetDeviceClass(HAL.ClassID.MassStorageController, + HAL.SubclassID.SATAController, + HAL.ProgramIF.SATA_AHCI); private static List mPorts = new List(); private static GenericRegisters mGeneric; From 5c0c65166e04380677beb7d06e739c0e73e2b592 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 29 Dec 2017 00:00:52 +0300 Subject: [PATCH 69/85] Update AHCI.cs --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 811e73fe9..25ef14d97 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -253,19 +253,19 @@ namespace Cosmos.HAL.BlockDevice var xDET = (DeviceDetectionStatus)(aPort.SSTS & 0x0F); var xSignature = aPort.SIG; - // Check if not reading wrong data! + // Check if the port is active! if (xIPM != InterfacePowerManagementStatus.Active) return PortType.Nothing; if (xDET != DeviceDetectionStatus.DeviceDetectedWithPhy) return PortType.Nothing; - switch (xSignature >> 16) + switch ((AHCISignature)xSignature >> 16) { - case 0xEB14: return PortType.SATAPI; - case 0xC33C: return PortType.SEMB; - case 0x9669: return PortType.PM; - case 0xFFFF: return PortType.Nothing; - default: return PortType.SATA; + case AHCISignature.SATA: return PortType.SATA; + case AHCISignature.SATAPI: return PortType.SATAPI; + case AHCISignature.SEMB: return PortType.SEMB; + case AHCISignature.PortMultiplier: return PortType.PM; + case AHCISignature.Null: return PortType.Nothing; } } From be1d4af68a76e95de1e309230ab4b6186c1578bf Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 29 Dec 2017 00:03:24 +0300 Subject: [PATCH 70/85] Update AHCIRegs.cs --- .../BlockDevice/Registers/AHCIRegs.cs | 194 +----------------- 1 file changed, 6 insertions(+), 188 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs b/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs index f1e3c89da..81320b8de 100644 --- a/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs +++ b/source/Cosmos.HAL2/BlockDevice/Registers/AHCIRegs.cs @@ -631,188 +631,6 @@ namespace Cosmos.HAL.BlockDevice.Registers } } - public class FISPIOSetup - { - private static MemoryBlock xBlock; - private static uint xAddress; - private static uint xDataSize; - public static FISPIOSetup GetFIS(uint aAddress) - { - xAddress = aAddress; - xBlock = new MemoryBlock(xAddress + 0x20, 0x14); - return new FISPIOSetup(); - } - - public byte FISType - { - get { return xBlock.Bytes[0x00]; } - set { xBlock.Bytes[0x00] = value; } - } - public byte PortMultiplier - { - get { return (byte)(xBlock.Bytes[0x01] & 0x0F); } - set { xBlock.Bytes[0x01] = value; } - } - public byte Reserved - { - get { return (byte)((xBlock.Bytes[0x01] >> 4) & 1); } - } - public byte DataTransferDir - { - get { return (byte)((xBlock.Bytes[0x01] >> 5) & 1); } - set { xBlock.Bytes[0x01] |= (byte)((value) << 5); } - } - public byte InterruptBit - { - get { return (byte)((xBlock.Bytes[0x01] >> 6) & 1); } - set { xBlock.Bytes[0x01] |= (byte)((value) << 6); } - } - public byte Reserved1 - { - get { return (byte)((xBlock.Bytes[0x01] >> 7) & 1); } - } - - public byte Status - { - get { return xBlock.Bytes[0x02]; } - set { xBlock.Bytes[0x02] = value; } - } - public byte Error - { - get { return xBlock.Bytes[0x03]; } - set { xBlock.Bytes[0x03] = value; } - } - - public byte LBA0 - { - get { return xBlock.Bytes[0x04]; } - set { xBlock.Bytes[0x04] = value; } - } - public byte LBA1 - { - get { return xBlock.Bytes[0x05]; } - set { xBlock.Bytes[0x05] = value; } - } - public byte LBA2 - { - get { return xBlock.Bytes[0x06]; } - set { xBlock.Bytes[0x06] = value; } - } - public byte Device - { - get { return xBlock.Bytes[0x07]; } - set { xBlock.Bytes[0x07] = value; } - } - - public byte LBA3 - { - get { return xBlock.Bytes[0x08]; } - set { xBlock.Bytes[0x08] = value; } - } - public byte LBA4 - { - get { return xBlock.Bytes[0x09]; } - set { xBlock.Bytes[0x09] = value; } - } - public byte LBA5 - { - get { return xBlock.Bytes[0x0A]; } - set { xBlock.Bytes[0x0A] = value; } - } - public byte Reserved2 // FeatureL in other Fis types - { - get { return xBlock.Bytes[0x0B]; } - set { xBlock.Bytes[0x0B] = value; } - } - - public byte CountLow - { - get { return xBlock.Bytes[0x0C]; } - set { xBlock.Bytes[0x0C] = value; } - } - public byte CountHigh - { - get { return xBlock.Bytes[0x0D]; } - set { xBlock.Bytes[0x0D] = value; } - } - public byte Reserved3 // ICC in other Fis types - { - get { return xBlock.Bytes[0x0E]; } - set { xBlock.Bytes[0x0E] = value; } - } - public byte E_Status - { - get { return xBlock.Bytes[0x0F]; } - set { xBlock.Bytes[0x0F] = value; } - } - - public ushort DataCount - { - get { return xBlock.Words[0x10]; } - set { xBlock.Words[0x10] = value; } - } - public byte Reserved4 - { - get { return xBlock.Bytes[0x12]; } - set { xBlock.Bytes[0x12] = value; } - } - public byte Reserved5 - { - get { return xBlock.Bytes[0x13]; } - set { xBlock.Bytes[0x13] = value; } - } - } - - public class FISData - { - private static MemoryBlock xBlock; - private static uint xAddress; - private static uint xDataSize; - public static FISData GetFIS(uint aAddress, uint aDataSize) - { - xAddress = aAddress; - xDataSize = aDataSize; - xBlock = new MemoryBlock(xAddress, 4 + (4 * aDataSize)); - return new FISData(); - } - - public byte FISType - { - get { return xBlock.Bytes[0x00]; } - set { xBlock.Bytes[0x00] = value; } - } - public byte PortMultiplier - { - get { return (byte)((xBlock.Bytes[0x01]) & 0x0F); } - set { xBlock.Bytes[0x01] = value; } - } - public byte Reserved - { - get { return (byte)(((xBlock.Bytes[0x01]) >> 4) & 0x0F); } - } - public byte Reserved1 - { - get { return xBlock.Bytes[0x02]; } - } - public byte Reserved2 - { - get { return xBlock.Bytes[0x03]; } - } - - public uint[] Data - { - get - { - UInt32[] xResult = new UInt32[xDataSize]; - for (int i = 0; i < xResult.Length; i++) - { - xResult[i] = xBlock[(uint)(0x04 * i)]; - } - return xResult; - } - } - } - // Enums public enum PortType { @@ -841,13 +659,13 @@ namespace Cosmos.HAL.BlockDevice.Registers FISRegisterH2D = 40 / sizeof(uint) } - public enum DriveSignature : uint // Drive Signature to identify what drive is plugged to Port X:X + public enum AHCISignature : uint // Drive Signature to identify what drive is plugged to Port X:X { - SATADrive = 0x00000101, - PMDrive = 0x96690101, - SATAPIDrive = 0xEB140101, - SEMBDrive = 0xC33C0101, - NullDrive = 0xFFFFFFFF + SATA = 0x0000, + PortMultiplier = 0x9669, + SATAPI = 0xEB14, + SEMB = 0xC33C, + Nothing = 0xFFFF } public enum InterfacePowerManagementStatus : uint // SATA Status: Interface Power Management Status From b18d72f725e50fd4ccfcc75f0c2274432acc6995 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 29 Dec 2017 00:04:16 +0300 Subject: [PATCH 71/85] Update AHCI.cs --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 25ef14d97..3c3200d6a 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -265,7 +265,7 @@ namespace Cosmos.HAL.BlockDevice case AHCISignature.SATAPI: return PortType.SATAPI; case AHCISignature.SEMB: return PortType.SEMB; case AHCISignature.PortMultiplier: return PortType.PM; - case AHCISignature.Null: return PortType.Nothing; + case AHCISignature.Nothing: return PortType.Nothing; } } From 7815013c631ce296b08aee4f67947f2257ecb2bc Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 29 Dec 2017 00:28:48 +0300 Subject: [PATCH 72/85] Update VMWareSVGAII.cs --- source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs b/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs index 2c90cdf02..00a75ac88 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs @@ -145,7 +145,7 @@ namespace Cosmos.HAL.Drivers.PCI.Video public VMWareSVGAII() { - device = (HAL.PCI.GetDevice(0x15AD, 0x0405)); + device = (HAL.PCI.GetDevice(HAL.VendorID.VMWare, HAL.DeviceID.SVGAIIAdapter)); device.EnableMemory(true); uint basePort = device.BaseAddressBar[0].BaseAddress; IndexPort = new IOPort((ushort)(basePort + (uint)IOPortOffset.Index)); From a2cc139ad340c6eb0a8a8a0ea2d9db1a901a89d3 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 29 Dec 2017 23:36:45 +0300 Subject: [PATCH 73/85] Update AHCI.cs --- source/Cosmos.Core/MemoryGroup/AHCI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.Core/MemoryGroup/AHCI.cs b/source/Cosmos.Core/MemoryGroup/AHCI.cs index 271adcc90..d0638ee51 100644 --- a/source/Cosmos.Core/MemoryGroup/AHCI.cs +++ b/source/Cosmos.Core/MemoryGroup/AHCI.cs @@ -10,7 +10,7 @@ namespace Cosmos.Core.MemoryGroup public AHCI(uint aSectorSize) { - DataBlock = new Core.MemoryBlock(0x0046C000, aSectorSize * 256); + DataBlock = new Core.MemoryBlock(0x0046C000, aSectorSize * 1024); DataBlock.Fill(0); } } From 415104fb7c9469153e734ee1de088ea906e8c2be Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Fri, 29 Dec 2017 23:53:43 +0300 Subject: [PATCH 74/85] Update AHCI.cs --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 3c3200d6a..e83851450 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -259,7 +259,9 @@ namespace Cosmos.HAL.BlockDevice if (xDET != DeviceDetectionStatus.DeviceDetectedWithPhy) return PortType.Nothing; - switch ((AHCISignature)xSignature >> 16) + xSignature >>= 16; + + switch ((AHCISignature)xSignature) { case AHCISignature.SATA: return PortType.SATA; case AHCISignature.SATAPI: return PortType.SATAPI; From 540baed1edb3956cc90b96c81aef8428a62ac337 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sat, 30 Dec 2017 00:47:51 +0300 Subject: [PATCH 75/85] Throw exception on impossibles --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index e83851450..0109d9f12 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -239,8 +239,11 @@ namespace Cosmos.HAL.BlockDevice { mAHCIDebugger.Send("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); } - else if (PortType != PortType.Nothing) + else if (PortType == (PortType)0x7FFF) + { mAHCIDebugger.Send("Unknown drive found with signature: 0x" + xPortReg.SIG);// If Implemented Port value was not zero and non of the above. + throw new Exception("SATA Error: Unknown driver found"); + } } xImplementedPort >>= 1; } @@ -268,6 +271,7 @@ namespace Cosmos.HAL.BlockDevice case AHCISignature.SEMB: return PortType.SEMB; case AHCISignature.PortMultiplier: return PortType.PM; case AHCISignature.Nothing: return PortType.Nothing; + default: return (PortType)0x7FFF; } } From e32cf99a6655e0b6db57181e4583d54183a3d1db Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 02:11:25 +0300 Subject: [PATCH 76/85] Update AHCI.cs --- source/Cosmos.HAL2/BlockDevice/AHCI.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/AHCI.cs b/source/Cosmos.HAL2/BlockDevice/AHCI.cs index 0109d9f12..60eec7057 100644 --- a/source/Cosmos.HAL2/BlockDevice/AHCI.cs +++ b/source/Cosmos.HAL2/BlockDevice/AHCI.cs @@ -239,11 +239,8 @@ namespace Cosmos.HAL.BlockDevice { mAHCIDebugger.Send("Port Multiplier Drive at port " + xPortString + " found, which is not supported yet!"); } - else if (PortType == (PortType)0x7FFF) - { - mAHCIDebugger.Send("Unknown drive found with signature: 0x" + xPortReg.SIG);// If Implemented Port value was not zero and non of the above. - throw new Exception("SATA Error: Unknown driver found"); - } + else if (PortType != PortType.Nothing) + throw new Exception("SATA Error"); } xImplementedPort >>= 1; } @@ -271,7 +268,7 @@ namespace Cosmos.HAL.BlockDevice case AHCISignature.SEMB: return PortType.SEMB; case AHCISignature.PortMultiplier: return PortType.PM; case AHCISignature.Nothing: return PortType.Nothing; - default: return (PortType)0x7FFF; + default: throw new Exception("SATA Error: Unknown drive found at port: " + aPort.mPortNumber);; } } From f6972849d57e0c7b63a820defdcb3df08a2e9c01 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 02:15:38 +0300 Subject: [PATCH 77/85] Update Sata.cs --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 21 ++++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index 8157b9892..ba581a3bc 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -35,11 +35,7 @@ namespace Cosmos.HAL.BlockDevice.Ports // Check if it is really a SATA Port! if (aSATAPort.mPortType != PortType.SATA || (aSATAPort.CMD & (1U << 24)) != 0) { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("[Error]"); - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($" 0:{aSATAPort.mPortNumber} is not a SATA port!\n"); - return; + throw new Exception($" 0:{aSATAPort.mPortNumber} is not a SATA port!\n"); } Mem = new Core.MemoryGroup.AHCI((uint)RegularSectorSize); @@ -102,8 +98,9 @@ namespace Cosmos.HAL.BlockDevice.Ports if ((mPortReg.CI & (1 << xSlot)) == 0) break; if ((mPortReg.IS & (1 << 30)) != 0) { - mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); - PortReset(mPortReg); + throw new Exception("SATA Fatal error: Command aborted"); + //mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); + //PortReset(mPortReg); return; } } @@ -187,8 +184,9 @@ namespace Cosmos.HAL.BlockDevice.Ports if ((mPortReg.CI & (1 << xSlot)) == 0) break; if ((mPortReg.IS & (1 << 30)) != 0) { - mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); - PortReset(mPortReg); + throw new Exception("SATA Fatal error: Command aborted"); + //mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); + //PortReset(mPortReg); return; } } @@ -252,8 +250,9 @@ namespace Cosmos.HAL.BlockDevice.Ports if ((mPortReg.CI & (1 << xSlot)) == 0) break; if ((mPortReg.IS & (1 << 30)) != 0) { - mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); - PortReset(mPortReg); + throw new Exception("SATA Fatal error: Command aborted"); + //mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); + //PortReset(mPortReg); return; } } From a512891c4d8829eaead3fa47602b633c036c77e8 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 02:15:56 +0300 Subject: [PATCH 78/85] Update Sata.cs From 14fa4018060055802ce1dd30cfa985e70771f2f1 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 02:30:06 +0300 Subject: [PATCH 79/85] Update Satapi.cs --- .../Cosmos.HAL2/BlockDevice/Ports/Satapi.cs | 41 +++++-------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs index e41d05968..c922a92d2 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs @@ -91,10 +91,7 @@ namespace Cosmos.HAL.BlockDevice.Ports if (xSpin == 1000000) { - Console.ForegroundColor = ConsoleColor.Red; - Console.Write("\n[Error]: "); - Console.Write("Port timed out!"); - Console.ResetColor(); + mSATAPIDebugger.Send($"Port {mPortNumber} timed out!"); return; }; @@ -102,33 +99,20 @@ namespace Cosmos.HAL.BlockDevice.Ports while(true) { - if((mPortReg.CI & (1 << xSlot)) == 0) - { - break; - } + if((mPortReg.CI & (1 << xSlot)) == 0) break; if ((mPortReg.IS & (1 << 30)) != 0) { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!"); - Console.ResetColor(); + throw new Exception("SATA Fatal error: Command aborted"); + //mSATADebugger.Send("[Fatal]: Fatal error occurred while sending command!"); + //PortReset(mPortReg); return; } } - if ((mPortReg.IS & (1 << 30)) != 0) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Fatal]: "); - Console.Write("Fatal error occurred while sending command!"); - Console.ResetColor(); - return; - } - - Console.ForegroundColor = ConsoleColor.Green; - Console.Write("\n[Success]: "); - Console.Write("Command has been sent successfully!"); - Console.ResetColor(); + //Console.ForegroundColor = ConsoleColor.Green; + //Console.Write("\n[Success]: "); + //Console.Write("Command has been sent successfully!"); + //Console.ResetColor(); return; } @@ -144,10 +128,7 @@ namespace Cosmos.HAL.BlockDevice.Ports return i; xSlots >>= 1; } - Console.ForegroundColor = ConsoleColor.Red; - Console.Write("\n[Error]: "); - Console.Write("Cannot find a free command slot!"); - Console.ResetColor(); + mSATAPIDebugger.Send("SATA Error: Cannot find a free command slot!"); return -1; } @@ -164,7 +145,7 @@ namespace Cosmos.HAL.BlockDevice.Ports public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData) { - + // To be implemented! } } } From 5bbab3345e4177ef983dbbff461e594eca4f531d Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 02:30:34 +0300 Subject: [PATCH 80/85] Update Sata.cs --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index ba581a3bc..5f84acbec 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -89,7 +89,13 @@ namespace Cosmos.HAL.BlockDevice.Ports Device = 0 }; - while ((mPortReg.TFD & 0x88) != 0) ; + while ((mPortReg.TFD & 0x88) != 0 && xSpin < 1000000); + + if (xSpin == 1000000) + { + mSATAPIDebugger.Send($"Port {mPortNumber} timed out!"); + return; + }; mPortReg.CI = 1U; From 75320a79e7e911eb417f115732833b833bcd20ad Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 02:33:12 +0300 Subject: [PATCH 81/85] Update Sata.cs --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 24 +++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index 5f84acbec..2b4c775ef 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -89,7 +89,9 @@ namespace Cosmos.HAL.BlockDevice.Ports Device = 0 }; - while ((mPortReg.TFD & 0x88) != 0 && xSpin < 1000000); + int xSpin = 0; + + while ((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; if (xSpin == 1000000) { @@ -181,7 +183,15 @@ namespace Cosmos.HAL.BlockDevice.Ports }; } - while ((mPortReg.TFD & 0x88) != 0); + int xSpin = 0; + + while ((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; + + if (xSpin == 1000000) + { + mSATAPIDebugger.Send($"Port {mPortNumber} timed out!"); + return; + }; mPortReg.CI = 1U; @@ -247,8 +257,16 @@ namespace Cosmos.HAL.BlockDevice.Ports CountH = (byte)((aCount >> 8) & 0xFF) }; - while ((mPortReg.TFD & 0x88) != 0) ; + int xSpin = 0; + + while ((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; + if (xSpin == 1000000) + { + mSATAPIDebugger.Send($"Port {mPortNumber} timed out!"); + return; + }; + mPortReg.CI = 1U; while (true) From 458e46562690e52d2cd8e7547035fbf7b7b089fc Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 02:35:14 +0300 Subject: [PATCH 82/85] Update Satapi.cs --- source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs index c922a92d2..d811b4cf2 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs @@ -23,11 +23,7 @@ namespace Cosmos.HAL.BlockDevice.Ports // Check if it is really a SATAPI Port! if (aSATAPIPort.mPortType != PortType.SATAPI || (aSATAPIPort.CMD & (1U << 24)) == 0) { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("\n[Error]"); - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($" 0:{aSATAPIPort.mPortNumber} is not a SATAPI port!"); - return; + throw new Exception($"SATAPI Error: 0:{mPortNumber} is not SATAPI port!"); } mSATAPIDebugger.Send("SATAPI Constructor"); From e562c7ed5687ef926ba282914fd16e4ae9667447 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 03:07:40 +0300 Subject: [PATCH 83/85] Update Sata.cs --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index 2b4c775ef..552c5852c 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -91,7 +91,7 @@ namespace Cosmos.HAL.BlockDevice.Ports int xSpin = 0; - while ((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; + while (((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; if (xSpin == 1000000) { @@ -185,7 +185,7 @@ namespace Cosmos.HAL.BlockDevice.Ports int xSpin = 0; - while ((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; + while (((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; if (xSpin == 1000000) { @@ -259,7 +259,7 @@ namespace Cosmos.HAL.BlockDevice.Ports int xSpin = 0; - while ((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; + while (((mPortReg.TFD & 0x88) != 0) && xSpin < 1000000) xSpin++; if (xSpin == 1000000) { From 243e43dd13be00121a13aa8277b6dc59fef8ee17 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 16:01:51 +0300 Subject: [PATCH 84/85] Update Satapi.cs --- source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs index d811b4cf2..40e975b12 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Satapi.cs @@ -4,12 +4,13 @@ using System.Text; using Cosmos.Core.Memory.Old; using Cosmos.HAL.BlockDevice.Registers; using Cosmos.Core; +using Cosmos.Debug.Kernel; namespace Cosmos.HAL.BlockDevice.Ports { public class SATAPI : StoragePort { - public Debug.Kernel.Debugger mSATAPIDebugger = new Debug.Kernel.Debugger("HAL", "SATAPI"); + internal static Debugger mSATAPIDebugger = new Debugger("HAL", "SATAPI"); public PortRegisters mPortReg; From 7cdf493dda2011d1d0f50cfcf481c07e6f66d4ff Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Sun, 31 Dec 2017 16:12:19 +0300 Subject: [PATCH 85/85] Final fix; --- source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs index 552c5852c..927a82b4f 100644 --- a/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs +++ b/source/Cosmos.HAL2/BlockDevice/Ports/Sata.cs @@ -95,7 +95,7 @@ namespace Cosmos.HAL.BlockDevice.Ports if (xSpin == 1000000) { - mSATAPIDebugger.Send($"Port {mPortNumber} timed out!"); + mSATADebugger.Send($"Port {mPortNumber} timed out!"); return; }; @@ -189,7 +189,7 @@ namespace Cosmos.HAL.BlockDevice.Ports if (xSpin == 1000000) { - mSATAPIDebugger.Send($"Port {mPortNumber} timed out!"); + mSATADebugger.Send($"Port {mPortNumber} timed out!"); return; }; @@ -263,7 +263,7 @@ namespace Cosmos.HAL.BlockDevice.Ports if (xSpin == 1000000) { - mSATAPIDebugger.Send($"Port {mPortNumber} timed out!"); + mSATADebugger.Send($"Port {mPortNumber} timed out!"); return; };