New working ATA PIO driver

This commit is contained in:
2025-03-10 20:09:50 +00:00
parent 837d69a44b
commit 920aca5bbf
5 changed files with 220 additions and 53 deletions
File diff suppressed because it is too large Load Diff
+40 -27
View File
@@ -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!');
+104
View File
@@ -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.
+8 -1
View File
@@ -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
+1
View File
@@ -335,6 +335,7 @@ begin
//serial.sendString('[outb]');
//serial.sendHex(port);
//serial.sendHex(val);
psleep(1);
asm
PUSH EAX
PUSH EDX