From e628377ddc7972ab56c0bb7ec843619ee43065ec Mon Sep 17 00:00:00 2001 From: mterwoord_cp <7cd3fd84a0151ea055c2f79e4d2eef9576fe9afesxUZAwxD> Date: Sat, 8 Mar 2008 08:26:25 +0000 Subject: [PATCH] Huge amount of fixes --- source/Boot/KudzuTest/Program.cs | 4 +- source/Boot/KudzuTest/Tests.cs | 26 +- source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs | 5 + source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs | 2 +- source/Cosmos.Hardware.PC/Global.cs | 4 + source/Cosmos.Hardware.PC/Interrupts.cs | 7 +- source/Cosmos/Cosmos.Hardware/BlockDevice.cs | 14 +- .../Cosmos.Hardware/Cosmos.Hardware.csproj | 2 + source/Cosmos/Cosmos.Hardware/Device.cs | 82 ++++-- .../New/Storage/ATA.Constants.cs | 113 +++++++++ .../Cosmos/Cosmos.Hardware/New/Storage/ATA.cs | 234 ++++++++++++++++++ .../Cosmos/Cosmos.Hardware/Old/DebugUtil.cs | 5 +- .../Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj | 3 + .../Commands/DeviceCommand.cs | 73 ++++++ .../Cosmos.Shell.Console.csproj | 1 + source/Cosmos/Cosmos.Shell.Console/Program.cs | 2 +- .../Cosmos/Cosmos.Shell.Console/Prompter.cs | 3 +- source/Indy.IL2CPU.IL.X86/Callvirt.cs | 3 +- source/Indy.IL2CPU.IL.X86/Castclass.cs | 28 +-- source/Indy.IL2CPU.IL.X86/Isinst.cs | 2 +- source/Indy.IL2CPU.IL.X86/Newobj.cs | 51 ++-- source/Indy.IL2CPU.IL.X86/Op.cs | 2 +- .../Indy.IL2CPU.IL/InitVmtImplementationOp.cs | 5 + source/Indy.IL2CPU/Engine.cs | 27 +- 24 files changed, 598 insertions(+), 100 deletions(-) create mode 100644 source/Cosmos/Cosmos.Hardware/New/Storage/ATA.Constants.cs create mode 100644 source/Cosmos/Cosmos.Hardware/New/Storage/ATA.cs create mode 100644 source/Cosmos/Cosmos.Shell.Console/Commands/DeviceCommand.cs diff --git a/source/Boot/KudzuTest/Program.cs b/source/Boot/KudzuTest/Program.cs index 98055142c..4ab7d1a7a 100644 --- a/source/Boot/KudzuTest/Program.cs +++ b/source/Boot/KudzuTest/Program.cs @@ -26,8 +26,8 @@ namespace KudzuTest { - Cosmos.Hardware.PC.Bus.PCIBus.Init(); - Console.ReadLine(); + //Cosmos.Hardware.PC.Bus.PCIBus.Init(); + //Console.ReadLine(); Tests.DoAll(); //Cosmos.Kernel.Temp.Kudzu.PCI.Test(); diff --git a/source/Boot/KudzuTest/Tests.cs b/source/Boot/KudzuTest/Tests.cs index 875355b53..ac79ded01 100644 --- a/source/Boot/KudzuTest/Tests.cs +++ b/source/Boot/KudzuTest/Tests.cs @@ -10,22 +10,22 @@ namespace KudzuTest { public delegate object TestDelegate(); static public void DoAll() { - Tests.Do("String Concatenation", Tests.StringConcat); - Console.WriteLine("String test"); - Console.WriteLine(" " + Tests.StringConcat()); - Console.WriteLine(); + Tests.Do("String Concatenation", Tests.StringConcat); + Console.WriteLine("String test"); + Console.WriteLine(" " + Tests.StringConcat()); + Console.WriteLine(); - Console.WriteLine("StringBuilder test"); - Console.WriteLine(Tests.StringBuilder()); - Console.WriteLine(); + Console.WriteLine("StringBuilder test"); + Console.WriteLine(Tests.StringBuilder()); + Console.WriteLine(); - Console.WriteLine("IntToStr 16 test"); - Console.WriteLine(" " + Tests.IntToStr16()); - Console.WriteLine(); + Console.WriteLine("IntToStr 16 test"); + Console.WriteLine(" " + Tests.IntToStr16()); + Console.WriteLine(); - Console.WriteLine("IntToStr 32 test"); - Console.WriteLine(" " + Tests.IntToStr32()); - Console.WriteLine(); + Console.WriteLine("IntToStr 32 test"); + Console.WriteLine(" " + Tests.IntToStr32()); + Console.WriteLine(); Console.WriteLine("WriteLnUInt32 test"); Console.WriteLine(" " + Tests.WriteLnUInt32()); diff --git a/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs b/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs index c819a0365..58b511339 100644 --- a/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs +++ b/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs @@ -13,5 +13,10 @@ namespace Cosmos.Hardware.PC.Bus.CPU { byte xByte = PC.Bus.CPUBus.Read8(0x60); ByteReceived(xByte); } + public override string Name { + get { + return "Keyboard"; + } + } } } diff --git a/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs b/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs index 988d9d520..ef6b3b5d6 100644 --- a/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs +++ b/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs @@ -5,7 +5,7 @@ using System.Text; namespace Cosmos.Hardware.PC.Bus.CPU { //TODO: Change this to be an instance like other drivers - public class PIC : Cosmos.Hardware.Device { + public abstract class PIC : Cosmos.Hardware.Device { /// /// Remaps the IRQ's to INT20-INT2F /// diff --git a/source/Cosmos.Hardware.PC/Global.cs b/source/Cosmos.Hardware.PC/Global.cs index 51ebc8343..1e205fc4b 100644 --- a/source/Cosmos.Hardware.PC/Global.cs +++ b/source/Cosmos.Hardware.PC/Global.cs @@ -27,6 +27,10 @@ namespace Cosmos.Hardware.PC { HW.CPU.CreateIDT(); // end old ----------------- + // MTW new + HW.New.Storage.ATA.Initialize(Sleep); + // MTW new end + HW.Device.Add(new Bus.CPU.Keyboard()); } diff --git a/source/Cosmos.Hardware.PC/Interrupts.cs b/source/Cosmos.Hardware.PC/Interrupts.cs index 46252d75f..af086c043 100644 --- a/source/Cosmos.Hardware.PC/Interrupts.cs +++ b/source/Cosmos.Hardware.PC/Interrupts.cs @@ -105,7 +105,9 @@ namespace Cosmos.Hardware.PC { //IRQ 14 - Primary IDE. If no Primary IDE this can be changed public static unsafe void HandleInterrupt_2E(InterruptContext* aContext) { - Storage.ATAOld.HandleInterruptPrimary(); + Cosmos.Hardware.DebugUtil.SendMessage("IRQ", "Primary IDE"); + //Storage.ATAOld.HandleInterruptPrimary(); + New.Storage.ATA.HandleInterruptPrimary(); Bus.CPU.PIC.SignalSecondary(); } @@ -120,7 +122,8 @@ namespace Cosmos.Hardware.PC { //IRQ 15 - Secondary IDE public static unsafe void HandleInterrupt_2F(InterruptContext* aContext) { - Storage.ATAOld.HandleInterruptSecondary(); + New.Storage.ATA.HandleInterruptSecondary(); + Cosmos.Hardware.DebugUtil.SendMessage("IRQ", "Secondary IDE"); Bus.CPU.PIC.SignalSecondary(); } diff --git a/source/Cosmos/Cosmos.Hardware/BlockDevice.cs b/source/Cosmos/Cosmos.Hardware/BlockDevice.cs index c25fda325..28b0e03f5 100644 --- a/source/Cosmos/Cosmos.Hardware/BlockDevice.cs +++ b/source/Cosmos/Cosmos.Hardware/BlockDevice.cs @@ -3,6 +3,16 @@ using System.Collections.Generic; using System.Text; namespace Cosmos.Hardware { - public abstract class BlockDevice : Device { - } + public abstract class BlockDevice: Device { + public abstract uint BlockSize { + get; + } + + public abstract ulong BlockCount { + get; + } + + public abstract byte[] ReadBlock(ulong aBlock); + public abstract void WriteBlock(ulong aBlock, byte[] aContents); + } } diff --git a/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj b/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj index 54745461d..327afa292 100644 --- a/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj +++ b/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj @@ -48,6 +48,8 @@ + + diff --git a/source/Cosmos/Cosmos.Hardware/Device.cs b/source/Cosmos/Cosmos.Hardware/Device.cs index 254d490b2..536b175ab 100644 --- a/source/Cosmos/Cosmos.Hardware/Device.cs +++ b/source/Cosmos/Cosmos.Hardware/Device.cs @@ -3,37 +3,65 @@ using System.Collections.Generic; using System.Text; namespace Cosmos.Hardware { - // This is the base class for all hardware devices. Hardware devices - // are defined here as abstracts and overridden in specific implementations - // later - public abstract class Device { - public enum DeviceType { Unknown, Other, Keyboard, Mouse, Storage }; + // This is the base class for all hardware devices. Hardware devices + // are defined here as abstracts and overridden in specific implementations + // later + public abstract class Device:Hardware { + public enum DeviceType { + Unknown, + Other, + Keyboard, + Mouse, + Storage + }; - public Device() { - } + public Device() { + } - static protected List mDevices = new List(); - static public List Devices { - get { return mDevices; } - } + static protected List mDevices = new List(); + static public List Devices { + get { + return mDevices; + } + } - static public void Add(Device aDevice) { + static public void Add(Device aDevice) { + if (aDevice == null) { + throw new ArgumentNullException("aDevice"); + } mDevices.Add(aDevice); - } + } - static public List Find(DeviceType aType) { - var xResult = new List(); - foreach (var xDevice in mDevices) { - if (xDevice.Type == aType) { - xResult.Add(xDevice); - } - } - return xResult; - } + public static Device FindFirst(DeviceType aType) { + for (int i = 0; i < mDevices.Count; i++) { + var xDevice = mDevices[i]; + if (xDevice.Type == aType) { + return xDevice; + } + } + return null; + } - protected DeviceType mType = DeviceType.Unknown; - public DeviceType Type { - get { return mType; } - } - } + static public List Find(DeviceType aType) { + var xResult = new List(); + for (int i = 0; i < mDevices.Count;i++){ + var xDevice = mDevices[i]; + if (xDevice.Type == aType) { + xResult.Add(xDevice); + } + } + return xResult; + } + + protected DeviceType mType = DeviceType.Unknown; + public DeviceType Type { + get { + return mType; + } + } + + public abstract string Name { + get; + } + } } diff --git a/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.Constants.cs b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.Constants.cs new file mode 100644 index 000000000..495965aa5 --- /dev/null +++ b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.Constants.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; + +namespace Cosmos.Hardware.New.Storage { + partial class ATA { + private static ushort[] mControllerAddresses1 = new ushort[] { + 0x1F0, + 0x170 + }; + private static ushort[] mControllerAddresses2 = new ushort[] { + 0x3F0, + 0x370 + }; + private static string[] mControllerNumbers = new string[] { "First", "Second", "Third", "Fourth" }; + private static string[] mControllerChannels = new string[] { "Primary", "Secondary" }; + private static string[] mDriveNames = new string[] { "Master", "Slave" }; + private const byte ATA_DELAY_DEFAULT = 5; + private const byte ATA_DATA = 0; + private const byte ATA_ERROR = 1; + private const byte ATA_SECTORCOUNT = 2; + private const byte ATA_SECTORNUMBER = 3; + private const byte ATA_CYLINDERLOW = 4; + private const byte ATA_CYLINDERHIGH = 5; + private const byte ATA_DRIVEHEAD = 6; + private const byte ATA_STATUS = 7; + private const byte ATA_COMMAND = 8; + + private const byte IDE_STATUSREG_ERR = 0x00000001; + private const byte IDE_STATUSREG_IDX = 0x00000002; + private const byte IDE_STATUSREG_CORR = 0x00000004; + private const byte IDE_STATUSREG_DRQ = 0x00000008; + private const byte IDE_STATUSREG_DSC = 0x00000010; + private const byte IDE_STATUSREG_DWF = 0x00000020; + private const byte IDE_STATUSREG_DRDY = 0x00000040; + private const byte IDE_STATUSREG_BSY = 0x00000080; + private const byte IDE_ERRORREG_ABRT = 0x00000004; + + private const uint Timeout = 60; + + private enum ATA_Commands: byte { + Nop = 0x00, + CfaRequestExtErrCode = 0x03, + DeviceReset = 0x08, + Recalibrate = 0x10, + ReadSectors = 0x20, + ReadSectorsExt = 0x24, + ReadDmaExt = 0x25, + ReadDmaQueuedExt = 0x26, + ReadMultipleExt = 0x29, + WriteSectors = 0x30, + WriteSectorsExt = 0x34, + WriteDmaExt = 0x35, + WriteDmaQueuedExt = 0x36, + CfaWriteSectorsWoErase = 0x38, + WriteMultipleExt = 0x39, + WriteVerify = 0x3C, + ReadVerifySectors = 0x40, + ReadVerifySectorsExt = 0x42, + FormatTrack = 0x50, + Seek = 0x70, + CfaTranslateSector = 0x87, + ExecuteDeviceDiagnostic = 0x90, + InitializeDriveParameters = 0x91, + InitializeDeviceParameters = 0x91, + StandbyImmediate2 = 0x94, + IdleImmediate2 = 0x95, + Standby2 = 0x96, + Idle2 = 0x97, + CheckPowerMode2 = 0x98, + Sleep2 = 0x99, + Packet = 0xA0, + IdentifyDevicePacket = 0xA1, + IdentifyPacketDevice = 0xA1, + Smart = 0xB0, + CfaEraseSectors = 0xC0, + ReadMultiple = 0xC4, + WriteMultiple = 0xC5, + SetMultipleMode = 0xC6, + ReadDmaQueued = 0xC7, + ReadDma = 0xC8, + WriteDma = 0xCA, + WriteDmaQueued = 0xCC, + CfaWriteMultipleWoErase = 0xCD, + StandbyImmediate1 = 0xE0, + IdleImmediate1 = 0xE1, + Standby1 = 0xE2, + Idle1 = 0xE3, + ReadBuffer = 0xE4, + CheckPowerMode1 = 0xE5, + Sleep1 = 0xE6, + FlushCache = 0xE7, + WriteBuffer = 0xE8, + FlushCacheExt = 0xEA, + IdentifyDevice = 0xEC, + SetFeatures = 0xEF, + } + private enum DeviceControlBits: byte { + /// + /// High Order Byte (48-bit LBA) + /// + HighOrderByte = 0x80, + /// + /// Soft reset + /// + CB_DC_SRST = 0x04,// soft reset + /// + /// Disable interrupts + /// + CB_DC_NIEN = 0x02 // disable interrupts + + } + } +} diff --git a/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.cs b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.cs new file mode 100644 index 000000000..bf1d7d646 --- /dev/null +++ b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections.Generic; + +namespace Cosmos.Hardware.New.Storage { + public partial class ATA: BlockDevice { + private static Action mSleep; + private readonly string mName; + private readonly byte mControllerIndex; + private readonly ushort mController; + private readonly ushort mController2; + private readonly ushort mController_Data; + private readonly ushort mController_Error; + private readonly ushort mController_FeatureReg; + private readonly ushort mController_SectorCount; + private readonly ushort mController_SectorNumber; + private readonly ushort mController_CylinderLow; + private readonly ushort mController_CylinderHigh; + private readonly ushort mController_DeviceHead; + private readonly ushort mController_PrimaryStatus; + private readonly ushort mController_Command; + private readonly ushort mController_AlternateStatus; + private readonly ushort mController_DeviceControl; + private readonly ushort mController_DeviceAddress; + private readonly bool mIsPrimary; + /* +#define CB_DATA 0 // data reg in/out pio_base_addr1+0 +#define CB_ERR 1 // error in pio_base_addr1+1 +#define CB_FR 1 // feature reg out pio_base_addr1+1 +#define CB_SC 2 // sector count in/out pio_base_addr1+2 +#define CB_SN 3 // sector number in/out pio_base_addr1+3 +#define CB_CL 4 // cylinder low in/out pio_base_addr1+4 +#define CB_CH 5 // cylinder high in/out pio_base_addr1+5 +#define CB_DH 6 // device head in/out pio_base_addr1+6 +#define CB_STAT 7 // primary status in pio_base_addr1+7 +#define CB_CMD 7 // command out pio_base_addr1+7 +#define CB_ASTAT 8 // alternate status in pio_base_addr2+6 +#define CB_DC 8 // device control out pio_base_addr2+6 +#define CB_DA 9 // device address in pio_base_addr2+7*/ + private readonly byte mDrive; + private ATA(string aName, byte aController, byte aDrive) { + DebugUtil.SendMessage("ATA", aName); + mName = aName; + mControllerIndex = aController; + mController = mControllerAddresses1[aController]; + mController2 = mControllerAddresses2[aController]; + DebugUtil.SendNumber("ATA", "Primary address", mController, 16); + DebugUtil.SendNumber("ATA", "Secondary address", mController2, 16); + mType = DeviceType.Storage; + mDrive = aDrive; + mController_Data = mController; + mIsPrimary = aController == 0; + mController_Error = mController; + //mController_Error += 1; + DebugUtil.SendNumber("ATA", "mController_Error", mController_Error, 16); + mController_FeatureReg = (ushort)(mController + 1); + DebugUtil.SendNumber("ATA", "mController_FeatureReg", mController_FeatureReg, 16); + mController_SectorCount = (ushort)(mController + 2); + DebugUtil.SendNumber("ATA", "mController_SectorCount", mController_SectorCount, 16); + mController_SectorNumber = (ushort)(mController + 3); + DebugUtil.SendNumber("ATA", "mController_SectorNumber", mController_SectorNumber, 16); + mController_CylinderLow = (ushort)(mController + 4); + DebugUtil.SendNumber("ATA", "mController_CylinderLow", mController_CylinderLow, 16); + mController_CylinderHigh = (ushort)(mController + 5); + DebugUtil.SendNumber("ATA", "mController_CylinderHigh", mController_CylinderHigh, 16); + mController_DeviceHead = (ushort)(mController + 6); + DebugUtil.SendNumber("ATA", "mController_DeviceHead", mController_DeviceHead, 16); + mController_PrimaryStatus = (ushort)(mController + 7); + DebugUtil.SendNumber("ATA", "mController_PrimaryStatus", mController_PrimaryStatus, 16); + mController_Command = (ushort)(mController + 7); + DebugUtil.SendNumber("ATA", "mController_Command", mController_Command, 16); + mController_AlternateStatus = (ushort)(mController2 + 8); + DebugUtil.SendNumber("ATA", "mController_AlternateStatus", mController_AlternateStatus, 16); + mController_DeviceControl = (ushort)(mController2 + 8); + DebugUtil.SendNumber("ATA", "mController_DeviceControl", mController_DeviceControl, 16); + mController_DeviceAddress = (ushort)(mController2 + 9); + DebugUtil.SendNumber("ATA", "mController_DeviceAddress", mController_DeviceAddress, 16); + DebugUtil.SendNumber("ATA", "Primary address", mController, 16); + DebugUtil.SendNumber("ATA", "Secondary address", mController2, 16); + IOWriteByte(mController_DeviceControl, 0); + } + + private void Initialize() { + } + + public static void HandleInterruptSecondary() { + mSecondaryInterruptCount++; + IOReadByte((ushort)(mControllerAddresses1[0] + 7)); + } + + private static uint mSecondaryInterruptCount; + + public static void HandleInterruptPrimary() { + mPrimaryInterruptCount++; + IOReadByte((ushort)(mControllerAddresses1[1] + 7)); + } + + private static uint mPrimaryInterruptCount; + + private uint mBlockCount; + + public static void Initialize(Action aSleep) { + if (aSleep == null) { + throw new ArgumentNullException("aSleep"); + } + mSleep = aSleep; + DebugUtil.SendMessage("ATA", "Start Device Detection"); + for (byte xControllerBaseAIdx = 0; xControllerBaseAIdx < mControllerAddresses1.Length; xControllerBaseAIdx++) { + for (byte xDrive = 0; xDrive < 2; xDrive++) { + IOWriteByte((ushort)(mControllerAddresses1[xControllerBaseAIdx] + ATA_DRIVEHEAD), (byte)((xControllerBaseAIdx << 4) | 0xA0 | (xDrive << 4))); + mSleep(1); + if (IOReadByte((ushort)(mControllerAddresses1[xControllerBaseAIdx] + ATA_STATUS)) == 0x50) { + Device.Add(new ATA(String.Concat(mControllerNumbers[xControllerBaseAIdx], " ", mDriveNames[xDrive]), xControllerBaseAIdx, xDrive)); + } + } + } + } + public override uint BlockSize { + get { + return 512; + } + } + + public override ulong BlockCount { + get { + throw new NotImplementedException(); + } + } + /* +#define CB_DATA 0 // data reg in/out pio_base_addr1+0 +#define CB_ERR 1 // error in pio_base_addr1+1 +#define CB_FR 1 // feature reg out pio_base_addr1+1 +#define CB_SC 2 // sector count in/out pio_base_addr1+2 +#define CB_SN 3 // sector number in/out pio_base_addr1+3 +#define CB_CL 4 // cylinder low in/out pio_base_addr1+4 +#define CB_CH 5 // cylinder high in/out pio_base_addr1+5 +#define CB_DH 6 // device head in/out pio_base_addr1+6 +#define CB_STAT 7 // primary status in pio_base_addr1+7 +#define CB_CMD 7 // command out pio_base_addr1+7 +#define CB_ASTAT 8 // alternate status in pio_base_addr2+6 +#define CB_DC 8 // device control out pio_base_addr2+6 +#define CB_DA 9 // device address in pio_base_addr2+7*/ + public override byte[] ReadBlock(ulong aBlock) { + // 1) Read the status register of the primary or the secondary IDE controller. + // 2) The BSY and DRQ bits must be zero if the controller is ready. + DebugUtil.SendNumber("ATA", "ReadBlock", (ushort)aBlock, 32); + uint xSleepCount = Timeout; + while (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) { + mSleep(1); + xSleepCount--; + } + if (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) { + throw new Exception("[ATA#2] Read failed"); + } + //3) Set the DEV bit to 0 for Drive0 and to 1 for Drive1 on the selected IDE controller using + // the Device/Head register and wait for approximately 400 nanoseconds using some NOP perhaps. + IOWriteByte(mController_DeviceHead, (byte)(mDrive << 4)); + //4) Read the status register again. + //5) The BSY and DRQ bits must be 0 again for you to know that the IDE controller and the selected IDE drive are ready. + xSleepCount = Timeout; + while (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) { + mSleep(1); + xSleepCount--; + } + if (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) { + throw new Exception("[ATA#5] Read failed"); + } + // 6) Write the LBA28 address to the designated IDE registers. + IOWriteByte(mController_SectorNumber, (byte)aBlock); + IOWriteByte(mController_CylinderLow, (byte)(aBlock >> 8)); + IOWriteByte(mController_CylinderHigh, (byte)(aBlock >> 16)); + IOWriteByte(mController_DeviceHead, (byte)(0xE0 | (mDrive << 4) | ((byte)((aBlock >> 24) & 0x0F)))); + // 7) Set the Sector count using the Sector Count register. + IOWriteByte(mController_SectorCount, 1); + //8) Issue the Read Sector(s) command. + IOWriteByte(mController_Command, 0x20); + // 9) Read the Error register. If the ABRT bit is set then the Read Sector(s) command + // is not supported for that IDE drive. If the ABRT bit is not set, continue to the next step. + if ((IOReadByte(mController_Error) & IDE_ERRORREG_ABRT) == IDE_ERRORREG_ABRT) { + throw new Exception("[ATA#9] Read failed"); + } + // 10) If you want to receive interrupts after reading each sector, clear the nIEN bit in the + // Device Control register. If you do not clear this bit then interrupts will not be generated + // after the reading of each sector which might cause an infinite loop if you are waiting for them. + // The Primary IDE Controller will generate IRQ14 and the secondary IDE controller generates IRQ 15. + IOWriteByte(mController_DeviceControl, 0); // receive interrupts... + // 11) Read the Alternate Status Register (you may even ignore the value that is read) + IOReadByte(mController_AlternateStatus); + // 12) Read the Status register for the selected IDE Controller. + IOReadByte(mController_Command); + //13) Whenever a sector of data is ready to be read from the Data Register, the BSY bit + // in the status register will be set to 0 and DRQ to 1 so you might want to wait until + // those bits are set to the mentioned values before attempting to read from the drive. + xSleepCount = Timeout; + while (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != IDE_STATUSREG_DRQ) && xSleepCount != 0) { + xSleepCount--; + mSleep(1); + } + if ((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != IDE_STATUSREG_DRQ) { + throw new Exception("[ATA#13] Read failed"); + } + //14) Read one sector from the IDE Controller 16-bits at a time using the IN or the INSW instructions. + byte[] xResult = new byte[512]; + for (uint i = 0; i < 256; i++) { + ushort xValue = IOReadWord(mController); + if (xValue > 0) { + Console.Write("Block "); + Console.Write(aBlock.ToString()); + Console.WriteLine(" Contains nonzero information!"); + } + xResult[i * 2] = (byte)xValue; + xResult[(i * 2) + 1] = (byte)(xValue >> 8); + } + // 15) See if you have to read one more sector. If yes, repeat from step 11 again. + //16) If you don't need to read any more sectors, read the Alternate Status Register and ignore the byte that you read. + IOReadByte(mController_AlternateStatus); + //17) Read the status register. When the status register is read, the IDE Controller will negate + // the INTRQ and you will not have pending IRQs waiting to be detected. This is a MUST to read + // the status register when you are done reading from IDE ports. + IOReadByte(mController_Command); + DebugUtil.SendATA_BlockReceived(mControllerIndex, mDrive, (uint)aBlock, xResult); + return xResult; + } + + public override void WriteBlock(ulong aBlock, byte[] aContents) { + throw new NotImplementedException(); + } + + public override string Name { + get { + return mName; + } + } + } +} diff --git a/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs b/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs index 0033fb759..96995fef1 100644 --- a/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs +++ b/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs @@ -36,9 +36,8 @@ namespace Cosmos.Hardware { EndLogging(); } - public static unsafe void SendATA_BlockReceived(byte aController, byte aDrive, uint aBlock, ushort* aValue) { + public static unsafe void SendATA_BlockReceived(byte aController, byte aDrive, uint aBlock, byte[] aValue) { StartLogging(); - byte* xValueBytes = (byte*)aValue; for (int i = 0; i < 4; i++) { WriteSerialString("\r\n"); } diff --git a/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj b/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj index fa08d7d51..4c7bb8a5a 100644 --- a/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj +++ b/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj @@ -90,6 +90,9 @@ + + +