FPU/MMX/XMM/SSE/SSE2 seems to be usable now

This commit is contained in:
mterwoord_cp 2008-08-15 15:08:52 +00:00
parent 3539a44e0b
commit ff4af1920f
8 changed files with 32 additions and 616 deletions

View file

@ -3,7 +3,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30428</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{CE50FE98-9AC4-4B4D-ADC7-31F6DCD28755}</ProjectGuid>
<OutputType>Library</OutputType>
@ -109,9 +109,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RTC.cs" />
<Compile Include="Serial.cs" />
<Compile Include="Old\Storage\ATA.cs" />
<Compile Include="Old\Storage\ATAOld.cs" />
<Compile Include="Old\Storage\Storage.cs" />
<Compile Include="DeviceSerial.cs" />
<Compile Include="TextScreen.cs" />
<Compile Include="VGAScreen.cs" />

View file

@ -1,4 +1,5 @@
using System;
#define WRITE_TO_DEBUG
using System;
using System.Collections.Generic;
using System.Text;
@ -251,9 +252,11 @@ namespace Cosmos.Hardware {
}
public static void WriteSerialString(string aData) {
//for (int i = 0; i < aData.Length; i++) {
// Serial.WriteSerial(1, (byte)aData[i]);
//}
#if WRITE_TO_DEBUG
for (int i = 0; i < aData.Length; i++) {
Serial.WriteSerial(1, (byte)aData[i]);
}
#endif
//Console.Write(aData);
}
}

View file

@ -1,172 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Cosmos.Hardware.Old.Storage {
public class ATA: Cosmos.Hardware.Storage.Storage {
private const byte IDE_PORT_DATA = 0x00000000;
private const byte IDE_PORT_ERROR = 0x00000001;
private const byte IDE_PORT_FEATURES = 0x00000001;
private const byte IDE_PORT_SECTORCOUNT = 0x00000002;
private const byte IDE_PORT_SECTORNUMBER = 0x00000003;
private const byte IDE_PORT_LBABITS0TO7 = 0x00000003;
private const byte IDE_PORT_CYLINDERLOW = 0x00000004;
private const byte IDE_PORT_LBABITS8TO15 = 0x00000004;
private const byte IDE_PORT_CYLINDERHIGH = 0x00000005;
private const byte IDE_PORT_LBABITS16TO23 = 0x00000005;
private const byte IDE_PORT_DRIVEHEAD = 0x00000006;
private const byte IDE_PORT_LBABITS24TO27 = 0x00000006;
private const byte IDE_PORT_STATUS = 0x00000007;
private const byte IDE_PORT_COMMAND = 0x00000007;
private const ushort IDE_PORT_ALTERNATESTATUS = 0x3F8;
private const ushort IDE_PORT_DEVICECONTROL = 0x3F8;
private const ushort IDE_PORT_DRIVEADDRESS = 0x3F9;
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 = 5*PIT.TicksPerSecond;
private readonly ushort mControllerAddress;
private readonly byte mController;
private readonly byte mDrive;
private static readonly ushort[] ATAControllerInfo = new ushort[] { 0x1F0, 0x170 };
private static Action<uint> mSleep;
public static void Initialize(Action<uint> aSleep) {
mSleep = aSleep;
}
public ATA(byte aController, byte aDrive) {
mController = aController;
mControllerAddress = ATAControllerInfo[aController];
mDrive = aDrive;
}
public override uint BlockSize {
get {
return 512;
}
}
public override unsafe void ReadBlock(uint aBlock, byte* aBuffer) {
// 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", aBlock, 32);
uint xSleepCount = Timeout;
while (((IOReadByte((ushort)(mControllerAddress + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (((IOReadByte((ushort)(mControllerAddress + IDE_PORT_STATUS)) & (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((ushort)(mControllerAddress + IDE_PORT_DRIVEHEAD), (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((ushort)(mControllerAddress + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (((IOReadByte((ushort)(mControllerAddress + IDE_PORT_STATUS)) & (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((ushort)(mControllerAddress + IDE_PORT_LBABITS0TO7), (byte)aBlock);
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_LBABITS8TO15), (byte)(aBlock >> 8));
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_LBABITS16TO23), (byte)(aBlock >> 16));
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_LBABITS24TO27), (byte)(0xE0 | (mDrive << 4) | ((byte)((aBlock >> 24) & 0x0F))));
// 7) Set the Sector count using the Sector Count register.
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_SECTORCOUNT), 1);
//8) Issue the Read Sector(s) command.
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_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((ushort)(mControllerAddress + IDE_PORT_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(IDE_PORT_DEVICECONTROL, 0); // receive interrupts...
// 11) Read the Alternate Status Register (you may even ignore the value that is read)
IOReadByte(IDE_PORT_ALTERNATESTATUS);
// 12) Read the Status register for the selected IDE Controller.
IOReadByte((ushort)(mControllerAddress + IDE_PORT_STATUS));
//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((ushort)(mControllerAddress + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != IDE_STATUSREG_DRQ) && xSleepCount != 0) {
xSleepCount--;
mSleep(1);
}
if ((IOReadByte((ushort)(mControllerAddress + IDE_PORT_STATUS)) & (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.
ushort* xBuffer = (ushort*)aBuffer;
for (uint i = 0; i < 256; i++) {
ushort xValue = IOReadWord(mControllerAddress);
xBuffer[i] = xValue;
}
// 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(IDE_PORT_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((ushort)(mControllerAddress + IDE_PORT_STATUS));
//DebugUtil.SendATA_BlockReceived(mController, mDrive, (uint)aBlock, (ushort*)aBuffer);
//DebugUtil.ATA_ReadBlock(255, mControllerAddress, mDrive, aBlock);
}
public override void WriteBlock(uint aBlock, byte[] aData) {
uint xSleepCount = Timeout;
while (((IOReadByte((ushort)(mControllerAddress + 0x206)) & 0x80) == 0x80) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (xSleepCount == 0) {
throw new Exception("[ATA|WriteBlockNew] Failed 1");
}
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_FEATURES), 0);
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_SECTORCOUNT), 1);
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_SECTORNUMBER), (byte)aBlock);
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_CYLINDERLOW), (byte)(aBlock >> 8));
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_CYLINDERHIGH), (byte)(aBlock >> 16));
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_DRIVEHEAD), (byte)(0xE0 | (mDrive << 4) | (byte)(aBlock >> 24)));
IOWriteByte(IDE_PORT_DEVICECONTROL, 0); // receive interrupts...
IOWriteByte((ushort)(mControllerAddress + IDE_PORT_COMMAND), 0x30);
xSleepCount = Timeout;
while (((IOReadByte((ushort)(mControllerAddress + IDE_PORT_STATUS)) & 0x80) == 0x80) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (xSleepCount == 0) {
throw new Exception("[ATA|WriteBlockNew] Failed 2");
}
if ((IOReadByte((ushort)(mControllerAddress + 0x206)) & 0x1) != 0) {
throw new Exception("[ATA|WriteBlockNew] Not valid!");
}
xSleepCount = Timeout;
while (((IOReadByte((ushort)(mControllerAddress + 0x206)) & 0x8) == 0x8) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (xSleepCount == 0) {
throw new Exception("[ATA|WriteBlockNew] Failed 3");
}
for (int i = 0; i < 256; i++) {
IOWriteWord(mControllerAddress, (ushort)((aData[i * 2]) | (aData[i * 2 + 1] << 8)));
}
}
}
}

View file

@ -1,401 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Cosmos.Hardware.Storage {
public class ATAOld: Hardware {
private const byte IDE_PORT_DATA = 0x00000000;
private const byte IDE_PORT_ERROR = 0x00000001;
private const byte IDE_PORT_FEATURES = 0x00000001;
private const byte IDE_PORT_SECTORCOUNT = 0x00000002;
private const byte IDE_PORT_SECTORNUMBER = 0x00000003;
private const byte IDE_PORT_LBABITS0TO7 = 0x00000003;
private const byte IDE_PORT_CYLINDERLOW = 0x00000004;
private const byte IDE_PORT_LBABITS8TO15 = 0x00000004;
private const byte IDE_PORT_CYLINDERHIGH = 0x00000005;
private const byte IDE_PORT_LBABITS16TO23 = 0x00000005;
private const byte IDE_PORT_DRIVEHEAD = 0x00000006;
private const byte IDE_PORT_LBABITS24TO27 = 0x00000006;
private const byte IDE_PORT_STATUS = 0x00000007;
private const byte IDE_PORT_COMMAND = 0x00000007;
private const ushort IDE_PORT_ALTERNATESTATUS = 0x3F8;
private const ushort IDE_PORT_DEVICECONTROL = 0x3F8;
private const ushort IDE_PORT_DRIVEADDRESS = 0x3F9;
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 static ushort[] ATAControllerInfo;
private const int Timeout = 25;
public static void WriteNumber(uint aNumber, byte aBits) {
uint xValue = aNumber;
byte xCurrentBits = aBits;
Console.Write("0x");
while (xCurrentBits >= 4) {
xCurrentBits -= 4;
byte xCurrentDigit = (byte)((xValue >> xCurrentBits) & 0xF);
string xDigitString = null;
switch (xCurrentDigit) {
case 0:
xDigitString = "0";
goto default;
case 1:
xDigitString = "1";
goto default;
case 2:
xDigitString = "2";
goto default;
case 3:
xDigitString = "3";
goto default;
case 4:
xDigitString = "4";
goto default;
case 5:
xDigitString = "5";
goto default;
case 6:
xDigitString = "6";
goto default;
case 7:
xDigitString = "7";
goto default;
case 8:
xDigitString = "8";
goto default;
case 9:
xDigitString = "9";
goto default;
case 10:
xDigitString = "A";
goto default;
case 11:
xDigitString = "B";
goto default;
case 12:
xDigitString = "C";
goto default;
case 13:
xDigitString = "D";
goto default;
case 14:
xDigitString = "E";
goto default;
case 15:
xDigitString = "F";
goto default;
default:
Console.Write(xDigitString);
break;
}
}
}
private static Action<uint> mSleep;
public static void HandleInterruptPrimary() {
//DebugUtil.SendMessage("ATA", "Primary Controller Ready");
IOWriteByte((ushort)(ATAControllerInfo[0] + IDE_PORT_ERROR), 0);
PrimaryControllerInterruptOccurred = true;
}
private static bool PrimaryControllerInterruptOccurred;
private static bool SecondaryControllerInterruptOccurred;
public static void HandleInterruptSecondary() {
DebugUtil.SendMessage("ATA", "Secondary Controller Ready");
IOWriteByte((ushort)(ATAControllerInfo[1] + IDE_PORT_ERROR), 0);
SecondaryControllerInterruptOccurred = true;
}
public static void Initialize(Action<uint> aSleep) {
mSleep = aSleep;
ATAControllerInfo = new ushort[] { 0x1F0, 0x170 };
}
public static void PrintControllerInfo() {
string[] xControllerDescriptions = new string[] { "Primary", "Secondary" };
string[] xDrivesDescription = new string[] { "Master", "Slave" };
for (int i = 0; i < ATAControllerInfo.Length; i++) {
ushort xController = ATAControllerInfo[i];
for (byte xDrive = 0; xDrive < 2; xDrive++) {
IOWriteByte(0x1F0 + IDE_PORT_DRIVEHEAD, (byte)(0xA0 | (xDrive << 4)));
mSleep(5);
byte xValue = IOReadByte((ushort)(xController + IDE_PORT_STATUS));
if ((xValue & 0x40) == 0x40) {
Console.Write("[ATA] ");
Console.Write(xControllerDescriptions[i]);
Console.Write(" ");
Console.Write(xDrivesDescription[xDrive]);
Console.Write(" exists (");
WriteNumber(xValue, 8);
Console.WriteLine(")");
}
}
}
}
public static bool WriteBlockNew(byte aController, byte aDrive, uint aBlock, byte[] aData) {
ushort xAddr = ATAControllerInfo[aController];
uint xSleepCount = Timeout;
while (((IOReadByte((ushort)(xAddr + 0x206)) & 0x80) == 0x80) && xSleepCount>0) {
mSleep(1);
xSleepCount--;
}
if(xSleepCount == 0){
Console.WriteLine("[ATA|WriteBlockNew] Failed 1");
return false;
}
IOWriteByte((ushort)(xAddr + IDE_PORT_FEATURES), 0);
IOWriteByte((ushort)(xAddr + IDE_PORT_SECTORCOUNT), 1);
IOWriteByte((ushort)(xAddr + IDE_PORT_SECTORNUMBER), (byte)aBlock);
IOWriteByte((ushort)(xAddr + IDE_PORT_CYLINDERLOW), (byte)(aBlock >> 8));
IOWriteByte((ushort)(xAddr + IDE_PORT_CYLINDERHIGH), (byte)(aBlock >> 16));
IOWriteByte((ushort)(xAddr + IDE_PORT_DRIVEHEAD), (byte)(0xE0 | (aDrive << 4) | (byte)(aBlock >> 24)));
IOWriteByte(IDE_PORT_DEVICECONTROL, 0); // receive interrupts...
IOWriteByte((ushort)(xAddr + IDE_PORT_COMMAND), 0x30);
xSleepCount = Timeout;
while (((IOReadByte((ushort)(xAddr + IDE_PORT_STATUS)) & 0x80) == 0x80) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (xSleepCount == 0) {
Console.WriteLine("[ATA|WriteBlockNew] Failed 2");
return false;
}
if ((IOReadByte((ushort)(xAddr + 0x206)) & 0x1) != 0) {
Console.WriteLine("[ATA|WriteBlockNew] Not valid!");
return false;
}
xSleepCount = Timeout;
while (((IOReadByte((ushort)(xAddr + 0x206)) & 0x8) == 0x8) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (xSleepCount == 0) {
Console.WriteLine("[ATA|WriteBlockNew] Failed 3");
return false;
}
for (int i = 0; i < 256; i++) {
IOWriteWord(xAddr, (ushort)((aData[i * 2]) | (aData[i * 2 + 1] << 8)));
}
return true;
}
public static bool WriteBlock(byte aController, byte aDrive, uint aBlock, byte[] aData) {
if (aData.Length != 512) {
Console.WriteLine("Incorrect buffer size!");
return false;
}
Console.WriteLine("Writing Write command data");
ushort xControllerAddr = ATAControllerInfo[aController];
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_FEATURES), 0);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_SECTORCOUNT), 1);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_SECTORNUMBER), (byte)aBlock);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_CYLINDERLOW), (byte)(aBlock >> 8));
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_CYLINDERHIGH), (byte)(aBlock >> 16));
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_DRIVEHEAD), (byte)(0x20 | (aDrive << 4) | ((byte)((aBlock >> 24) & 0xF))));
IOWriteByte(IDE_PORT_DEVICECONTROL, 0); // receive interrupts...
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_COMMAND), 0x30);
uint xSleepTimes = Timeout;
mSleep(2);
while (((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & 0x8) != 0x8) && xSleepTimes > 0) {
mSleep(1);
xSleepTimes--;
}
if (xSleepTimes == 0) {
byte xStatus = IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS));
Console.Write("Device state: ");
WriteNumber(xStatus, 8);
Console.WriteLine("");
return false;
}
for (int i = 0; i < 256; i++) {
ushort xValue = (ushort)(aData[i * 2] | (aData[i * 2 + 1] << 8));
IOWriteWord(xControllerAddr, xValue);
}
return true;
}
public static bool FlushCaches(byte aController, byte aDrive) {
ushort xControllerAddr = ATAControllerInfo[aController];
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_FEATURES), 0);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_SECTORCOUNT), 0);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_SECTORNUMBER), 0);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_CYLINDERLOW), 0);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_CYLINDERHIGH), 0);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_DRIVEHEAD), (byte)(aDrive << 4));
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_COMMAND), 0xE7);
uint xSleepTimes = 1000;
mSleep(2);
while (((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & 0x20) != 020) && xSleepTimes > 0) {
mSleep(1);
xSleepTimes--;
}
if (xSleepTimes == 0) {
byte xStatus = IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS));
Console.WriteLine("Device State:");
Console.Write(" Status: ");
WriteNumber(xStatus, 8);
Console.WriteLine("");
xStatus = IOReadByte((ushort)(xControllerAddr + IDE_PORT_ERROR));
Console.Write(" Error: ");
WriteNumber(xStatus, 8);
Console.WriteLine("");
xStatus = IOReadByte((ushort)(xControllerAddr + IDE_PORT_SECTORNUMBER));
Console.Write(" Sector Number: ");
WriteNumber(xStatus, 8);
Console.WriteLine("");
xStatus = IOReadByte((ushort)(xControllerAddr + IDE_PORT_CYLINDERLOW));
Console.Write(" Cylinder Low: ");
WriteNumber(xStatus, 8);
Console.WriteLine("");
xStatus = IOReadByte((ushort)(xControllerAddr + IDE_PORT_CYLINDERHIGH));
Console.Write(" Cylinder Low: ");
WriteNumber(xStatus, 8);
Console.WriteLine("");
xStatus = IOReadByte((ushort)(xControllerAddr + IDE_PORT_DRIVEHEAD));
Console.Write(" Device/Head: ");
WriteNumber(xStatus, 8);
Console.WriteLine("");
return false;
}
return true;
}
private static void ResetDevice(ushort aController, byte aDrive) {
IOWriteByte((ushort)(aController + IDE_PORT_DRIVEHEAD), (byte)(aDrive << 4));
byte xError = IOReadByte((ushort)(aController + IDE_PORT_ERROR));
}
public static unsafe bool ReadDataNew(byte aController, byte aDrive, int aBlock, ushort* aBuffer) {
//DebugUtil.SendNumber("ATA", "ReadData, block", (uint)aBlock, 32);
ushort xControllerAddr = ATAControllerInfo[aController];
// 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.
int xSleepCount = 1000;
while (((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
Console.WriteLine("[ATA#2] Read failed");
return false;
}
//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((ushort)(xControllerAddr + IDE_PORT_DRIVEHEAD), (byte)(aDrive << 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 = 1000;
while (((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
mSleep(1);
xSleepCount--;
}
if (((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
Console.WriteLine("[ATA#5] Read failed");
return false;
}
// 6) Write the LBA28 address to the designated IDE registers.
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_LBABITS0TO7), (byte)aBlock);
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_LBABITS8TO15), (byte)(aBlock >> 8));
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_LBABITS16TO23), (byte)(aBlock >> 16));
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_LBABITS24TO27), (byte)(0xE0 | (aDrive << 4) | ((byte)((aBlock >> 24) & 0x0F))));
// 7) Set the Sector count using the Sector Count register.
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_SECTORCOUNT), 1);
//8) Issue the Read Sector(s) command.
IOWriteByte((ushort)(xControllerAddr + IDE_PORT_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((ushort)(xControllerAddr + IDE_PORT_ERROR)) & IDE_ERRORREG_ABRT) == IDE_ERRORREG_ABRT) {
Console.WriteLine("[ATA#9] Read failed");
return false;
}
// 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(IDE_PORT_DEVICECONTROL, 0); // receive interrupts...
// 11) Read the Alternate Status Register (you may even ignore the value that is read)
IOReadByte(IDE_PORT_ALTERNATESTATUS);
// 12) Read the Status register for the selected IDE Controller.
IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS));
//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 = 1000;
while (((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != IDE_STATUSREG_DRQ) && xSleepCount > 0) {
xSleepCount--;
mSleep(1);
}
if ((IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS)) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != IDE_STATUSREG_DRQ) {
Console.WriteLine("[ATA#13] Read failed");
return false;
}
//14) Read one sector from the IDE Controller 16-bits at a time using the IN or the INSW instructions.
for (uint i = 0; i < 256; i++) {
ushort xValue = IOReadWord(xControllerAddr);
aBuffer[i] = xValue;
}
// 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(IDE_PORT_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((ushort)(xControllerAddr + IDE_PORT_STATUS));
//DebugUtil.SendATA_BlockReceived(aController, aDrive, (uint)aBlock, aBuffer);
return true;
}
public static unsafe bool ReadData(byte aController, byte aDrive, uint aBlock, ushort* aBuffer) {
ushort xControllerAddr = ATAControllerInfo[aController];
//Console.WriteLine("[ATA|ReadData] Start");
IOWriteByte((ushort)(xControllerAddr + 1), 0);
IOWriteByte((ushort)(xControllerAddr + 2), 1);
IOWriteByte((ushort)(xControllerAddr + 3), (byte)aBlock);
IOWriteByte((ushort)(xControllerAddr + 4), (byte)(aBlock >> 8));
IOWriteByte((ushort)(xControllerAddr + 5), (byte)(aBlock >> 16));
IOWriteByte((ushort)(xControllerAddr + 6), (byte)(0xE0 | (aDrive << 4) | ((byte)((aBlock >> 24) & 0x0F))));
uint xSleepTimes = 1000;
while (((IOReadByte((ushort)(xControllerAddr + 7)) & 0x80) != 0x80) && (xSleepTimes > 0)) {
mSleep(1);
xSleepTimes--;
}
if ((IOReadByte((ushort)(xControllerAddr + 7)) & 0x80) == 0x80) {
Console.Write("State was ");
WriteNumber(IOReadByte((ushort)(xControllerAddr + 7)), 8);
Console.WriteLine("");
return false;
}
IOWriteByte((ushort)(xControllerAddr + 7), 0x20);
xSleepTimes = 1000;
while (((IOReadByte((ushort)(xControllerAddr + 7)) & 0x80) == 0x80) && (xSleepTimes > 0)) {
mSleep(1);
xSleepTimes--;
}
if ((IOReadByte((ushort)(xControllerAddr + 7)) & 0x80) == 0x80) {
Console.Write("State was ");
WriteNumber(IOReadByte((ushort)(xControllerAddr + 7)), 8);
Console.WriteLine("");
return false;
}
IOReadByte((ushort)(xControllerAddr + IDE_PORT_STATUS));
ReadingDone();
return true;
}
private static void ReadingDone() {
// do nothing
}
}
}

View file

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Cosmos.Hardware.Storage {
public abstract class Storage: Hardware {
public abstract uint BlockSize {
get;
}
public abstract unsafe void ReadBlock(uint aBlock, byte* aBuffer);
public abstract void WriteBlock(uint aBlock, byte[] aData);
}
}

View file

@ -6490,16 +6490,27 @@ namespace Cosmos.Hardware {
/// <param name="rDevices">The list of Devices</param>
private static void EnumerateBus(byte aBus, ref List<PCIDevice> rDevices) {
//Console.WriteLine("Enumerate " + Bus );
DebugUtil.SendNumber("PCI", "Enumerating bus", aBus, 8);
for (byte xSlot = 0; xSlot < 32; xSlot++) {
byte xMaxFunctions = 1;
DebugUtil.SendNumber("PCI",
"Enumerating slot",
xSlot,
8);
for (byte xFunction = 0; xFunction < xMaxFunctions; xFunction++) {
DebugUtil.SendNumber("PCI",
"Enumerating function",
xFunction,
8);
PCIDevice xPCIDevice = new PCIDeviceNormal(aBus, xSlot, xFunction);
DebugUtil.SendMessage("PCI", xPCIDevice.DeviceExists ? "Device exists" : "Device doesnt exist");
if (xPCIDevice.DeviceExists) {
//if (xPCIDevice.HeaderType == 0 /* PCIHeaderType.Normal */)
// xPCIDevice = xPCIDevice;
DebugUtil.SendNumber("PCI",
"HeaderType",
xPCIDevice.HeaderType,
8);
if (xPCIDevice.HeaderType == 2) { /* PCIHeaderType.Cardbus */
xPCIDevice = new PCIDeviceCardBus(aBus, xSlot, xFunction);
}
@ -6511,6 +6522,11 @@ namespace Cosmos.Hardware {
rDevices.Add(xPCIDevice);
if (xPCIDevice is PCIDeviceBridge) {
DebugUtil.SendMessage("PCI", "PCI device is a Bridge");
DebugUtil.SendNumber("PCI",
"SecondaryBus",
((PCIDeviceBridge)xPCIDevice).SecondaryBus,
8);
EnumerateBus(((PCIDeviceBridge)xPCIDevice).SecondaryBus, ref rDevices);
}
@ -6816,9 +6832,9 @@ namespace Cosmos.Hardware {
/// </summary>
public bool DeviceExists { get { return VendorID != 0xFFFF && VendorID != 0x0; } }
/// <summary>
/// Is this a multifunction devie?
/// Is this a multifunction device?
/// </summary>
public bool IsMultiFunction { get { return (Read8(0x0e) & 0xf0) != 0; } }
public bool IsMultiFunction { get { return (Read8(0x0e) & 0x80) != 0; } }
/// <summary>
/// The Vendor ID

View file

@ -110,11 +110,12 @@ namespace Cosmos.Kernel.Plugs.Assemblers {
new CPUx86.Move("eax", "esp"); // preserve old stack address for passing to interrupt handler
new Label(".BeforeAlign");
//new CPUx86.Call("DEBUG_STUB_");
// store floating point data
new CPUx86.And("esp", "0xfffffff0"); // fxsave needs to be 16-byte alligned
new CPUx86.Sub("esp", "512"); // fxsave needs 512 bytes
//new CPUx86.FXSave("[esp]"); // save the registers
new CPUx86.FXSave("[esp]"); // save the registers
new CPUx86.Sub("eax", "4");
new CPUx86.Move("[eax]", "esp");

View file

@ -28,20 +28,6 @@ namespace Cosmos.Kernel.Plugs {
[PlugMethod(MethodAssembler = typeof(Assemblers.ZeroFill))]
// TODO: implement this using REP STOSB and REPO STOSD
public static unsafe void ZeroFill(uint aStartAddress, uint aLength) {
Console.Write("Clearing ");
Cosmos.Hardware.Storage.ATAOld.WriteNumber(aLength, 32);
Console.Write(" bytes at ");
Cosmos.Hardware.Storage.ATAOld.WriteNumber(aStartAddress, 32);
Console.WriteLine("");
uint* xPtr = (uint*)aStartAddress;
for (uint i = 0; i < (aLength / 4); i++) {
xPtr[i] = 0;
if (i % (256 * 1024) == 0) {
Console.Write("Cleared Megabyte ");
Cosmos.Hardware.Storage.ATAOld.WriteNumber(i / (256 * 1024), 16);
Console.WriteLine();
}
}
}
[PlugMethod(MethodAssembler = typeof(Assemblers.GetEndOfStack))]