New working ATA PIO driver
This commit is contained in:
+67
-25
File diff suppressed because it is too large
Load Diff
+40
-27
@@ -30,6 +30,14 @@ implementation
|
||||
uses
|
||||
ide;
|
||||
|
||||
|
||||
procedure outb(port : uint16; value : uint8);
|
||||
begin
|
||||
util.outb(port, value);
|
||||
psleep(1);
|
||||
// get_status(primaryDevices[0]);
|
||||
end;
|
||||
|
||||
{
|
||||
ensure the address is a valid 28 bit address
|
||||
|
||||
@@ -72,7 +80,7 @@ begin
|
||||
console.writestringln('Error identifying device, maybe'); //todo
|
||||
end;
|
||||
|
||||
ready := wait_for_device(device);
|
||||
ready := wait_for_device(device, false);
|
||||
|
||||
if not ready then begin
|
||||
console.writestringln('Device not ready in time!');
|
||||
@@ -123,18 +131,26 @@ begin
|
||||
end;
|
||||
|
||||
select_device(device);
|
||||
psleep(50);
|
||||
no_interrupt(device.isPrimary);
|
||||
|
||||
psleep(50);
|
||||
set_lba_mode(device, lba);
|
||||
psleep(50);
|
||||
|
||||
outb(device.base + ATA_REG_SECCOUNT, count);
|
||||
psleep(50);
|
||||
|
||||
outb(device.base + ATA_REG_LBA0, (lba and $000000FF));
|
||||
psleep(50);
|
||||
outb(device.base + ATA_REG_LBA1, (lba and $0000FF00) shr 8);
|
||||
psleep(50);
|
||||
outb(device.base + ATA_REG_LBA2, (lba and $00FF0000) shr 16);
|
||||
psleep(50);
|
||||
|
||||
outb(device.base + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
|
||||
psleep(50);
|
||||
|
||||
ready := wait_for_device(device);
|
||||
ready := wait_for_device(device, false);
|
||||
|
||||
if not ready then begin
|
||||
console.writestringln('Device not ready in time!');
|
||||
@@ -142,15 +158,11 @@ begin
|
||||
end;
|
||||
|
||||
for i:=0 to count-1 do begin
|
||||
for ii:=0 to 511 do begin //TODO needs to read sector size
|
||||
buffer[i] := inw(device.base + ATA_REG_DATA);
|
||||
|
||||
ready := wait_for_device(device);
|
||||
|
||||
if not ready then begin
|
||||
console.writestringln('Device not ready in time!');
|
||||
BSOD('Device not ready in time!', 'ATA DEVICE NOT READY IN TIME FOR READ');
|
||||
end;
|
||||
ii:=0;
|
||||
while ii < 256 do begin
|
||||
buffer[ii+(i*256)] := inw(device.base + ATA_REG_DATA);
|
||||
ii := ii + 1;
|
||||
psleep(50);
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -175,17 +187,16 @@ begin
|
||||
|
||||
select_device(device);
|
||||
no_interrupt(device.isPrimary); //maybe not?
|
||||
|
||||
set_lba_mode(device, lba);
|
||||
|
||||
|
||||
outb(device.base + ATA_REG_SECCOUNT, count);
|
||||
outb(device.base + ATA_REG_LBA0, (lba and $000000FF));
|
||||
outb(device.base + ATA_REG_LBA1, (lba and $0000FF00) shr 8);
|
||||
outb(device.base + ATA_REG_LBA2, (lba and $00FF0000) shr 16);
|
||||
|
||||
outb(device.base + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
|
||||
|
||||
ready := wait_for_device(device);
|
||||
ready := wait_for_device(device, false);
|
||||
|
||||
if not ready then begin
|
||||
console.writestringln('Device not ready in time!');
|
||||
@@ -193,21 +204,23 @@ begin
|
||||
end;
|
||||
|
||||
for i:=0 to count-1 do begin
|
||||
for ii:=0 to 511 do begin //TODO needs to read sector size
|
||||
outw(device.base + ATA_REG_DATA, uint16(buffer[i]));
|
||||
|
||||
ready := wait_for_device(device);
|
||||
|
||||
if not ready then begin
|
||||
console.writestringln('Device not ready in time!');
|
||||
BSOD('Device not ready in time!', 'ATA DEVICE NOT READY IN TIME FOR WRITE');
|
||||
end;
|
||||
ii:=0;
|
||||
while ii < 256 do begin
|
||||
outw(ATA_PRIMARY_BASE + ATA_REG_DATA, buffer[ii+(i*256)]);
|
||||
ii := ii + 1;
|
||||
psleep(50);
|
||||
end;
|
||||
|
||||
psleep(50); //todo check
|
||||
outb(device.base + ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH);
|
||||
ready := wait_for_device(device, false);
|
||||
|
||||
if not ready then begin
|
||||
console.writestringln('Device not ready in time!');
|
||||
BSOD('Device not ready in time!', 'ATA DEVICE NOT READY IN TIME FOR WRITE');
|
||||
end;
|
||||
end;
|
||||
|
||||
psleep(50); //todo check
|
||||
outb(device.base + ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH);
|
||||
ready := wait_for_device(device);
|
||||
|
||||
// if not ready then begin
|
||||
// console.writestringln('Device not ready in time!');
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
unit atapi;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
util,
|
||||
drivertypes,
|
||||
console,
|
||||
terminal,
|
||||
drivermanagement,
|
||||
vmemorymanager,
|
||||
lmemorymanager,
|
||||
storagemanagement,
|
||||
strings,
|
||||
tracer,
|
||||
drivemanager,
|
||||
storagetypes,
|
||||
idetypes;
|
||||
|
||||
var
|
||||
|
||||
test : uint32;
|
||||
|
||||
function identify_device(var device : TIDE_Device) : Boolean;
|
||||
function read_pio28(device : TIDE_Device; lba : uint32; count : uint8; buffer : puint16) : boolean;
|
||||
function write_pio28(device : TIDE_Device; lba : uint32; count : uint8; buffer : puint16) : boolean;
|
||||
|
||||
|
||||
implementation
|
||||
uses
|
||||
ide;
|
||||
|
||||
{
|
||||
Identify the device on the IDE bus
|
||||
|
||||
@param(device The device to identify)
|
||||
@returns(@True if the device is identified, @False otherwise)
|
||||
}
|
||||
function identify_device(var device : TIDE_Device) : Boolean;
|
||||
var
|
||||
i : uint8;
|
||||
status : TIDE_Status;
|
||||
buffer : TIdentResponse;
|
||||
ready : boolean;
|
||||
begin
|
||||
select_device(device);
|
||||
no_interrupt(device.isPrimary);
|
||||
|
||||
status := get_status(device);
|
||||
|
||||
outb(device.base + ATA_REG_SECCOUNT, 0);
|
||||
outb(device.base + ATA_REG_LBA0, 0);
|
||||
outb(device.base + ATA_REG_LBA1, 0);
|
||||
outb(device.base + ATA_REG_LBA2, 0);
|
||||
|
||||
psleep(1);
|
||||
|
||||
outb(device.base + ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
|
||||
|
||||
status := get_status(device);
|
||||
|
||||
if status.ERROR then begin
|
||||
console.writestringln('Error identifying device, maybe'); //todo
|
||||
end;
|
||||
|
||||
ready := wait_for_device(device, false);
|
||||
|
||||
if not ready then begin
|
||||
console.writestringln('Device not ready in time!');
|
||||
//teapot time
|
||||
// BSOD('Device not ready in time!', 'ATA DEVICE NOT READY IN TIME FOR IDENT');
|
||||
exit(false);
|
||||
end;
|
||||
|
||||
for i:=0 to 255 do begin
|
||||
buffer[i] := inw(device.base + ATA_REG_DATA);
|
||||
end;
|
||||
|
||||
device.info := @buffer;
|
||||
|
||||
identify_device := true;
|
||||
end;
|
||||
|
||||
function read_pio28(device : TIDE_Device; lba : uint32; count : uint8; buffer : puint16) : boolean;
|
||||
var
|
||||
i : uint16;
|
||||
ii : uint16;
|
||||
status : TIDE_Status;
|
||||
ready : boolean;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
function write_pio28(device : TIDE_Device; lba : uint32; count : uint8; buffer : puint16) : boolean;
|
||||
var
|
||||
i : uint16;
|
||||
ii : uint16;
|
||||
status : TIDE_Status;
|
||||
ready : boolean;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -84,7 +84,7 @@ const
|
||||
ATA_REG_LBA3 = $09;
|
||||
ATA_REG_LBA4 = $0A;
|
||||
ATA_REG_LBA5 = $0B;
|
||||
ATA_REG_CONTROL = $0C;
|
||||
ATA_REG_CONTROL = $0C; //1FC on some systems, 3F6 on all
|
||||
ATA_REG_ALTSTATUS = $0C;
|
||||
ATA_REG_DEVADDRESS = $0D;
|
||||
|
||||
@@ -134,6 +134,13 @@ type
|
||||
info : PIdentResponse;
|
||||
end;
|
||||
|
||||
TIDE_PACKET = record
|
||||
command : uint8;
|
||||
lba : uint32;
|
||||
count : uint8;
|
||||
buffer : puint16;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
@@ -335,6 +335,7 @@ begin
|
||||
//serial.sendString('[outb]');
|
||||
//serial.sendHex(port);
|
||||
//serial.sendHex(val);
|
||||
psleep(1);
|
||||
asm
|
||||
PUSH EAX
|
||||
PUSH EDX
|
||||
|
||||
Reference in New Issue
Block a user