Unfinished changes for PIO IDE read/write.
This commit is contained in:
parent
cea53c24fe
commit
65fb17870e
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user