mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 22:12:25 +00:00
FPU/MMX/XMM/SSE/SSE2 seems to be usable now
This commit is contained in:
parent
3539a44e0b
commit
ff4af1920f
8 changed files with 32 additions and 616 deletions
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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))]
|
||||
|
|
|
|||
Loading…
Reference in a new issue