mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 05:18:38 +00:00
Fix ata detection bug. CD drives were recognized as ATAPI devices, but still handled as ATA ones. Currently we don't have an ATAPI driver, so the CD drives are ignored.
Fixes #129
This commit is contained in:
parent
9b13be0d02
commit
5fca0ecbb7
5 changed files with 85 additions and 58 deletions
|
|
@ -32,11 +32,11 @@ namespace Cosmos.Debug.VSDebugEngine.Host
|
|||
"floppy_bootsig_check: disabled=0\n" +
|
||||
"# no floppya\n" +
|
||||
"# no floppyb\n" +
|
||||
"ata0-master: type=cdrom, path=\"%CDROMBOOTPATH%\", status=inserted, model=\"Generic 1234\", biosdetect=auto\n" +
|
||||
"ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14\n" +
|
||||
"ata0-master: type=disk, path=\"%HARDDISKPATH%\", mode=vmware4, cylinders=0, heads=0, spt=0, model=\"Generic 1234\", biosdetect=auto, translation=auto\n" +
|
||||
"ata0-slave: type=none\n" +
|
||||
"ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15\n" +
|
||||
"ata1-master: type=cdrom, path=\"%CDROMBOOTPATH%\", status=inserted, model=\"Generic 1234\", biosdetect=auto\n" +
|
||||
"ata1-master: type=disk, path=\"%HARDDISKPATH%\", mode=vmware4, cylinders=0, heads=0, spt=0, model=\"Generic 1234\", biosdetect=auto, translation=auto\n" +
|
||||
"ata2: enabled=0\n" +
|
||||
"ata3: enabled=0\n" +
|
||||
"pci: enabled=1, chipset=i440fx\n" +
|
||||
|
|
@ -85,11 +85,8 @@ namespace Cosmos.Debug.VSDebugEngine.Host
|
|||
|
||||
defaultConfigs.Set("com1", defaultConfigs.Get("com1").Replace("%PIPESERVERNAME%", xParts[1].ToLower()));
|
||||
var xHarddiskFile = Path.Combine(CosmosPaths.Build, @"VMWare\Workstation\Filesystem.vmdk");
|
||||
defaultConfigs.Set("ata0-master", defaultConfigs.Get("ata0-master").Replace("%HARDDISKPATH%", xHarddiskFile));
|
||||
|
||||
defaultConfigs.Set("ata1-master", defaultConfigs.Get("ata1-master").Replace("%CDROMBOOTPATH%", mParams["ISOFile"]));
|
||||
|
||||
|
||||
defaultConfigs.Set("ata0-master", defaultConfigs.Get("ata0-master").Replace("%CDROMBOOTPATH%", mParams["ISOFile"]));
|
||||
defaultConfigs.Set("ata1-master", defaultConfigs.Get("ata1-master").Replace("%HARDDISKPATH%", xHarddiskFile));
|
||||
}
|
||||
|
||||
private void GenerateConfiguration(string filePath)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,8 @@
|
|||
[*.cs]
|
||||
indent_size=4
|
||||
|
||||
[Global.cs]
|
||||
indent_size = 2
|
||||
|
||||
[BlockDevice/Ata.cs]
|
||||
indent_size = 2
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Cosmos.Debug.Kernel;
|
||||
|
||||
namespace Cosmos.HAL.BlockDevice {
|
||||
public abstract class Ata : BlockDevice {
|
||||
public abstract class Ata : BlockDevice
|
||||
{
|
||||
|
||||
internal static Debugger AtaDebugger = new Debugger("HAL", "Ata");
|
||||
|
||||
protected Ata() {
|
||||
mBlockSize = 512;
|
||||
}
|
||||
|
||||
// In future may need to add a None for PCI ATA controllers.
|
||||
// In future may need to add a None for PCI ATA controllers.
|
||||
// Or maybe they all have Primary and Secondary on them as well.
|
||||
public enum ControllerIdEnum { Primary, Secondary }
|
||||
protected ControllerIdEnum mControllerID;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using Cosmos.Common;
|
||||
using Cosmos.Debug.Kernel;
|
||||
|
||||
namespace Cosmos.HAL.BlockDevice
|
||||
{
|
||||
|
|
@ -80,7 +81,7 @@ namespace Cosmos.HAL.BlockDevice
|
|||
//* Bit 6: LBA (0: CHS, 1: LBA).
|
||||
LBA = 0x40,
|
||||
//* Bit 5: Obsolete and isn't used, but should be set.
|
||||
//* Bit 7: Obsolete and isn't used, but should be set.
|
||||
//* Bit 7: Obsolete and isn't used, but should be set.
|
||||
Default = 0xA0
|
||||
};
|
||||
|
||||
|
|
@ -127,6 +128,13 @@ namespace Cosmos.HAL.BlockDevice
|
|||
}
|
||||
#endregion
|
||||
|
||||
internal static Debugger mDebugger = new Debugger("HAL", "AtaPio");
|
||||
|
||||
private static void Debug(string message)
|
||||
{
|
||||
mDebugger.Send("AtaPio debug: " + message);
|
||||
}
|
||||
|
||||
public AtaPio(Core.IOGroup.ATA aIO, Ata.ControllerIdEnum aControllerId, Ata.BusPositionEnum aBusPosition)
|
||||
{
|
||||
IO = aIO;
|
||||
|
|
@ -180,10 +188,10 @@ namespace Cosmos.HAL.BlockDevice
|
|||
}
|
||||
|
||||
// ATA requires a wait of 400 nanoseconds.
|
||||
// Read the Status register FIVE TIMES, and only pay attention to the value
|
||||
// returned by the last one -- after selecting a new master or slave device. The point being that
|
||||
// you can assume an IO port read takes approximately 100ns, so doing the first four creates a 400ns
|
||||
// delay -- which allows the drive time to push the correct voltages onto the bus.
|
||||
// Read the Status register FIVE TIMES, and only pay attention to the value
|
||||
// returned by the last one -- after selecting a new master or slave device. The point being that
|
||||
// you can assume an IO port read takes approximately 100ns, so doing the first four creates a 400ns
|
||||
// delay -- which allows the drive time to push the correct voltages onto the bus.
|
||||
// Since we read status again later, we wait by reading it 4 times.
|
||||
protected void Wait()
|
||||
{
|
||||
|
|
@ -206,7 +214,6 @@ namespace Cosmos.HAL.BlockDevice
|
|||
return SendCmd(aCmd, true);
|
||||
}
|
||||
|
||||
|
||||
public Status SendCmd(Cmd aCmd, bool aThrowOnError)
|
||||
{
|
||||
IO.Command.Byte = (byte)aCmd;
|
||||
|
|
@ -221,6 +228,7 @@ namespace Cosmos.HAL.BlockDevice
|
|||
if (aThrowOnError && (xStatus & Status.Error) != 0)
|
||||
{
|
||||
// TODO: Read error port
|
||||
Debug("ATA Error in SendCmd. Cmd = " + (byte)aCmd + ", Status = " + (byte)xStatus);
|
||||
throw new Exception("ATA Error");
|
||||
}
|
||||
return xStatus;
|
||||
|
|
@ -228,7 +236,7 @@ namespace Cosmos.HAL.BlockDevice
|
|||
|
||||
protected string GetString(UInt16[] aBuffer, int aIndexStart, int aStringLength)
|
||||
{
|
||||
// Would be nice to convert to byte[] and use
|
||||
// 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];
|
||||
|
|
@ -256,13 +264,13 @@ namespace Cosmos.HAL.BlockDevice
|
|||
// Not sure if all this is needed, its different than documented elsewhere but might not be bad
|
||||
// to add code to do all listed here:
|
||||
//
|
||||
//To use the IDENTIFY command, select a target drive by sending 0xA0 for the master drive, or 0xB0 for the slave, to the "drive select" IO port. On the Primary bus, this would be port 0x1F6.
|
||||
// Then set the Sectorcount, LBAlo, LBAmid, and LBAhi IO ports to 0 (port 0x1F2 to 0x1F5).
|
||||
// Then send the IDENTIFY command (0xEC) to the Command IO port (0x1F7).
|
||||
// Then read the Status port (0x1F7) again. If the value read is 0, the drive does not exist. For any other value: poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) clears.
|
||||
// Because of some ATAPI drives that do not follow spec, at this point you need to check the LBAmid and LBAhi ports (0x1F4 and 0x1F5) to see if they are non-zero.
|
||||
//To use the IDENTIFY command, select a target drive by sending 0xA0 for the master drive, or 0xB0 for the slave, to the "drive select" IO port. On the Primary bus, this would be port 0x1F6.
|
||||
// Then set the Sectorcount, LBAlo, LBAmid, and LBAhi IO ports to 0 (port 0x1F2 to 0x1F5).
|
||||
// Then send the IDENTIFY command (0xEC) to the Command IO port (0x1F7).
|
||||
// Then read the Status port (0x1F7) again. If the value read is 0, the drive does not exist. For any other value: poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) clears.
|
||||
// Because of some ATAPI drives that do not follow spec, at this point you need to check the LBAmid and LBAhi ports (0x1F4 and 0x1F5) to see if they are non-zero.
|
||||
// If so, the drive is not ATA, and you should stop polling. Otherwise, continue polling one of the Status ports until bit 3 (DRQ, value = 8) sets, or until bit 0 (ERR, value = 1) sets.
|
||||
// At that point, if ERR is clear, the data is ready to read from the Data port (0x1F0). Read 256 words, and store them.
|
||||
// At that point, if ERR is clear, the data is ready to read from the Data port (0x1F0). Read 256 words, and store them.
|
||||
|
||||
// Read Identification Space of the Device
|
||||
var xBuff = new UInt16[256];
|
||||
|
|
@ -310,7 +318,7 @@ namespace Cosmos.HAL.BlockDevice
|
|||
IO.SectorCount.Byte = (byte)aSectorCount;
|
||||
IO.LBA0.Byte = (byte)(aSectorNo);
|
||||
IO.LBA1.Byte = (byte)(aSectorNo >> 8);
|
||||
IO.LBA2.Byte = (byte)(aSectorNo >> 16);
|
||||
IO.LBA2.Byte = (byte)(aSectorNo >> 16);
|
||||
//IO.LBA0.Byte = (byte)(aSectorNo & 0xFF);
|
||||
//IO.LBA1.Byte = (byte)((aSectorNo & 0xFF00) >> 8);
|
||||
//IO.LBA2.Byte = (byte)((aSectorNo & 0xFF0000) >> 16);
|
||||
|
|
@ -347,4 +355,4 @@ namespace Cosmos.HAL.BlockDevice
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Cosmos.HAL.BlockDevice;
|
||||
|
||||
namespace Cosmos.HAL {
|
||||
static public class Global {
|
||||
|
|
@ -14,46 +15,57 @@ namespace Cosmos.HAL {
|
|||
|
||||
public static PCI Pci;
|
||||
|
||||
static void InitAta(BlockDevice.Ata.ControllerIdEnum aControllerID, BlockDevice.Ata.BusPositionEnum aBusPosition) {
|
||||
private static void InitAta(BlockDevice.Ata.ControllerIdEnum aControllerID, BlockDevice.Ata.BusPositionEnum aBusPosition)
|
||||
{
|
||||
var xIO = aControllerID == BlockDevice.Ata.ControllerIdEnum.Primary ? Cosmos.Core.Global.BaseIOGroups.ATA1 : Cosmos.Core.Global.BaseIOGroups.ATA2;
|
||||
var xATA = new BlockDevice.AtaPio(xIO, aControllerID, aBusPosition);
|
||||
if (xATA.DriveType != BlockDevice.AtaPio.SpecLevel.Null) {
|
||||
if (xATA.DriveType == BlockDevice.AtaPio.SpecLevel.Null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (xATA.DriveType == BlockDevice.AtaPio.SpecLevel.ATA)
|
||||
{
|
||||
BlockDevice.BlockDevice.Devices.Add(xATA);
|
||||
var xMbrData = new byte[512];
|
||||
xATA.ReadBlock(0UL, 1U, xMbrData);
|
||||
var xMBR = new BlockDevice.MBR(xMbrData);
|
||||
}
|
||||
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 BlockDevice.MBR(xMbrData);
|
||||
|
||||
if (xMBR.EBRLocation != 0)
|
||||
{
|
||||
//EBR Detected
|
||||
var xEbrData = new byte[512];
|
||||
xATA.ReadBlock(xMBR.EBRLocation, 1U, xEbrData);
|
||||
var xEBR = new BlockDevice.EBR(xEbrData);
|
||||
if (xMBR.EBRLocation != 0)
|
||||
{
|
||||
//EBR Detected
|
||||
var xEbrData = new byte[512];
|
||||
xATA.ReadBlock(xMBR.EBRLocation, 1U, xEbrData);
|
||||
var xEBR = new BlockDevice.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);
|
||||
}
|
||||
}
|
||||
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
|
||||
Console.WriteLine("Number of MBR partitions found: " + 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 BlockDevice.Partition(xATA, xPart.StartSector, xPart.SectorCount);
|
||||
BlockDevice.BlockDevice.Devices.Add(xPartDevice);
|
||||
Console.WriteLine("Found partition at idx " + i);
|
||||
}
|
||||
}
|
||||
// TODO Change this to foreach when foreach is supported
|
||||
Console.WriteLine("Number of MBR partitions found: " + 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 BlockDevice.Partition(xATA, xPart.StartSector, xPart.SectorCount);
|
||||
BlockDevice.BlockDevice.Devices.Add(xPartDevice);
|
||||
Console.WriteLine("Found partition at idx " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue