Unfinished changes for PIO IDE read/write.

This commit is contained in:
Ali Mashtizadeh 2014-07-11 00:04:55 -07:00
parent cea53c24fe
commit 65fb17870e

View File

@ -38,7 +38,9 @@
// IDE Commands
#define IDE_CMD_READ
#define IDE_CMD_READ_EXT 0x24
#define IDE_CMD_WRITE
#define IDE_CMD_WRITE_EXT 0x34
#define IDE_CMD_IDENTIFY 0xEC
// Status
@ -51,12 +53,22 @@
#define IDE_CONTROL_SRST 0x04 /* Software Reset */
#define IDE_SECTOR_SIZE 512
typedef struct IDE
{
uint16_t base; // Base Port
uint16_t devctl; // Device Control
} IDE;
typedef struct IDEDrive
{
IDE *ide; // IDE Controller
int drive; // Drive Number
bool lba48; // Supports 48-bit LBA
uint64_t size; // Size of Disk
} IDEDrive;
bool IDE_HasController(IDE *ide);
void IDE_Reset(IDE *ide);
void IDE_Identify(IDE *ide, int drive);
@ -193,3 +205,94 @@ IDE_Identify(IDE *ide, int drive)
drive, ident.lbaSectors, ident.lbaSectors / 2048ULL);
}
void
IDE_Read(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
{
uint8_t driveCode;
uint8_t status;
IDE *ide = drive->ide;
ASSERT(drive->drive == 0 || drive->drive == 1);
if (drive->drive == 0)
driveCode = IDE_DRIVE_MASTER;
else
driveCode = IDE_DRIVE_SLAVE;
ASSERT(len < 0x10000);
outb(ide->base + IDE_DRIVE, driveCode);
outb(ide->base + IDE_SECTORCOUNT, len >> 8);
outb(ide->base + IDE_LBALOW, off >> 24);
outb(ide->base + IDE_LBAMID, off >> 32);
outb(ide->base + IDE_LBAHIGH, off >> 40);
outb(ide->base + IDE_SECTORCOUNT, len);
outb(ide->base + IDE_LBALOW, off);
outb(ide->base + IDE_LBAMID, off >> 8);
outb(ide->base + IDE_LBAHIGH, off >> 16);
outb(ide->base + IDE_COMMAND, IDE_CMD_READ_EXT);
// XXX: Need timeout
while (1) {
status = inb(ide->base + IDE_STATUS);
if ((status & IDE_STATUS_BSY) == 0)
break;
}
if ((status & IDE_STATUS_ERR) != 0) {
kprintf("IDE: Error trying read from drive %d\n", drive);
return;
}
int sectors;
for (sectors = 0; sectors < len; sectors++)
{
uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
insw(ide->base, b, 256);
}
}
void
IDE_Write(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
{
uint8_t driveCode;
uint8_t status;
IDE *ide = drive->ide;
ASSERT(drive->drive == 0 || drive->drive == 1);
if (drive->drive == 0)
driveCode = IDE_DRIVE_MASTER;
else
driveCode = IDE_DRIVE_SLAVE;
ASSERT(len < 0x10000);
outb(ide->base + IDE_DRIVE, driveCode);
outb(ide->base + IDE_SECTORCOUNT, len >> 8);
outb(ide->base + IDE_LBALOW, off >> 24);
outb(ide->base + IDE_LBAMID, off >> 32);
outb(ide->base + IDE_LBAHIGH, off >> 40);
outb(ide->base + IDE_SECTORCOUNT, len);
outb(ide->base + IDE_LBALOW, off);
outb(ide->base + IDE_LBAMID, off >> 8);
outb(ide->base + IDE_LBAHIGH, off >> 16);
outb(ide->base + IDE_COMMAND, IDE_CMD_WRITE_EXT);
// XXX: Need timeout
while (1) {
status = inb(ide->base + IDE_STATUS);
if ((status & IDE_STATUS_BSY) == 0)
break;
}
if ((status & IDE_STATUS_ERR) != 0) {
kprintf("IDE: Error trying write from drive %d\n", drive);
return;
}
// XXX: Loop on outw(ide->base, b + sectorOffset);
// XXX: CACHE FLUSH
}