git-svn-id: https://spexeah.com:8443/svn/Asuro@359 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
parent
a608c38353
commit
c2ca17dfc4
286
src/driver/storage/AHCI.pas
Normal file
286
src/driver/storage/AHCI.pas
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
{ ************************************************
|
||||||
|
* Asuro
|
||||||
|
* Unit: Drivers/AHCI
|
||||||
|
* Description: AHCI SATA Driver
|
||||||
|
************************************************
|
||||||
|
* Author: Aaron Hance
|
||||||
|
* Contributors:
|
||||||
|
************************************************ }
|
||||||
|
|
||||||
|
unit AHCI;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
util,
|
||||||
|
PCI,
|
||||||
|
drivertypes,
|
||||||
|
drivermanagement,
|
||||||
|
lmemorymanager,
|
||||||
|
console,
|
||||||
|
vmemorymanager;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
//Struct hell
|
||||||
|
|
||||||
|
TFIS_Type = (
|
||||||
|
REG_H2D = $27,
|
||||||
|
REG_D2H = $34,
|
||||||
|
DMA_ACT = $39,
|
||||||
|
DMA_SETUP = $41,
|
||||||
|
DATA = $46,
|
||||||
|
BIST = $58,
|
||||||
|
PIO_SETUP = $5F,
|
||||||
|
DEV_BITS = $A0
|
||||||
|
);
|
||||||
|
|
||||||
|
PFIS_REG_H2D = ^TFIS_REG_H2D;
|
||||||
|
TFIS_REG_H2D = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
port_mult : UBit4;
|
||||||
|
rsv0 : UBit3;
|
||||||
|
coc : boolean;
|
||||||
|
command : uint8;
|
||||||
|
feature_low : uint8;
|
||||||
|
lba0 : uint8;
|
||||||
|
lba1 : uint8;
|
||||||
|
lba2 : uint8;
|
||||||
|
device : uint8;
|
||||||
|
lba3 : uint8;
|
||||||
|
lba4 : uint8;
|
||||||
|
lba5 : uint8;
|
||||||
|
feature_high : uint8;
|
||||||
|
count_low : uint8;
|
||||||
|
count_high : uint8;
|
||||||
|
icc : uint8;
|
||||||
|
control : uint8;
|
||||||
|
rsvl : uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TFIS_REG_D2H = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
port_mult : UBit4;
|
||||||
|
rsv0 : UBit2;
|
||||||
|
i : boolean;
|
||||||
|
rsvl : boolean;
|
||||||
|
status : uint8;
|
||||||
|
error : uint8;
|
||||||
|
lba0 : uint8;
|
||||||
|
lba1 : uint8;
|
||||||
|
lba2 : uint8;
|
||||||
|
device : uint8;
|
||||||
|
lba3 : uint8;
|
||||||
|
lba4 : uint8;
|
||||||
|
lba5 : uint8;
|
||||||
|
rsv2 : uint8;
|
||||||
|
count_low : uint8;
|
||||||
|
count_high : uint8;
|
||||||
|
rsv3 : uint16;
|
||||||
|
rsv4 : uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TFIS_Data = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
port_mult : UBit4;
|
||||||
|
rsv0 : UBit4;
|
||||||
|
rsv1 : uint16;
|
||||||
|
data : ^uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TFIS_PIO_Setup = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
pmport : UBit4;
|
||||||
|
rsv0 : boolean;
|
||||||
|
d : boolean;
|
||||||
|
i : boolean;
|
||||||
|
rsv1 : boolean;
|
||||||
|
status : uint8;
|
||||||
|
error : uint8;
|
||||||
|
lba0 : uint8;
|
||||||
|
lba1 : uint8;
|
||||||
|
lba2 : uint8;
|
||||||
|
device : uint8;
|
||||||
|
lba3 : uint8;
|
||||||
|
lba4 : uint8;
|
||||||
|
lba5 : uint8;
|
||||||
|
rsv2 : uint8;
|
||||||
|
countl : uint8;
|
||||||
|
counth : uint8;
|
||||||
|
rsv3 : uint8;
|
||||||
|
e_status : uint8;
|
||||||
|
tc : uint16;
|
||||||
|
rsv4 : uint16;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// TFIS_DMA_Setup = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
// THBA_Memory = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
// THBA_Port = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
// THBA_FIS = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
PHBA_PORT = ^THBA_PORT;
|
||||||
|
THBA_PORT = bitpacked record
|
||||||
|
clb : uint32;
|
||||||
|
clbu : uint32;
|
||||||
|
fb : uint32;
|
||||||
|
fbu : uint32;
|
||||||
|
istat : uint32;
|
||||||
|
ie : uint32;
|
||||||
|
cmd : uint32;
|
||||||
|
rsv0 : uint32;
|
||||||
|
tfd : uint32;
|
||||||
|
sig : uint32;
|
||||||
|
ssts : uint32;
|
||||||
|
sctl : uint32;
|
||||||
|
serr : uint32;
|
||||||
|
sact : uint32;
|
||||||
|
ci : uint32;
|
||||||
|
sntf : uint32;
|
||||||
|
fbs : uint32;
|
||||||
|
rsv1 : array[0..11] of uint32;
|
||||||
|
vendor : array[0..4] of uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
THBA_MEM = bitpacked record
|
||||||
|
cap : uint32; //0
|
||||||
|
global_host_control : uint32; //4
|
||||||
|
interrupt_status : uint32; //8
|
||||||
|
port_implemented : uint32; //c
|
||||||
|
version : uint32; //10
|
||||||
|
ccc_control : uint32; //14
|
||||||
|
ccc_ports : uint32; //18
|
||||||
|
em_location : uint32; //1c
|
||||||
|
em_Control : uint32; //20
|
||||||
|
hcap2 : uint32; //24
|
||||||
|
bohc : uint32; //28
|
||||||
|
rsv0 : array[0..210] of boolean;
|
||||||
|
ports : array[0..31] of THBA_Port;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PHBA = ^THBA_MEM;
|
||||||
|
|
||||||
|
PCMDHeader = ^ TCommand_Header;
|
||||||
|
TCommand_Header = bitpacked record
|
||||||
|
cfl : ubit5;
|
||||||
|
a : boolean;
|
||||||
|
w : boolean;
|
||||||
|
p : boolean;
|
||||||
|
r : boolean;
|
||||||
|
b : boolean;
|
||||||
|
c : boolean;
|
||||||
|
rsv0 : boolean;
|
||||||
|
pmp : ubit4;
|
||||||
|
PRDTL : uint16;
|
||||||
|
PRDTBC : uint32;
|
||||||
|
CTBA : uint32;
|
||||||
|
CTBAU : uint32;
|
||||||
|
rsv1 : array[0..3] of uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TPRD_Entry = bitpacked record
|
||||||
|
data_base_address : uint32;
|
||||||
|
data_bade_address_U : uint32;
|
||||||
|
rsv0 : uint32;
|
||||||
|
data_byte_count : ubit22;
|
||||||
|
rsv1 : ubit9;
|
||||||
|
interrupt_oc : boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PCommand_Table = ^TCommand_Table;
|
||||||
|
TCommand_Table = bitpacked record
|
||||||
|
cfis : array[0..64] of uint8;
|
||||||
|
acmd : array[0..16] of uint8;
|
||||||
|
rsv : array[0..48] of uint8;
|
||||||
|
prdt : array[0..7] of TPRD_Entry;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TSataDevice = record
|
||||||
|
controller : uint8;
|
||||||
|
port : uint8;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
//constants
|
||||||
|
//SATA_SIG_ATA := $101;
|
||||||
|
//SATA_SIG_ATAPI := $EB140101;
|
||||||
|
//STA_SIG_SEMB := $C33C0101;
|
||||||
|
//STAT_SIG_PM := $96690101;
|
||||||
|
AHCI_BASE: uint32 = $400000; //irrelivent
|
||||||
|
|
||||||
|
//other
|
||||||
|
ahciControllers : array[0.16] of PuInt32;
|
||||||
|
ahciControllerCount : uint8 = 0;
|
||||||
|
hba : array[0..16] of PHBA;
|
||||||
|
|
||||||
|
sataDevices : array[0..127] of TSataDevice;
|
||||||
|
sataDeviceCount : uint8;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure init();
|
||||||
|
procedure check_ports(controller : uint8);
|
||||||
|
procedure enable_cmd(port : uint8);
|
||||||
|
procedure disable_cmd(port : uint8);
|
||||||
|
procedure port_rebase(port : uint8);
|
||||||
|
function load(ptr:void): boolean;
|
||||||
|
function read(port : uint8; startl : uint32; starth : uint32; count : uint32; buf : PuInt32) : boolean;
|
||||||
|
function write(port : uint8; startl : uint32; starth : uint32; count : uint32; buf : PuInt32) : boolean;
|
||||||
|
function find_cmd_slot(port : uint8) : uint32;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure init();
|
||||||
|
var
|
||||||
|
devID : TDeviceIdentifier;
|
||||||
|
begin
|
||||||
|
console.writestringln('AHCI: Registering driver');
|
||||||
|
devID.bus:= biPCI;
|
||||||
|
devID.id0:= idANY;
|
||||||
|
devID.id1:= $00000001;
|
||||||
|
devID.id2:= $00000006;
|
||||||
|
devID.id3:= $00000001;
|
||||||
|
devID.id4:= idANY;
|
||||||
|
devID.ex:= nil;
|
||||||
|
drivermanagement.register_driver('AHCI Driver', @devID, @load);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure load(ptr : void);
|
||||||
|
begin
|
||||||
|
console.writestringln('AHCI: initilizing a new controller');
|
||||||
|
ahciControllers[ahciControllerCount] := ptr;
|
||||||
|
hba[ahciControllerCount] := PPCI_Device(ptr)^.address5;
|
||||||
|
new_page_at_address(hba[ahciControllerCount]);
|
||||||
|
|
||||||
|
//here would be any controller setup needed
|
||||||
|
|
||||||
|
check_ports(ahciControllerCount);
|
||||||
|
ahciControllerCount += 1;
|
||||||
|
exit(true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure check_ports(controller : uint8);
|
||||||
|
var
|
||||||
|
d : uint32 = 1;
|
||||||
|
i : uint32;
|
||||||
|
begin
|
||||||
|
for i:=0 to 31 do begin
|
||||||
|
if (d > 0) and (hba[controller]^.port_implemented shr i) = 1 then begin
|
||||||
|
if (hba[controller]^.ports[i].ssts shr 8) <> 1 and (hba[controller]^.ports[i].ssts and $0F) <> 3 then begin
|
||||||
|
if hba[controller]^.ports[i].sig = 1 then begin
|
||||||
|
//device is sata
|
||||||
|
sataDevices[sataDeviceCount].controller := controller;
|
||||||
|
sataDevices[sataDeviceCount].port := i;
|
||||||
|
sataDeviceCount += 1;
|
||||||
|
end;
|
||||||
|
//TODO implement ATAPI
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
539
src/driver/storage/AHCI_OLD.pas
Normal file
539
src/driver/storage/AHCI_OLD.pas
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
{ ************************************************
|
||||||
|
* Asuro
|
||||||
|
* Unit: Drivers/AHCI
|
||||||
|
* Description: AHCI SATA Driver
|
||||||
|
************************************************
|
||||||
|
* Author: Aaron Hance
|
||||||
|
* Contributors:
|
||||||
|
************************************************ }
|
||||||
|
|
||||||
|
unit AHCI;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
util,
|
||||||
|
PCI,
|
||||||
|
drivertypes,
|
||||||
|
drivermanagement,
|
||||||
|
lmemorymanager,
|
||||||
|
console,
|
||||||
|
vmemorymanager;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
//Struct hell
|
||||||
|
|
||||||
|
TFIS_Type = (
|
||||||
|
REG_H2D = $27,
|
||||||
|
REG_D2H = $34,
|
||||||
|
DMA_ACT = $39,
|
||||||
|
DMA_SETUP = $41,
|
||||||
|
DATA = $46,
|
||||||
|
BIST = $58,
|
||||||
|
PIO_SETUP = $5F,
|
||||||
|
DEV_BITS = $A0
|
||||||
|
);
|
||||||
|
|
||||||
|
PFIS_REG_H2D = ^TFIS_REG_H2D;
|
||||||
|
TFIS_REG_H2D = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
port_mult : UBit4;
|
||||||
|
rsv0 : UBit3;
|
||||||
|
coc : boolean;
|
||||||
|
command : uint8;
|
||||||
|
feature_low : uint8;
|
||||||
|
lba0 : uint8;
|
||||||
|
lba1 : uint8;
|
||||||
|
lba2 : uint8;
|
||||||
|
device : uint8;
|
||||||
|
lba3 : uint8;
|
||||||
|
lba4 : uint8;
|
||||||
|
lba5 : uint8;
|
||||||
|
feature_high : uint8;
|
||||||
|
count_low : uint8;
|
||||||
|
count_high : uint8;
|
||||||
|
icc : uint8;
|
||||||
|
control : uint8;
|
||||||
|
rsvl : uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TFIS_REG_D2H = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
port_mult : UBit4;
|
||||||
|
rsv0 : UBit2;
|
||||||
|
i : boolean;
|
||||||
|
rsvl : boolean;
|
||||||
|
status : uint8;
|
||||||
|
error : uint8;
|
||||||
|
lba0 : uint8;
|
||||||
|
lba1 : uint8;
|
||||||
|
lba2 : uint8;
|
||||||
|
device : uint8;
|
||||||
|
lba3 : uint8;
|
||||||
|
lba4 : uint8;
|
||||||
|
lba5 : uint8;
|
||||||
|
rsv2 : uint8;
|
||||||
|
count_low : uint8;
|
||||||
|
count_high : uint8;
|
||||||
|
rsv3 : uint16;
|
||||||
|
rsv4 : uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TFIS_Data = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
port_mult : UBit4;
|
||||||
|
rsv0 : UBit4;
|
||||||
|
rsv1 : uint16;
|
||||||
|
data : ^uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TFIS_PIO_Setup = bitpacked record
|
||||||
|
fis_type : uint8;
|
||||||
|
pmport : UBit4;
|
||||||
|
rsv0 : boolean;
|
||||||
|
d : boolean;
|
||||||
|
i : boolean;
|
||||||
|
rsv1 : boolean;
|
||||||
|
status : uint8;
|
||||||
|
error : uint8;
|
||||||
|
lba0 : uint8;
|
||||||
|
lba1 : uint8;
|
||||||
|
lba2 : uint8;
|
||||||
|
device : uint8;
|
||||||
|
lba3 : uint8;
|
||||||
|
lba4 : uint8;
|
||||||
|
lba5 : uint8;
|
||||||
|
rsv2 : uint8;
|
||||||
|
countl : uint8;
|
||||||
|
counth : uint8;
|
||||||
|
rsv3 : uint8;
|
||||||
|
e_status : uint8;
|
||||||
|
tc : uint16;
|
||||||
|
rsv4 : uint16;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// TFIS_DMA_Setup = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
// THBA_Memory = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
// THBA_Port = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
// THBA_FIS = bitpacked record
|
||||||
|
// end;
|
||||||
|
|
||||||
|
PHBA_PORT = ^THBA_PORT;
|
||||||
|
THBA_PORT = bitpacked record
|
||||||
|
clb : uint32;
|
||||||
|
clbu : uint32;
|
||||||
|
fb : uint32;
|
||||||
|
fbu : uint32;
|
||||||
|
istat : uint32;
|
||||||
|
ie : uint32;
|
||||||
|
cmd : uint32;
|
||||||
|
rsv0 : uint32;
|
||||||
|
tfd : uint32;
|
||||||
|
sig : uint32;
|
||||||
|
ssts : uint32;
|
||||||
|
sctl : uint32;
|
||||||
|
serr : uint32;
|
||||||
|
sact : uint32;
|
||||||
|
ci : uint32;
|
||||||
|
sntf : uint32;
|
||||||
|
fbs : uint32;
|
||||||
|
rsv1 : array[0..11] of uint32;
|
||||||
|
vendor : array[0..4] of uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
THBA_MEM = bitpacked record
|
||||||
|
cap : uint32; //0
|
||||||
|
global_host_control : uint32; //4
|
||||||
|
interrupt_status : uint32; //8
|
||||||
|
port_implemented : uint32; //c
|
||||||
|
version : uint32; //10
|
||||||
|
ccc_control : uint32; //14
|
||||||
|
ccc_ports : uint32; //18
|
||||||
|
em_location : uint32; //1c
|
||||||
|
em_Control : uint32; //20
|
||||||
|
hcap2 : uint32; //24
|
||||||
|
bohc : uint32; //28
|
||||||
|
rsv0 : array[0..210] of boolean;
|
||||||
|
ports : array[0..31] of THBA_Port;
|
||||||
|
end;
|
||||||
|
|
||||||
|
THBAptr = ^THBA_MEM;
|
||||||
|
|
||||||
|
PCMDHeader = ^ TCommand_Header;
|
||||||
|
TCommand_Header = bitpacked record
|
||||||
|
cfl : ubit5;
|
||||||
|
a : boolean;
|
||||||
|
w : boolean;
|
||||||
|
p : boolean;
|
||||||
|
r : boolean;
|
||||||
|
b : boolean;
|
||||||
|
c : boolean;
|
||||||
|
rsv0 : boolean;
|
||||||
|
pmp : ubit4;
|
||||||
|
PRDTL : uint16;
|
||||||
|
PRDTBC : uint32;
|
||||||
|
CTBA : uint32;
|
||||||
|
CTBAU : uint32;
|
||||||
|
rsv1 : array[0..3] of uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TPRD_Entry = bitpacked record
|
||||||
|
data_base_address : uint32;
|
||||||
|
data_bade_address_U : uint32;
|
||||||
|
rsv0 : uint32;
|
||||||
|
data_byte_count : ubit22;
|
||||||
|
rsv1 : ubit9;
|
||||||
|
interrupt_oc : boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PCommand_Table = ^TCommand_Table;
|
||||||
|
TCommand_Table = bitpacked record
|
||||||
|
cfis : array[0..64] of uint8;
|
||||||
|
acmd : array[0..16] of uint8;
|
||||||
|
rsv : array[0..48] of uint8;
|
||||||
|
prdt : array[0..7] of TPRD_Entry;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
//constants
|
||||||
|
//SATA_SIG_ATA := $101;
|
||||||
|
//SATA_SIG_ATAPI := $EB140101;
|
||||||
|
//STA_SIG_SEMB := $C33C0101;
|
||||||
|
//STAT_SIG_PM := $96690101;
|
||||||
|
AHCI_BASE: uint32 = $400000;
|
||||||
|
|
||||||
|
//other
|
||||||
|
ahciController : PuInt32;
|
||||||
|
hba : THBAptr;
|
||||||
|
|
||||||
|
sataStorageDevices : array[0..31] of PuInt32;
|
||||||
|
sataStorageDeviceCount : uint8;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure init();
|
||||||
|
procedure check_ports();
|
||||||
|
procedure enable_cmd(port : uint8);
|
||||||
|
procedure disable_cmd(port : uint8);
|
||||||
|
procedure port_rebase(port : uint8);
|
||||||
|
function load(ptr:void): boolean;
|
||||||
|
function read(port : uint8; startl : uint32; starth : uint32; count : uint32; buf : PuInt32) : boolean;
|
||||||
|
function write(port : uint8; startl : uint32; starth : uint32; count : uint32; buf : PuInt32) : boolean;
|
||||||
|
function find_cmd_slot(port : uint8) : uint32;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure init();
|
||||||
|
var
|
||||||
|
devID : TDeviceIdentifier;
|
||||||
|
begin
|
||||||
|
console.writestringln('AHCI: STARTING INIT');
|
||||||
|
devID.bus:= biPCI;
|
||||||
|
devID.id0:= idANY;
|
||||||
|
devID.id1:= $00000001;
|
||||||
|
devID.id2:= $00000006;
|
||||||
|
devID.id3:= $00000001;
|
||||||
|
devID.ex:= nil;
|
||||||
|
drivermanagement.register_driver('AHCI Controller', @devID, @load);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function load(ptr : void) : boolean;
|
||||||
|
begin
|
||||||
|
ahciController := ptr;
|
||||||
|
hba := THBAptr(PPCI_Device(ahciController)^.address5);
|
||||||
|
new_page_at_address(uint32(hba));
|
||||||
|
new_page_at_address(AHCI_BASE);
|
||||||
|
AHCI_BASE := PPCI_Device(ahciController)^.address5;
|
||||||
|
check_ports();
|
||||||
|
load:= true;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure check_ports();
|
||||||
|
var
|
||||||
|
d : uint32;
|
||||||
|
i : uint32;
|
||||||
|
activePorts : array[0..32] of uint32;
|
||||||
|
|
||||||
|
begin
|
||||||
|
d:= 1;
|
||||||
|
for i:= 0 to 31 do begin
|
||||||
|
if (d > 0) and (hba^.port_implemented <> 0) then begin // port connected
|
||||||
|
if hba^.ports[i].ssts = 259 then begin // port in use and active
|
||||||
|
if hba^.ports[i].sig = 1 then begin //device is sata
|
||||||
|
sataStorageDevices[sataStorageDeviceCount - 1] := @hba^.ports[i];
|
||||||
|
sataStorageDeviceCount += 1;
|
||||||
|
port_rebase(i);
|
||||||
|
end;
|
||||||
|
//TODO implement other types
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
d := d shl 1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure enable_cmd(port : uint8);
|
||||||
|
begin
|
||||||
|
while (hba^.ports[port].cmd and $8000) <> 0 do begin end;
|
||||||
|
hba^.ports[port].cmd := hba^.ports[port].cmd or $0010;
|
||||||
|
hba^.ports[port].cmd := hba^.ports[port].cmd or $0001;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure disable_cmd(port : uint8);
|
||||||
|
begin
|
||||||
|
hba^.ports[port].cmd := hba^.ports[port].cmd and $0001;
|
||||||
|
while (hba^.ports[port].cmd and $4000) <> 0 do begin end;
|
||||||
|
hba^.ports[port].cmd := hba^.ports[port].cmd and $0010;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure port_rebase(port : uint8);
|
||||||
|
var
|
||||||
|
cmdHeader : PCMDHeader;
|
||||||
|
i : uint16;
|
||||||
|
begin
|
||||||
|
disable_cmd(port);
|
||||||
|
hba^.ports[port].clb := AHCI_BASE + (port shl 10);
|
||||||
|
hba^.ports[port].clbu := 0;
|
||||||
|
memset(hba^.ports[port].clb, 0, 1024);
|
||||||
|
|
||||||
|
hba^.ports[port].fb := AHCI_BASE + (32 shl 10) + (port shl 8);
|
||||||
|
hba^.ports[port].fbu := 0;
|
||||||
|
memset(hba^.ports[port].fb, 0, 256);
|
||||||
|
|
||||||
|
cmdheader := PCMDHeader(hba^.ports[port].clb);
|
||||||
|
for i:= 0 to 31 do begin
|
||||||
|
cmdHeader[i].PRDTL := 8; // no of prdt entries per cmd table
|
||||||
|
cmdheader[i].ctba := AHCI_BASE + (40 shl 10) + (port shl 13) + (i shl 8);
|
||||||
|
cmdheader[i].CTBAU := 0;
|
||||||
|
memset(cmdheader[i].ctba, 0, 256);
|
||||||
|
end;
|
||||||
|
enable_cmd(port);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function read(port : uint8; startl : uint32; starth : uint32; count : uint32; buf : PuInt32) : boolean;
|
||||||
|
var
|
||||||
|
pport : PHBA_PORT;
|
||||||
|
slot : uint32;
|
||||||
|
cmdHeader : PCMDHeader;
|
||||||
|
cmdTable : PCommand_Table;
|
||||||
|
cmdFis : PFIS_REG_H2D;
|
||||||
|
i : uint32;
|
||||||
|
spin : uint32 = 0;
|
||||||
|
begin
|
||||||
|
console.writestringln('1');
|
||||||
|
pport := @hba^.ports[port];
|
||||||
|
//new_page_at_address(uint32(pport));
|
||||||
|
pport^.istat := $ffff;
|
||||||
|
slot := find_cmd_slot(port);
|
||||||
|
if slot = -1 then exit(false);
|
||||||
|
|
||||||
|
console.writestringln('2');
|
||||||
|
cmdHeader := @pport^.clb;
|
||||||
|
//new_page_at_address(uint32(cmdHeader));
|
||||||
|
cmdHeader += slot;
|
||||||
|
cmdHeader^.w := false;
|
||||||
|
cmdHeader^.PRDTL := uint16(((count - 1) shr 4) + 1);
|
||||||
|
|
||||||
|
console.writestringln('3');
|
||||||
|
cmdTable := @cmdheader^.ctba;
|
||||||
|
//new_page_at_address(uint32(cmdTable));
|
||||||
|
memset(uint32(cmdTable), 0, sizeof(TCommand_Table) + (cmdheader^.PRDTL-1) * sizeof(TPRD_Entry));
|
||||||
|
|
||||||
|
console.writestringln('4');
|
||||||
|
if cmdHeader^.PRDTL > 0 then begin
|
||||||
|
for i:= 0 to cmdHeader^.PRDTL -1 do begin
|
||||||
|
cmdTable^.prdt[i].data_base_address := uint32(buf);
|
||||||
|
cmdTable^.prdt[i].data_byte_count := 8*1024-1;
|
||||||
|
cmdTable^.prdt[i].interrupt_oc := false;
|
||||||
|
buf += 4*1024;
|
||||||
|
count -= 16;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('5');
|
||||||
|
cmdTable^.prdt[cmdHeader^.PRDTL].data_base_address := uint32(buf);
|
||||||
|
cmdTable^.prdt[cmdHeader^.PRDTL].data_byte_count := (count shl 9)-1;
|
||||||
|
cmdTable^.prdt[cmdHeader^.PRDTL].interrupt_oc := false;
|
||||||
|
|
||||||
|
console.writestringln('6');
|
||||||
|
//setup command
|
||||||
|
cmdfis := @cmdTable^.cfis;
|
||||||
|
new_page_at_address(uint32(cmdfis));
|
||||||
|
cmdfis^.coc := true;
|
||||||
|
cmdfis^.command := $25;
|
||||||
|
cmdfis^.lba0 := uint8(startl);
|
||||||
|
cmdfis^.lba1 := uint8(startl shr 8);
|
||||||
|
cmdfis^.lba2 := uint8(startl shr 16);
|
||||||
|
cmdfis^.device := 1 shl 6;
|
||||||
|
cmdfis^.lba3 := uint8(startl shr 24);
|
||||||
|
cmdfis^.lba4 := uint8(starth);
|
||||||
|
cmdfis^.lba3 := uint8(starth shr 8);
|
||||||
|
cmdfis^.count_low := count and $FF;
|
||||||
|
cmdfis^.count_high:= (count shr 8) and $FF;
|
||||||
|
|
||||||
|
console.writestringln('7');
|
||||||
|
// while (pport^.tfd and $88) and spin < 1000000 do begin
|
||||||
|
// spin += 1;
|
||||||
|
// end;
|
||||||
|
|
||||||
|
console.writestringln('8');
|
||||||
|
if spin = 1000000 then begin
|
||||||
|
console.writestringln('AHCI controller: port is hung!');
|
||||||
|
read:= false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('9');
|
||||||
|
//pport^.ci := 1 shl slot;
|
||||||
|
pport^.ci := 1;
|
||||||
|
|
||||||
|
console.writestringln('10');
|
||||||
|
while true do begin
|
||||||
|
if(pport^.ci and (1 shl slot)) = (1 shl slot) then break;
|
||||||
|
if(pport^.istat and (1 shl 30)) = (1 shl 30) then begin
|
||||||
|
console.writestringln('AHCI controller: Disk read error!');
|
||||||
|
read:= false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('11');
|
||||||
|
if(pport^.istat and (1 shl 30)) = (1 shl 30) then begin
|
||||||
|
console.writestringln('AHCI controller: Disk read error!');
|
||||||
|
read:= false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('12');
|
||||||
|
read:= true;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function write(port : uint8; startl : uint32; starth : uint32; count : uint32; buf : PuInt32) : boolean;
|
||||||
|
var
|
||||||
|
pport : PHBA_PORT;
|
||||||
|
slot : uint32;
|
||||||
|
cmdHeader : PCMDHeader;
|
||||||
|
cmdTable : PCommand_Table;
|
||||||
|
cmdFis : PFIS_REG_H2D;
|
||||||
|
i : uint32;
|
||||||
|
spin : uint32 = 0;
|
||||||
|
begin
|
||||||
|
console.writestringln('1');
|
||||||
|
pport := @hba^.ports[port];
|
||||||
|
new_page_at_address(uint32(pport));
|
||||||
|
pport^.istat := $ffff;
|
||||||
|
slot := find_cmd_slot(port);
|
||||||
|
if slot = -1 then exit(false);
|
||||||
|
|
||||||
|
console.writestringln('2');
|
||||||
|
cmdHeader := @pport^.clb;
|
||||||
|
cmdHeader += slot;
|
||||||
|
// new_page_at_address(uint32(cmdHeader));
|
||||||
|
cmdHeader^.w := false;
|
||||||
|
cmdHeader^.PRDTL := uint16(((count - 1) shr 4) + 1);
|
||||||
|
console.writeintln(cmdHeader^.PRDTL); // different value on differnt emulators????
|
||||||
|
console.writestringln('3');
|
||||||
|
cmdTable := @cmdheader^.ctba;
|
||||||
|
// new_page_at_address(uint32(cmdTable));
|
||||||
|
// new_page_at_address(uint32(@cmdTable^.prdt));
|
||||||
|
memset(uint32(cmdTable), 0, sizeof(TCommand_Table) + (cmdheader^.PRDTL-1) * sizeof(TPRD_Entry));
|
||||||
|
|
||||||
|
console.writestringln('4');
|
||||||
|
console.writestring('PRDTL: ');
|
||||||
|
console.writeintln(cmdHeader^.PRDTL);
|
||||||
|
if cmdHeader^.PRDTL > 0 then begin
|
||||||
|
for i:= 0 to cmdHeader^.PRDTL -1 do begin
|
||||||
|
cmdTable^.prdt[i].data_base_address := uint32(buf);
|
||||||
|
cmdTable^.prdt[i].data_byte_count := 8*1024-1;
|
||||||
|
cmdTable^.prdt[i].interrupt_oc := false;
|
||||||
|
buf += 4*1024;
|
||||||
|
count -= 16;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('5');
|
||||||
|
cmdTable^.prdt[cmdHeader^.PRDTL].data_base_address := uint32(buf);
|
||||||
|
console.writestringln('5.1');
|
||||||
|
cmdTable^.prdt[cmdHeader^.PRDTL].data_byte_count := (count shl 9)-1;
|
||||||
|
console.writestringln('5.2');
|
||||||
|
cmdTable^.prdt[cmdHeader^.PRDTL].interrupt_oc := false;
|
||||||
|
|
||||||
|
console.writestringln('6');
|
||||||
|
cmdfis := @cmdTable^.cfis;
|
||||||
|
new_page_at_address(uint32(cmdfis));
|
||||||
|
cmdfis^.coc := true;
|
||||||
|
cmdfis^.command := $35;
|
||||||
|
cmdfis^.lba0 := uint8(startl);
|
||||||
|
cmdfis^.lba1 := uint8(startl shr 8);
|
||||||
|
cmdfis^.lba2 := uint8(startl shr 16);
|
||||||
|
cmdfis^.device := 1 shl 6;
|
||||||
|
cmdfis^.lba3 := uint8(startl shr 24);
|
||||||
|
cmdfis^.lba4 := uint8(starth);
|
||||||
|
cmdfis^.lba3 := uint8(starth shr 8);
|
||||||
|
cmdfis^.count_low := count and $FF;
|
||||||
|
cmdfis^.count_high:= (count shr 8) and $FF;
|
||||||
|
|
||||||
|
console.writestringln('7');
|
||||||
|
// while (pport^.tfd and $88) and spin < 1000000 do begin
|
||||||
|
// spin += 1;
|
||||||
|
// end;
|
||||||
|
|
||||||
|
console.writestringln('8');
|
||||||
|
if spin = 1000000 then begin
|
||||||
|
console.writestringln('AHCI controller: port is hung!');
|
||||||
|
write:= false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('9');
|
||||||
|
//pport^.ci := 1 shl slot;
|
||||||
|
pport^.ci := 1;
|
||||||
|
|
||||||
|
console.writestringln('10');
|
||||||
|
while true do begin
|
||||||
|
if(pport^.ci and (1 shl slot)) = (1 shl slot) then break;
|
||||||
|
if(pport^.istat and (1 shl 30)) = (1 shl 30) then begin
|
||||||
|
console.writestringln('AHCI controller: Disk write error!');
|
||||||
|
write:= false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('11');
|
||||||
|
if(pport^.istat and (1 shl 30)) = (1 shl 30) then begin
|
||||||
|
console.writestringln('AHCI controller: Disk write error!');
|
||||||
|
write:= false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
console.writestringln('12');
|
||||||
|
write:= true;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function find_cmd_slot(port : uint8) : uint32;
|
||||||
|
var
|
||||||
|
slots : uint32;
|
||||||
|
i : uint32;
|
||||||
|
begin
|
||||||
|
slots := hba^.ports[port].sact or hba^.ports[port].ci;
|
||||||
|
for i:=0 to 31 do begin
|
||||||
|
if (slots and 1) = 0 then begin
|
||||||
|
exit(i);
|
||||||
|
end;
|
||||||
|
slots := slots shr 1;
|
||||||
|
end;
|
||||||
|
console.writestringln('AHCI Controller: Unable to find free command slots!');
|
||||||
|
exit(-1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
271
src/driver/storage/ATA_OLD.pas
Normal file
271
src/driver/storage/ATA_OLD.pas
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
{ ************************************************
|
||||||
|
* Asuro
|
||||||
|
* Unit: Drivers/ATA
|
||||||
|
* Description: ATA DMA Driver
|
||||||
|
* currently a hack needs to be re-written if works
|
||||||
|
************************************************
|
||||||
|
* Author: Aaron Hance
|
||||||
|
* Contributors:
|
||||||
|
************************************************ }
|
||||||
|
unit ATA;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
util,
|
||||||
|
drivertypes,
|
||||||
|
console,
|
||||||
|
terminal,
|
||||||
|
isr76,
|
||||||
|
vmemorymanager;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
intptr = ^uint32;
|
||||||
|
|
||||||
|
ATA_Device = record
|
||||||
|
reading : boolean;
|
||||||
|
master : boolean;
|
||||||
|
primary : boolean;
|
||||||
|
currentIndex : uint16;
|
||||||
|
device_lba : uint32;
|
||||||
|
Command_Register : uint32;
|
||||||
|
Status_Register : uint32;
|
||||||
|
PRDT_Address_Reg : uint32;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Physical_Region_Descriptor = bitpacked record
|
||||||
|
empty0 : 0..1;
|
||||||
|
MRPB_Address : 1..32; // memory address
|
||||||
|
Byte_Count : 32..47; // size in bytes (0 is 64K)
|
||||||
|
empty1 : 47..63;
|
||||||
|
EOT : 63..64; // end of table
|
||||||
|
empty2 : 64..65;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ATA_Command_Buffer = bitpacked record
|
||||||
|
start_stop_bit : 0..1; // 0 stopped
|
||||||
|
read_write_bit : 3..4; // 0 read
|
||||||
|
end;
|
||||||
|
|
||||||
|
ATA_Status_Buffer = bitpacked record end;
|
||||||
|
|
||||||
|
ATA_IO_PORT = record
|
||||||
|
data : uint16;
|
||||||
|
error : uint8;
|
||||||
|
sector_count : uint8;
|
||||||
|
lba_low : uint8;
|
||||||
|
lba_mid : uint8;
|
||||||
|
lba_hi : uint8;
|
||||||
|
drive : uint8;
|
||||||
|
command : uint8;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
ports : ATA_IO_PORT;
|
||||||
|
devices : array[0..4] of ATA_Device;
|
||||||
|
PRD_Table : array[0..100] of Physical_Region_Descriptor; // up 64K r/w each, upto 8000 supported per table.
|
||||||
|
controller : TPCI_device;
|
||||||
|
|
||||||
|
procedure init(_controller : TPCI_device);
|
||||||
|
procedure read(address : uint32; data_lba : uint32; data_bytes : uint32);
|
||||||
|
procedure write(address : uint32; data_lba : uint32; data_bytes : uint32);
|
||||||
|
procedure callback(data : void);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure init(_controller : TPCI_device); //alloc, pmem; map_page vmem;
|
||||||
|
begin
|
||||||
|
console.writestringln('ATA: INIT BEGIN.');
|
||||||
|
isr76.hook(uint32(@callback));
|
||||||
|
|
||||||
|
controller := _controller;
|
||||||
|
|
||||||
|
new_page_at_address(controller.address4);
|
||||||
|
|
||||||
|
devices[0].primary := true;
|
||||||
|
devices[0].Command_Register := controller.address4;
|
||||||
|
devices[0].Status_Register := controller.address4 + 2;
|
||||||
|
devices[0].PRDT_Address_Reg := controller.address4 + 4;
|
||||||
|
|
||||||
|
ports.command := $1F7;
|
||||||
|
ports.lba_low := $1F3;
|
||||||
|
ports.lba_mid := $1F4;
|
||||||
|
ports.lba_hi := $1F5;
|
||||||
|
ports.drive := $1F6;
|
||||||
|
ports.sector_count := $F2;
|
||||||
|
console.writestringln('ATA: INIT END.');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure read(address : uint32; data_lba : uint32; data_bytes : uint32);
|
||||||
|
var
|
||||||
|
PRD : Physical_Region_Descriptor;
|
||||||
|
empty_table : array[0..100] of Physical_Region_Descriptor;
|
||||||
|
i : uint32;
|
||||||
|
ptr : intptr;
|
||||||
|
sector_count : uint8;
|
||||||
|
cb : ATA_Command_Buffer;
|
||||||
|
begin
|
||||||
|
devices[0].device_lba := data_lba;
|
||||||
|
devices[0].reading := true;
|
||||||
|
PRD_Table := empty_table;
|
||||||
|
PRD.MRPB_Address := address;
|
||||||
|
|
||||||
|
//limit
|
||||||
|
if data_bytes > 6400000 then exit;
|
||||||
|
|
||||||
|
if data_bytes < 64001 then begin
|
||||||
|
PRD.EOT := 1;
|
||||||
|
if data_bytes = 64000 then begin
|
||||||
|
PRD.Byte_Count := 0
|
||||||
|
end else begin
|
||||||
|
PRD.Byte_Count := data_bytes;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
while data_bytes > 64000 do begin
|
||||||
|
PRD.EOT := 0;
|
||||||
|
PRD.MRPB_Address := address;
|
||||||
|
PRD.Byte_Count := 0;
|
||||||
|
|
||||||
|
data_bytes := data_bytes - 64000;
|
||||||
|
address := address + 64000;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PRD.EOT := 1;
|
||||||
|
PRD.MRPB_Address := address;
|
||||||
|
PRD.Byte_Count := data_bytes;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
ptr := intptr(devices[0].PRDT_Address_Reg);
|
||||||
|
ptr^ := uint32(@PRD_Table);
|
||||||
|
|
||||||
|
ptr := intptr(devices[0].Status_Register);
|
||||||
|
ptr^ := 0;
|
||||||
|
|
||||||
|
outb(ports.drive, $A0);
|
||||||
|
outb(ports.sector_count, 125);
|
||||||
|
outb(ports.lba_low, (data_lba and $000000FF));
|
||||||
|
outb(ports.lba_mid, (data_lba and $0000FF00) SHR 8);
|
||||||
|
outb(ports.lba_hi, (data_lba and $0000FF00) SHR 16);
|
||||||
|
outb(ports.command, $C8);
|
||||||
|
devices[0].currentIndex := 1;
|
||||||
|
|
||||||
|
cb.start_stop_bit := 1;
|
||||||
|
cb.read_write_bit := 0;
|
||||||
|
|
||||||
|
ptr := intptr(devices[0].Command_Register);
|
||||||
|
ptr^ := uint8(cb);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure write(address : uint32; data_lba : uint32; data_bytes : uint32);
|
||||||
|
var
|
||||||
|
PRD : Physical_Region_Descriptor;
|
||||||
|
empty_table : array[0..100] of Physical_Region_Descriptor;
|
||||||
|
i : uint32;
|
||||||
|
ptr : intptr;
|
||||||
|
sector_count : uint8;
|
||||||
|
cb : ATA_Command_Buffer;
|
||||||
|
begin
|
||||||
|
devices[0].device_lba := data_lba;
|
||||||
|
devices[0].reading := true;
|
||||||
|
PRD_Table := empty_table;
|
||||||
|
PRD.MRPB_Address := address;
|
||||||
|
|
||||||
|
//limit
|
||||||
|
if data_bytes > 6400000 then exit;
|
||||||
|
|
||||||
|
if data_bytes < 64001 then begin
|
||||||
|
PRD.EOT := 1;
|
||||||
|
if data_bytes = 64000 then begin
|
||||||
|
PRD.Byte_Count := 0
|
||||||
|
end else begin
|
||||||
|
PRD.Byte_Count := data_bytes;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
while data_bytes > 64000 do begin
|
||||||
|
PRD.EOT := 0;
|
||||||
|
PRD.MRPB_Address := address;
|
||||||
|
PRD.Byte_Count := 0;
|
||||||
|
|
||||||
|
data_bytes := data_bytes - 64000;
|
||||||
|
address := address + 64000;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PRD.EOT := 1;
|
||||||
|
PRD.MRPB_Address := address;
|
||||||
|
PRD.Byte_Count := data_bytes;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
ptr := intptr(devices[0].PRDT_Address_Reg);
|
||||||
|
ptr^ := uint32(@PRD_Table);
|
||||||
|
|
||||||
|
ptr := intptr(devices[0].Status_Register);
|
||||||
|
ptr^ := 0;
|
||||||
|
|
||||||
|
outb(ports.drive, $A0);
|
||||||
|
outb(ports.sector_count, 125);
|
||||||
|
outb(ports.lba_low, (data_lba and $000000FF));
|
||||||
|
outb(ports.lba_mid, (data_lba and $0000FF00) SHR 8);
|
||||||
|
outb(ports.lba_hi, (data_lba and $0000FF00) SHR 16);
|
||||||
|
outb(ports.command, $CA);
|
||||||
|
devices[0].currentIndex := 1;
|
||||||
|
|
||||||
|
cb.start_stop_bit := 1;
|
||||||
|
cb.read_write_bit := 1;
|
||||||
|
|
||||||
|
ptr := intptr(devices[0].Command_Register);
|
||||||
|
ptr^ := uint8(cb);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure callback(data : void); //need r/w, is last
|
||||||
|
var
|
||||||
|
cb : ATA_Command_Buffer;
|
||||||
|
ptr : intptr;
|
||||||
|
tmp : uint16;
|
||||||
|
mode : uint8;
|
||||||
|
begin
|
||||||
|
if(PRD_Table[devices[0].currentIndex - 1].EOT = 1) then begin
|
||||||
|
//other stuff
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//if(devices[0].reading = true) then begin
|
||||||
|
if(PRD_Table[devices[0].currentIndex].EOT = 0) then begin
|
||||||
|
outb(ports.sector_count, 125);
|
||||||
|
outb(ports.lba_low, (devices[0].device_lba + (64000 * devices[0].currentIndex)) and $000000FF);
|
||||||
|
outb(ports.lba_mid, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 8);
|
||||||
|
outb(ports.lba_hi, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 16);
|
||||||
|
//outb(ports.command, $C8);
|
||||||
|
end else begin
|
||||||
|
tmp := uint16((PRD_Table[devices[0].currentIndex].Byte_Count and $FFFF) DIV 512);
|
||||||
|
outb(ports.sector_count, uint16(tmp)); // wont work if 64k
|
||||||
|
outb(ports.lba_low, (devices[0].device_lba + (64000 * devices[0].currentIndex)) and $000000FF);
|
||||||
|
outb(ports.lba_mid, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 8);
|
||||||
|
outb(ports.lba_hi, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 16);
|
||||||
|
//outb(ports.command, $C8);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if(devices[0].reading = true) then begin
|
||||||
|
outb(ports.command, $C8);
|
||||||
|
cb.start_stop_bit := 1;
|
||||||
|
cb.read_write_bit := 0;
|
||||||
|
end else begin
|
||||||
|
outb(ports.command, $CA);
|
||||||
|
cb.start_stop_bit := 1;
|
||||||
|
cb.read_write_bit := 1;
|
||||||
|
end;
|
||||||
|
ptr := intptr(devices[0].Command_Register);
|
||||||
|
ptr^ := uint8(cb);
|
||||||
|
|
||||||
|
|
||||||
|
devices[0].currentIndex := devices[0].currentIndex + 1;
|
||||||
|
//end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
Loading…
x
Reference in New Issue
Block a user