M storage/IDE.pas
M storage/fat32.pas M storage/storagemanagement.pas git-svn-id: https://spexeah.com:8443/svn/Asuro@970 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
parent
6c931149f3
commit
86013b1125
@ -20,11 +20,13 @@ uses
|
|||||||
vmemorymanager,
|
vmemorymanager,
|
||||||
lmemorymanager,
|
lmemorymanager,
|
||||||
storagemanagement,
|
storagemanagement,
|
||||||
|
strings,
|
||||||
tracer;
|
tracer;
|
||||||
|
|
||||||
type
|
type
|
||||||
TIdentResponse = array[0..255] of uint16;
|
TPortMode = (P_READ, P_WRITE);
|
||||||
|
|
||||||
|
TIdentResponse = array[0..255] of uint16;
|
||||||
|
|
||||||
TIDE_Channel_Registers = record
|
TIDE_Channel_Registers = record
|
||||||
base : uint16;
|
base : uint16;
|
||||||
@ -105,7 +107,7 @@ const
|
|||||||
ATA_REG_DATA = $00;
|
ATA_REG_DATA = $00;
|
||||||
ATA_REG_ERROR = $01;
|
ATA_REG_ERROR = $01;
|
||||||
ATA_REG_FEATURES = $01;
|
ATA_REG_FEATURES = $01;
|
||||||
ATA_REG_SECCOUNT0 = $02;
|
ATA_REG_SECCOUNT = $02;
|
||||||
ATA_REG_LBA0 = $03;
|
ATA_REG_LBA0 = $03;
|
||||||
ATA_REG_LBA1 = $04;
|
ATA_REG_LBA1 = $04;
|
||||||
ATA_REG_LBA2 = $05;
|
ATA_REG_LBA2 = $05;
|
||||||
@ -120,6 +122,11 @@ const
|
|||||||
ATA_REG_ALTSTATUS = $0C;
|
ATA_REG_ALTSTATUS = $0C;
|
||||||
ATA_REG_DEVADDRESS = $0D;
|
ATA_REG_DEVADDRESS = $0D;
|
||||||
|
|
||||||
|
ATA_DEVICE_MASTER = $A0;
|
||||||
|
ATA_DEVICE_SLAVE = $B0;
|
||||||
|
|
||||||
|
ATA_PRIMARY_BASE = $1F0;
|
||||||
|
|
||||||
var
|
var
|
||||||
controller : PPCI_Device;
|
controller : PPCI_Device;
|
||||||
|
|
||||||
@ -133,70 +140,106 @@ var
|
|||||||
|
|
||||||
procedure init();
|
procedure init();
|
||||||
function load(ptr : void) : boolean;
|
function load(ptr : void) : boolean;
|
||||||
function identify_device(bus : uint8; drive : uint8) : TIdentResponse;
|
function identify_device(bus : uint8; device : uint8) : TIdentResponse;
|
||||||
procedure readPIO28(drive : uint8; LBA : uint32; sectorCount : uint8; buffer : puint32);
|
|
||||||
procedure writePIO28(drive : uint8; LBA : uint32; sectorCount : uint8; buffer : Puint32);
|
// procedure flush();
|
||||||
|
procedure readPIO28(drive : uint8; LBA : uint32; buffer : puint8);
|
||||||
|
procedure writePIO28(drive : uint8; LBA : uint32; buffer : puint8);
|
||||||
//read/write must be capable of reading/writting any amknt of data upto disk size
|
//read/write must be capable of reading/writting any amknt of data upto disk size
|
||||||
|
|
||||||
procedure read(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32);
|
procedure read(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : puint32);
|
||||||
procedure write(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32);
|
procedure write(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : puint32);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure test_command(params : PParamList);
|
function port_read(register : uint8) : uint8;
|
||||||
var
|
|
||||||
secotrs : uint32;
|
|
||||||
cpacityMB : uint32;
|
|
||||||
buffer : puint32;
|
|
||||||
i : uint32;
|
|
||||||
d : uint8;
|
|
||||||
begin
|
begin
|
||||||
|
port_read:= inb(ATA_PRIMARY_BASE + register);
|
||||||
|
end;
|
||||||
|
|
||||||
for d:= 0 to 1 do begin
|
procedure port_write(register : uint8; data : uint8);
|
||||||
secotrs := IDEDevices[d].info[60];
|
var
|
||||||
secotrs := secotrs or (IDEDevices[d].info[61] shl 16);
|
i : uint8;
|
||||||
|
begin
|
||||||
cpacityMB := (secotrs * 512) DIV 1000 DIV 1000;
|
outb(ATA_PRIMARY_BASE + register, data);
|
||||||
|
util.psleep(1);
|
||||||
if d = 0 then console.writestring('HHD_Primary_MASTER -');
|
if register = ATA_REG_COMMAND then begin
|
||||||
if d = 1 then console.writestring('HHD_Primary_SLAVE -');
|
for i:= 0 to 5 do begin
|
||||||
|
port_read(ATA_REG_STATUS);
|
||||||
console.writestring(' Capacity: ');
|
|
||||||
console.writeint(cpacityMB);
|
|
||||||
console.writestringln('MB');
|
|
||||||
|
|
||||||
buffer := puint32(kalloc(1024 * 2000));
|
|
||||||
//buffer^:= secotrs;
|
|
||||||
|
|
||||||
for i:=0 to 20 do begin
|
|
||||||
puint32(buffer + (i div 2))^:= $10010110;
|
|
||||||
end;
|
|
||||||
|
|
||||||
writePIO28(d, 2, 2, buffer);
|
|
||||||
//buffer^:= $FFFF;
|
|
||||||
for i:=0 to 20 do begin
|
|
||||||
puint32(buffer + (i div 2))^:= $FFFFFFFF;
|
|
||||||
end;
|
|
||||||
|
|
||||||
readPIO28(d, 2, 2, buffer);
|
|
||||||
|
|
||||||
for i:=0 to 20 do begin
|
|
||||||
if puint32(buffer + (i div 2))^ <> $10010110 then begin
|
|
||||||
console.writestringln('Tests failed!');
|
|
||||||
exit;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
// if uint32(buffer^) = secotrs then begin
|
procedure no_interrupt(device : uint8);
|
||||||
console.writestringln('Tests successful!');
|
begin
|
||||||
// end
|
outb($3F6, inb($3f6) or (1 shl 1));
|
||||||
// else begin
|
end;
|
||||||
// console.writestringln('Tests failed!');
|
|
||||||
// console.writehexln($01101001);
|
procedure device_select(device : uint8);
|
||||||
// console.writehexln(uint32(buffer^));
|
begin
|
||||||
// end;
|
outb($1F6, device); //TODO clean
|
||||||
kfree(buffer);
|
end;
|
||||||
|
|
||||||
|
function is_ready() : boolean;
|
||||||
|
var
|
||||||
|
status : uint8;
|
||||||
|
i : uint32;
|
||||||
|
begin
|
||||||
|
//wait for drive to be ready
|
||||||
|
while true do begin
|
||||||
|
status := port_read(ATA_REG_COMMAND);
|
||||||
|
|
||||||
|
if(status and ATA_SR_ERR) = ATA_SR_ERR then begin
|
||||||
|
console.writestringln('[IDE] (IDENTIFY_DEVICE) DRIVE ERROR!');
|
||||||
|
console.redrawWindows();
|
||||||
|
is_ready := false;
|
||||||
|
break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if (status and ATA_SR_BUSY) <> ATA_SR_BUSY then begin
|
||||||
|
is_ready := true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function validate_28bit_address(addr : uint32) : boolean;
|
||||||
|
begin
|
||||||
|
validate_28bit_address := (addr and $F0000000) = 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function identify_device(bus : uint8; device : uint8) : TIdentResponse;
|
||||||
|
var
|
||||||
|
status : uint8;
|
||||||
|
identResponse : TIdentResponse;
|
||||||
|
i : uint8;
|
||||||
|
begin
|
||||||
|
device_select(device);
|
||||||
|
no_interrupt(device);
|
||||||
|
port_write(ATA_REG_CONTROL, 0);
|
||||||
|
|
||||||
|
//check if bus is floating
|
||||||
|
status := port_read(ATA_REG_COMMAND);
|
||||||
|
if status = $FF then exit;
|
||||||
|
|
||||||
|
port_write(ATA_REG_SECCOUNT, 0);
|
||||||
|
port_write(ATA_REG_LBA0, 0);
|
||||||
|
port_write(ATA_REG_LBA1, 0);
|
||||||
|
port_write(ATA_REG_LBA2, 0);
|
||||||
|
|
||||||
|
port_write(ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
|
||||||
|
|
||||||
|
//check if drive is present
|
||||||
|
status := port_read(ATA_REG_COMMAND);
|
||||||
|
if status = $00 then exit;
|
||||||
|
|
||||||
|
if not is_ready() then exit;
|
||||||
|
|
||||||
|
for i:=0 to 255 do begin
|
||||||
|
identResponse[i] := inw(ATA_PRIMARY_BASE + ATA_REG_DATA);
|
||||||
|
end;
|
||||||
|
|
||||||
|
identify_device := identResponse;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure init();
|
procedure init();
|
||||||
@ -221,306 +264,183 @@ end;
|
|||||||
|
|
||||||
function load(ptr : void) : boolean;
|
function load(ptr : void) : boolean;
|
||||||
var
|
var
|
||||||
storageDevice : TStorage_Device;
|
controller : PPCI_Device;
|
||||||
storageDevice1 : TStorage_Device;
|
masterDevice : TStorage_Device;
|
||||||
|
slaveDevice : TStorage_Device;
|
||||||
|
buffer : puint8;
|
||||||
|
i : uint8;
|
||||||
begin
|
begin
|
||||||
push_trace('ide.load');
|
push_trace('ide.load');
|
||||||
console.writestringln('[IDE] (LOAD) BEGIN');
|
console.writestringln('[IDE] (LOAD) BEGIN');
|
||||||
//controller := PPCI_Device(ptr);
|
//controller := PPCI_Device(ptr);
|
||||||
|
controller := PPCI_Device(ptr);
|
||||||
|
|
||||||
console.writestringln('[IDE] (INIT) CHECK FLOATING BUS');
|
console.writestringln('[IDE] (INIT) CHECK FLOATING BUS');
|
||||||
//check if bus is floating and identify device
|
//check if bus is floating and identify device
|
||||||
if inb($1F7) <> $FF then begin
|
if inb($1F7) <> $FF then begin
|
||||||
//outb($3F6, inb($3f6) or (1 shl 1)); // disable interrupts
|
//outb($3F6, inb($3f6) or (1 shl 1)); // disable interrupts
|
||||||
IDEDevices[0].isMaster:= true;
|
IDEDevices[0].isMaster:= true;
|
||||||
IDEDevices[0].info := identify_device(0, $A0);
|
IDEDevices[0].info := identify_device(0, ATA_DEVICE_MASTER);
|
||||||
|
|
||||||
storageDevice.controller := ControllerIDE;
|
masterDevice.controller := ControllerIDE;
|
||||||
storageDevice.controllerId0:= 0;
|
masterDevice.controllerId0:= 0;
|
||||||
storageDevice.maxSectorCount:= (IDEDevices[0].info[60] or (IDEDevices[0].info[61] shl 16) ); //LBA28 SATA
|
masterDevice.maxSectorCount:= (IDEDevices[0].info[60] or (IDEDevices[0].info[61] shl 16) ); //LBA28 SATA
|
||||||
|
|
||||||
storageDevice.hpc:= uint32(IDEDevices[0].info[3] DIV IDEDevices[0].info[1]);
|
if IDEDevices[0].info[1] = 0 then begin
|
||||||
|
console.writestringln('[IDE] (INIT) ERROR: DEVICE IDENT FAILED!');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
storageDevice.sectorSize:= 512;
|
masterDevice.hpc:= uint32(IDEDevices[0].info[3] DIV IDEDevices[0].info[1]);
|
||||||
if storageDevice.maxSectorCount <> 0 then begin
|
|
||||||
|
masterDevice.sectorSize:= 512;
|
||||||
|
if masterDevice.maxSectorCount <> 0 then begin
|
||||||
IDEDevices[0].exists:= true;
|
IDEDevices[0].exists:= true;
|
||||||
storageDevice.readCallback:= @read;
|
masterDevice.readCallback:= @read;
|
||||||
storageDevice.writeCallback:= @write;
|
masterDevice.writeCallback:= @write;
|
||||||
storagemanagement.register_device(@storageDevice);
|
storagemanagement.register_device(@masterDevice);
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if inb($1F7) <> $FF then begin
|
|
||||||
IDEDevices[1].isMaster:= false;
|
|
||||||
IDEDevices[1].info := identify_device(0, $B0);
|
|
||||||
|
|
||||||
storageDevice1.controller := ControllerIDE;
|
|
||||||
storageDevice1.controllerId0:= 1;
|
|
||||||
storageDevice1.maxSectorCount:= (IDEDevices[1].info[60] or (IDEDevices[1].info[61] shl 16) ); //LBA28 SATA
|
|
||||||
storageDevice1.sectorSize:= 512;
|
|
||||||
if storageDevice1.maxSectorCount <> 0 then begin
|
|
||||||
IDEDevices[1].exists:= true;
|
|
||||||
storageDevice1.readCallback:= @read;
|
|
||||||
storageDevice1.writeCallback:= @write;
|
|
||||||
//storagemanagement.register_device(@storageDevice1);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
console.writestringln('[IDE] (LOAD) END');
|
console.writestringln('[IDE] (LOAD) END');
|
||||||
pop_trace();
|
pop_trace();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure noInt(drive : uint8);
|
// procedure flush();
|
||||||
begin
|
// begin
|
||||||
if drive = 0 then begin
|
// port_write(ATA_CMD_CACHE_FLUSH);
|
||||||
outb($1F6, $A0); //drive select
|
// if not is_ready() then exit;
|
||||||
outb($3F6, inb($3f6) or (1 shl 1)); // disable interrupts
|
// end;
|
||||||
//outb($1F6, $B0); //drive select
|
|
||||||
//outb($3F6, inb($3f6) and (0 shl 1)); // disable interrupts
|
|
||||||
end else begin
|
|
||||||
outb($1F6, $B0); //drive select
|
|
||||||
outb($3F6, inb($3f6) or (1 shl 1)); // disable interrupts
|
|
||||||
//outb($1F6, $A0); //drive select
|
|
||||||
//outb($3F6, inb($3f6) and (0 shl 1)); // disable interrupts
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function identify_device(bus : uint8; drive : uint8) : TIdentResponse;
|
procedure readPIO28(drive : uint8; LBA : uint32; buffer : puint8);
|
||||||
var
|
var
|
||||||
i : uint8;
|
status : uint8;
|
||||||
identResponse : TIdentResponse;
|
i: uint16;
|
||||||
t : uint32 = 0;
|
device: uint8;
|
||||||
|
data: uint16;
|
||||||
begin
|
begin
|
||||||
push_trace('ide.identify_device');
|
if not validate_28bit_address(LBA) then begin
|
||||||
console.writestringln('[IDE] (IDENTIFY_DEVICE) BEGIN');
|
console.writestringln('IDE (writePIO28) ERROR: Invalid LBA!');
|
||||||
if bus = 0 then begin
|
|
||||||
|
|
||||||
if drive = $A0 then noInt(0);
|
|
||||||
if drive = $B0 then noInt(1);
|
|
||||||
|
|
||||||
outb($1F6, drive); //drive select
|
|
||||||
|
|
||||||
outb($1F2, 0); //clear sector count and lba
|
|
||||||
outb($1F3, 0);
|
|
||||||
outb($1F4, 0);
|
|
||||||
outb($1F5, 0);
|
|
||||||
|
|
||||||
outb($1F7, ATA_CMD_IDENTIFY); //send identify command//
|
|
||||||
|
|
||||||
while true do begin
|
|
||||||
if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
while true do begin
|
//Add last 4 bits of LBA to device port
|
||||||
if (inb($1f7) and (1 shl 3)) <> 0 then break;
|
|
||||||
if (inb($1F7) and 1) <> 0 then exit; //drive error
|
|
||||||
if t > 100000 then exit; //todo return false
|
|
||||||
t +=1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
for i:=0 to 255 do begin
|
|
||||||
identResponse[i] := inb($1F0); //read all bits
|
|
||||||
end;
|
|
||||||
|
|
||||||
identify_device:= identResponse;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
console.writestringln('[IDE] (IDENTIFY_DEVICE) END');
|
|
||||||
pop_trace();
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure writePIO28(drive : uint8; LBA : uint32; sectorCount : uint8; buffer : Puint32);
|
|
||||||
var
|
|
||||||
i : uint8;
|
|
||||||
ii : uint8;
|
|
||||||
iii : uint32;
|
|
||||||
begin
|
|
||||||
push_trace('ide.writePIO28');
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) BEGIN');
|
|
||||||
console.redrawWindows;
|
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
|
||||||
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) 1');
|
|
||||||
console.redrawWindows;
|
|
||||||
|
|
||||||
noInt(drive);
|
|
||||||
|
|
||||||
if IDEDevices[drive].isMaster then begin
|
if IDEDevices[drive].isMaster then begin
|
||||||
outb($1F6, $A0); //drive select
|
device:= ATA_DEVICE_MASTER;
|
||||||
outb($1F7, $E0 or ((LBA shr 24) and $0F)); //LBA command primary master
|
device_select($E0 or ((LBA and $0F000000) shr 24)); //LBA primary master
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
outb($1F6, $B0); //drive select
|
device:= ATA_DEVICE_SLAVE;
|
||||||
outb($1F7, $F0 or ((LBA shr 24) and $0F)); //LBA command primary slave
|
device_select($F0 or ((LBA and $0F000000) shr 24)); //LBA primary slave
|
||||||
end;
|
end;
|
||||||
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) 2');
|
no_interrupt(device);
|
||||||
console.redrawWindows;
|
port_write(ATA_REG_ERROR, 0);
|
||||||
|
|
||||||
outb($1F2, sectorCount);
|
//Write sector count and LBA
|
||||||
outb($1F3, LBA);
|
port_write(ATA_REG_SECCOUNT, 1);
|
||||||
outb($1F4, LBA shr 8);
|
port_write(ATA_REG_LBA0, (LBA and $000000FF));
|
||||||
outb($1F5, LBA shr 16);
|
port_write(ATA_REG_LBA1, (LBA and $0000FF00) shr 8);
|
||||||
outb($1F7, $30); //write command
|
port_write(ATA_REG_LBA2, (LBA and $00FF0000) shr 16);
|
||||||
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) 3');
|
//send read command
|
||||||
console.redrawWindows;
|
port_write(ATA_REG_COMMAND, ATA_CMD_READ_PIO);
|
||||||
|
if not is_ready() then exit;
|
||||||
|
|
||||||
for i:=0 to sectorCount-1 do begin
|
i:=0;
|
||||||
|
while i < 512 do begin
|
||||||
|
// if not is_ready() then exit;
|
||||||
|
|
||||||
//poll status
|
data:= inw(ATA_PRIMARY_BASE + ATA_REG_DATA);
|
||||||
while true do if (inb($1f7) and ATA_SR_BUSY) = 0 then break; //Wait until drive not busy
|
|
||||||
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) 4');
|
buffer[i+1] := uint8($00ff and (data shr 8));
|
||||||
console.redrawWindows;
|
buffer[i] := uint8($00ff and data);
|
||||||
|
|
||||||
while true do begin
|
i:= i + 2;
|
||||||
console.writestring('[IDE] (WRITEPIO28) inb($1f7): ');
|
|
||||||
writehexpair(inb($1f7));
|
|
||||||
if inb($1f7) = $40 then begin
|
|
||||||
while true do begin console.redrawWindows; end;
|
|
||||||
end;
|
end;
|
||||||
writestringln(' ');
|
|
||||||
console.redrawWindows;
|
|
||||||
if (inb($1f7) and (1 shl 3)) <> 0 then break;
|
|
||||||
if (inb($1F7) and 1) <> 0 then begin
|
|
||||||
console.writestringln('write error');
|
|
||||||
console.redrawWindows;
|
|
||||||
exit;
|
|
||||||
end; //drive error
|
|
||||||
end;
|
|
||||||
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) 5');
|
|
||||||
console.redrawWindows;
|
|
||||||
|
|
||||||
for ii:=0 to 127 do begin //write data
|
|
||||||
outb($1F0, Puint32(buffer + ((i * 512) + (ii * 32) DIV 32) )^);
|
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
|
||||||
outb($1F7, $E7);
|
|
||||||
if ii <> 127 then begin
|
|
||||||
outb($1F0, Puint32(buffer + ((i * 512) + (ii * 32) DIV 32) )^ shr 16);
|
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
|
||||||
outb($1F7, $E7);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) 6');
|
|
||||||
console.redrawWindows;
|
|
||||||
|
|
||||||
end;
|
|
||||||
console.writestringln('[IDE] (WRITEPIO28) END');
|
|
||||||
console.redrawWindows;
|
|
||||||
pop_trace();
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure readPIO28(drive : uint8; LBA : uint32; sectorCount : uint8; buffer : puint32);
|
procedure writePIO28(drive : uint8; LBA : uint32; buffer : puint8);
|
||||||
var
|
var
|
||||||
i : uint8;
|
status : uint8;
|
||||||
ii : uint8;
|
i: uint16;
|
||||||
iii : uint32;
|
device: uint8;
|
||||||
begin
|
begin
|
||||||
push_trace('ide.readPIO28');
|
if not validate_28bit_address(LBA) then begin
|
||||||
console.writestringln('[IDE] (READPIO28) BEGIN');
|
console.writestringln('IDE (writePIO28) ERROR: Invalid LBA!');
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
end;
|
||||||
|
|
||||||
noInt(drive);
|
|
||||||
|
|
||||||
|
//Add last 4 bits of LBA to device port
|
||||||
if IDEDevices[drive].isMaster then begin
|
if IDEDevices[drive].isMaster then begin
|
||||||
//outb($1F6, $A0); //drive select
|
device:= ATA_DEVICE_MASTER;
|
||||||
outb($1F7, $E0 or ((LBA shr 24) and $0F)); //read command primary master
|
device_select($E0 or ((LBA and $0F000000) shr 24)); //LBA primary master
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
//outb($1F6, $B0); //drive select
|
device:= ATA_DEVICE_SLAVE;
|
||||||
outb($1F7, $F0 or ((LBA shr 24) and $0F)); //read command primary slave
|
device_select($F0 or ((LBA and $0F000000) shr 24)); //LBA primary slave
|
||||||
end;
|
end;
|
||||||
|
|
||||||
outb($1F2, sectorCount);
|
no_interrupt(device);
|
||||||
outb($1F3, LBA);
|
port_write(ATA_REG_ERROR, 0);
|
||||||
outb($1F4, LBA shr 8);
|
port_write(ATA_REG_CONTROL, 0);
|
||||||
outb($1F5, LBA shr 16);
|
|
||||||
outb($1F7, $20); //read command
|
|
||||||
|
|
||||||
|
//check if bus is floating
|
||||||
|
status := port_read(ATA_REG_COMMAND);
|
||||||
|
if status = $FF then exit;
|
||||||
|
|
||||||
for i:=0 to sectorCount-1 do begin
|
//Write sector count and LBA
|
||||||
|
port_write(ATA_REG_SECCOUNT, 1);
|
||||||
|
port_write(ATA_REG_LBA0, (LBA and $000000FF));
|
||||||
|
port_write(ATA_REG_LBA1, (LBA and $0000FF00) shr 8);
|
||||||
|
port_write(ATA_REG_LBA2, (LBA and $00FF0000) shr 16);
|
||||||
|
|
||||||
//poll status
|
//send write command
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
port_write(ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
|
||||||
while true do begin
|
|
||||||
if (inb($1f7) and (1 shl 3)) <> 0 then break;
|
console.writestringln('ide write sttart');
|
||||||
if (inb($1f7) and (1 shl 5)) <> 0 then begin
|
console.redrawWindows();
|
||||||
console.writestringln('IDE DRIVE FAULT');
|
|
||||||
redrawWindows();
|
//write data
|
||||||
exit;
|
i:=0;
|
||||||
end;
|
while i < 512 do begin
|
||||||
if (inb($1f7) and (1 shl 6)) <> 0 then begin
|
outw(ATA_PRIMARY_BASE + ATA_REG_DATA, uint16(buffer[i] or (buffer[i+1] shl 8)));
|
||||||
console.writestringln('IDE Spun Down');
|
i:= i + 2;
|
||||||
redrawWindows();
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if (inb($1F7) and 1) <> 0 then begin
|
|
||||||
console.writestringln('IDE read ERROR');
|
|
||||||
redrawWindows();
|
|
||||||
exit;
|
|
||||||
end; //drive error
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
for ii:=0 to 127 do begin //read data
|
console.writestringln('ise write stop');
|
||||||
Puint32(buffer + ((i * 512) + (ii * 32) DIV 32))^ := uint32(inb($1F0));
|
console.redrawWindows();
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
|
||||||
if ii <> 127 then begin
|
//flush drive cache
|
||||||
Puint32(buffer + ((i * 512) + (ii * 32) DIV 32))^ := ((uint32(inb($1F0)) shl 16) or Puint32(buffer + ((i * 512) + (ii * 32) DIV 32))^); //wrong
|
psleep(1);
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
port_write(ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH);
|
||||||
end;
|
psleep(1);
|
||||||
end;
|
if not is_ready() then exit;
|
||||||
end;
|
|
||||||
console.writestringln('[IDE] (READPIO28) END');
|
console.writestringln('ide write end');
|
||||||
pop_trace();
|
console.redrawWindows();
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure readPIOPI(drive : uint8; LBA : uint32; buffer : Puint32);
|
procedure read(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32);
|
||||||
var
|
var
|
||||||
i : uint16;
|
i : uint16;
|
||||||
begin
|
begin
|
||||||
console.writestringln('[IDE] (READPIOPI) BEGIN');
|
// for i:=0 to sectorCount-1 do begin
|
||||||
if IDEDevices[drive].isMaster then begin
|
// readPIO28(device^.controllerId0, LBA, puint8(@buffer[512*i]));
|
||||||
outb($1F7, $E0 or ((LBA shr 24) and $0F)); // command primary master
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
outb($1F7, $F0 or ((LBA shr 24) and $0F)); // command primary slave
|
|
||||||
end;
|
|
||||||
|
|
||||||
outb($1F2, 1);
|
|
||||||
outb($1F3, LBA);
|
|
||||||
outb($1F4, LBA shr 8);
|
|
||||||
outb($1F5, LBA shr 16);
|
|
||||||
outb($1F7, ATAPI_CMD_READ); //read command
|
|
||||||
|
|
||||||
//poll status
|
|
||||||
while true do if (inb($1f7) and (1 shl 7)) = 0 then break; //Wait until drive not busy
|
|
||||||
|
|
||||||
while true do begin
|
|
||||||
if (inb($1f7) and (1 shl 3)) <> 0 then break;
|
|
||||||
if (inb($1F7) and 1) <> 0 then begin
|
|
||||||
console.writestringln('IDE read ERROR');
|
|
||||||
exit;
|
|
||||||
end; //drive error
|
|
||||||
end;
|
|
||||||
|
|
||||||
// for i:=0 to 1023 do begin
|
|
||||||
// Puint32(buffer + (i * 1))^ := inb($1F0);
|
|
||||||
// end;
|
// end;
|
||||||
console.writestringln('[IDE] (READPIOPI) END');
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
readPIO28(device^.controllerId0, LBA, puint8(buffer));
|
||||||
|
|
||||||
procedure read(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32);
|
|
||||||
begin
|
|
||||||
readPIO28(device^.controllerId0, LBA, sectorCount, buffer); //need to figure out max read/write amount per operation
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure write(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32);
|
procedure write(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32);
|
||||||
|
var
|
||||||
|
i : uint16;
|
||||||
begin
|
begin
|
||||||
writePIO28(device^.controllerId0, LBA, sectorCount, buffer);
|
// for i:=0 to sectorCount-1 do begin
|
||||||
|
// writePIO28(device^.controllerId0, LBA, puint8(@buffer[512*i]));
|
||||||
|
// end;
|
||||||
|
writePIO28(device^.controllerId0, LBA, puint8(buffer));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
@ -834,21 +834,11 @@ begin //maybe increase buffer size by one?
|
|||||||
zeroBuffer:= puint32(kalloc( disk^.sectorSize ));
|
zeroBuffer:= puint32(kalloc( disk^.sectorSize ));
|
||||||
memset(uint32(zeroBuffer), 0, disk^.sectorSize );
|
memset(uint32(zeroBuffer), 0, disk^.sectorSize );
|
||||||
|
|
||||||
{while true do begin
|
// while true do begin
|
||||||
if i > FATSize then break;
|
// if i > FATSize then break;
|
||||||
writestring('LOOP BEGIN: ');
|
// disk^.writecallback(disk, fatStart + i, 1, zeroBuffer);
|
||||||
writeintln(i);
|
// i+=1;
|
||||||
writeintln(bootRecord^.rsvSectors);
|
// end;
|
||||||
writeintln(start);
|
|
||||||
writeintln(fatStart);
|
|
||||||
writeintln(FATSize);
|
|
||||||
console.redrawWindows;
|
|
||||||
disk^.writecallback(disk, fatStart + i, 1, zeroBuffer);
|
|
||||||
writestring('LOOP END: ');
|
|
||||||
writeintln(i);
|
|
||||||
console.redrawWindows;
|
|
||||||
i+=1;
|
|
||||||
end;}
|
|
||||||
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
kfree(zeroBuffer);
|
kfree(zeroBuffer);
|
||||||
|
@ -25,7 +25,7 @@ uses
|
|||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
TControllerType = (ControllerIDE, ControllerUSB, ControllerAHCI, ControllerNET);
|
TControllerType = (ControllerIDE, ControllerUSB, ControllerAHCI, ControllerNET, ControllerRAM, rsvctr1, rsvctr2, rsvctr3);
|
||||||
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
|
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
|
||||||
PStorage_volume = ^TStorage_Volume;
|
PStorage_volume = ^TStorage_Volume;
|
||||||
PStorage_device = ^TStorage_Device;
|
PStorage_device = ^TStorage_Device;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user