diff --git a/src/driver/storage/AHCI/AHCI.pas b/src/driver/storage/AHCI/AHCI.pas index 0f7d7058..6f2381f3 100644 --- a/src/driver/storage/AHCI/AHCI.pas +++ b/src/driver/storage/AHCI/AHCI.pas @@ -50,6 +50,7 @@ function send_read_dma(device : PAHCI_Device; lba : uint64; count : uint32; buff function send_write_dma(device : PAHCI_Device; lba : uint64; count : uint32; buffer : puint32) : boolean; function read_atapi(device : PAHCI_Device; lba : uint64; count : uint32; buffer : puint32) : boolean; + implementation procedure init(); @@ -113,8 +114,44 @@ begin // Clear the SERR register by writing 1s to it. port^.sata_error := $FFFFFFFF; + + start_port(port); end; +// procedure reset_port(port : PHBA_Port); +// var +// ssts, serr, timeout : uint32; +// begin +// console.writestringln('AHCI: Performing a full port reset.'); + +// port^.cmd := port^.cmd and not $1; + +// // Wait until CR (bit 15) is cleared. +// timeout := 0; +// while (port^.cmd and $8000) <> 0 do begin +// timeout := timeout + 1; +// if timeout > 1000000 then begin +// console.writestringln('AHCI: Port reset timeout.'); +// break; +// end; +// end; + +// port^.sata_ctrl := port^.sata_ctrl and $FFFF0000; +// port^.sata_ctrl := port^.sata_ctrl or $1; +// psleep(10); +// port^.sata_ctrl := port^.sata_ctrl and $FFFF0000; + +// while (port^.sata_status and $F) <> $3 do begin +// //wait for the port to be ready +// end; + +// // Clear the SERR register by writing 1s to it. +// port^.sata_error := $FFFFFFFF; + +// // start_port(port); +// end; + + { Check the ports on the controller and setup the command list, FIS, and command table } @@ -229,7 +266,6 @@ begin //reset the port reset_port(port); - start_port(port); //print sata status console.writestring('AHCI: sata status: '); @@ -383,19 +419,23 @@ begin console.writestringln(''); - buffer := puint32(kalloc(512)); - memset(uint32(buffer), 0, 512); + buffer := puint32(kalloc(2048)); + memset(uint32(buffer), 0, 2048); //send a read DMA command to the device if isATAPI then begin - read_atapi(device, 16, 512, buffer); + read_atapi(device, 0, 2048, buffer); end else begin - send_read_dma(device, 10, 512, buffer); + memset(uint32(buffer), $77, 2048); + send_write_dma(device, 22, 512, buffer); + memset(uint32(buffer), 0, 2048); + + send_read_dma(device, 22, 512, buffer); end; //print the buffer for i:=0 to 63 do begin - console.writehex(uint32(buffer[i])); + console.writehex(puInt8(buffer)[i]); console.writestring(' '); end; console.writestringln(''); @@ -536,7 +576,6 @@ begin console.writestringln('AHCI: Sending read DMA command'); reset_port(device^.port); - start_port(device^.port); //prdt count is 22 bits prdt_count := (count div 4194304) + 1; @@ -647,7 +686,6 @@ begin console.writestringln('AHCI: Sending write DMA command'); reset_port(device^.port); - start_port(device^.port); //prdt count is 22 bits prdt_count := (count div 4194304) + 1; @@ -688,6 +726,8 @@ begin fis^.command := ATA_CMD_WRITE_DMA_EXT; fis^.device := $40; // LBA mode 48? + count:= count div 512; + fis^.lba0 := lba and $FF; fis^.lba1 := ( lba shr 8) and $FF; @@ -764,7 +804,6 @@ begin console.writestringln('AHCI: Sending read ATAPI command'); reset_port(device^.port); - start_port(device^.port); //prdt count is 22 bits prdt_count := (count div 4194304) + 1; @@ -781,12 +820,13 @@ begin cmd_header^.wrt := 0; cmd_header^.prdtl := 1; cmd_header^.atapi := 1; + cmd_header^.clear_busy := 1; // Setup the command table (using slot 0) cmd_table := PHBA_CMD_TABLE(uint32(device^.command_table) + (slot * sizeof(THBA_CMD_TABLE))); cmd_table^.prdt[0].dba := vtop(uint32(buffer)); - cmd_table^.prdt[0].dbc := 512 - 1; // 512 bytes (0-based count + cmd_table^.prdt[0].dbc := 2048 - 1; // 512 bytes (0-based count cmd_table^.prdt[0].int := 1; // Interrupt on completion // Construct the Command FIS in the command table's CFIS area @@ -795,7 +835,7 @@ begin fis^.fis_type := uint8(FIS_TYPE_REG_H2D); fis^.c := $1; fis^.command := ATA_CMD_PACKET; - fis^.device := $A0; // LBA mode 48? + fis^.device := $A0; fis^.featurel := fis^.featurel or 1; //setting both of these might not work on real hardware fis^.featurel := fis^.featurel or (1 shl 2); diff --git a/src/driver/storage/AHCIold.pas b/src/driver/storage/AHCIold.pas deleted file mode 100644 index c100c5a7..00000000 --- a/src/driver/storage/AHCIold.pas +++ /dev/null @@ -1,296 +0,0 @@ -// // Copyright 2021 Aaron Hance -// // -// // Licensed under the Apache License, Version 2.0 (the "License"); -// // you may not use this file except in compliance with the License. -// // You may obtain a copy of the License at -// // -// // http://www.apache.org/licenses/LICENSE-2.0 -// // -// // Unless required by applicable law or agreed to in writing, software -// // distributed under the License is distributed on an "AS IS" BASIS, -// // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// // See the License for the specific language governing permissions and -// // limitations under the License. - -// { -// Drivers->Storage->AHCI - AHCI SATA Driver. - -// @author(Aaron Hance ) -// } -// 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; \ No newline at end of file diff --git a/src/driver/storage/ATA_ISR.pas b/src/driver/storage/ATA_ISR.pas deleted file mode 100644 index a3bd1cb3..00000000 --- a/src/driver/storage/ATA_ISR.pas +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2021 Aaron Hance -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -{ - Drivers->Storage->ATA_ISR - Primary ATA IRQ. - - @author(Aaron Hance ) -} -unit ATA_ISR; - -interface - -uses - util, - console, - isr_types, - isrmanager, - IDT; - -procedure register(); -procedure hook(hook_method : uint32); -procedure unhook(hook_method : uint32); - -implementation - -var - Hooks : Array[1..MAX_HOOKS] of pp_hook_method; - -procedure Main(); interrupt; -var - i : integer; - -begin - CLI; - for i:=0 to MAX_HOOKS-1 do begin - if uint32(Hooks[i]) <> 0 then Hooks[i](void($00000000)); - end; - console.writestringln('Disk Operation Complete'); -end; - -procedure register(); -begin - memset(uint32(@Hooks[0]), 0, sizeof(pp_hook_method)*MAX_HOOKS); - //isrmanager.registerISR(76, @Main); - //IDT.set_gate(76, uint32(@Main), $08, ISR_RING_0); -end; - -procedure hook(hook_method : uint32); -var - i : uint32; - -begin - for i:=0 to MAX_HOOKS-1 do begin - if uint32(Hooks[i]) = hook_method then exit; - end; - for i:=0 to MAX_HOOKS-1 do begin - if uint32(Hooks[i]) = 0 then begin - Hooks[i]:= pp_hook_method(hook_method); - exit; - end; - end; -end; - -procedure unhook(hook_method : uint32); -var - i : uint32; -begin - for i:=0 to MAX_HOOKS-1 do begin - If uint32(Hooks[i]) = hook_method then Hooks[i]:= nil; - exit; - end; -end; - -end. \ No newline at end of file diff --git a/src/driver/storage/IDE.pas b/src/driver/storage/IDE.pas index 8c37be6d..e8a4825e 100644 --- a/src/driver/storage/IDE.pas +++ b/src/driver/storage/IDE.pas @@ -14,6 +14,8 @@ { Drivers->Storage->ide - IDE Driver. + + NOT FINSIHED NEEDS WORK @author(Aaron Hance ) } diff --git a/src/driver/storage/drivemanager.pas b/src/driver/storage/OLD_drivemanager.pas similarity index 100% rename from src/driver/storage/drivemanager.pas rename to src/driver/storage/OLD_drivemanager.pas diff --git a/src/driver/storage/storagemanagement.pas b/src/driver/storage/OLD_storagemanagement.pas similarity index 100% rename from src/driver/storage/storagemanagement.pas rename to src/driver/storage/OLD_storagemanagement.pas diff --git a/src/driver/storage/volumemanager.pas b/src/driver/storage/OLD_volumemanager.pas similarity index 100% rename from src/driver/storage/volumemanager.pas rename to src/driver/storage/OLD_volumemanager.pas diff --git a/src/driver/storage/atapi.pas b/src/driver/storage/atapi.pas index b294bd4f..63cf7700 100644 --- a/src/driver/storage/atapi.pas +++ b/src/driver/storage/atapi.pas @@ -1,3 +1,27 @@ +// Copyright 2021 Aaron Hance +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +{ + Drivers->Storage->ATAPI - ATAPI Driver. + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !!!!!!!!!!!!!!!!!!!!!! CURRENTLY NOT FUNCTIONAL !!!!!!!!!!!!!!!!!!!!!! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + @author(Aaron Hance ) +} + unit atapi; interface diff --git a/src/driver/storage/oldIDE.pas b/src/driver/storage/oldIDE.pas deleted file mode 100644 index dcdc2261..00000000 --- a/src/driver/storage/oldIDE.pas +++ /dev/null @@ -1,504 +0,0 @@ -{ ************************************************ - * Asuro - * Unit: Drivers/storage/IDE - * Description: IDE ATA Driver - * - ************************************************ - * Author: Aaron Hance - * Contributors: - ************************************************ } -unit IDE; - -interface - -uses - util, - drivertypes, - console, - terminal, - drivermanagement, - vmemorymanager, - lmemorymanager, - storagemanagement, - strings, - tracer, - drivemanager, - storagetypes; - -type - TPortMode = (P_READ, P_WRITE); - - TIdentResponse = array[0..255] of uint16; - - TIDE_Channel_Registers = record - base : uint16; - ctrl : uint16; - bmide : uint16; - noInter : uint8 - end; - - TIDE_Device = record - exists : boolean; - isPrimary : boolean; - isMaster : boolean; - isATAPI : boolean; - info : TIdentResponse; - end; - - TIDE_Status = bitpacked record - Busy : Boolean; - Ready : Boolean; - Fault : Boolean; - Seek : Boolean; - DRQ : Boolean; - CORR : Boolean; - IDDEX : Boolean; - ERROR : Boolean; - end; - PIDE_Status = ^TIDE_Status; - - -const - ATA_SR_BUSY = $80; //BUSY - ATA_SR_DRDY = $40; //DRIVE READY - ATA_SR_DF = $20; //DRIVE WRITE FAULT - ATA_SR_DSC = $10; //DRIVE SEEK COMPLETE - ATA_SR_DRQ = $08; //DATA REQUEST READY - ATA_SR_CORR = $04; //CORRECTED DATA - ATA_SR_IDX = $02; //INLEX - ATA_SR_ERR = $01; //ERROR - - ATA_ER_BBK = $80; //BAD SECTOR - ATA_ER_UNC = $40; //UNCORRECTABLE DATA - ATA_ER_MC = $20; //NO MEDIA - ATA_ER_IDNF = $10; //ID MARK NOT FOUND - ATA_ER_MCR = $08; //NO MEDIA - ATA_ER_ABRT = $04; //COMMAND ABORTED - ATA_ER_TK0NF = $02; //TRACK 0 NOT FOUND - ATA_ER_AMNF = $01; //NO ADDRESS MARK - - ATA_CMD_READ_PIO = $20; - ATA_CMD_READ_PIO_EXT = $24; - ATA_CMD_READ_DMA = $C8; - ATA_CMD_READ_DMA_EXT = $25; - ATA_CMD_WRITE_PIO = $30; - ATA_CMD_WRITE_PIO_EXT = $34; - ATA_CMD_WRITE_DMA = $CA; - ATA_CMD_WRITE_DMA_EXT = $35; - ATA_CMD_CACHE_FLUSH = $E7; - ATA_CMD_CACHE_FLUSH_EXT = $EA; - ATA_CMD_PACKET = $A0; - ATA_CMD_IDENTIFY_PACKET = $A1; - ATA_CMD_IDENTIFY = $EC; - - ATAPI_CMD_READ = $A8; - ATAPI_CMD_EJECT = $1B; - - ATA_IDENT_DEVICETYPE = $0; - ATA_IDENT_CYLINDERS = $2; - ATA_IDENT_HEADS = $6; - ATA_IDENT_SECOTRS = $12; - ATA_IDENT_SERIAL = $20; - ATA_IDENT_MODEL = $54; - ATA_IDENT_CAPABILITIES = $98; - ATA_IDENT_FIELDVALID = $106; - ATA_IDENT_MAX_LBA = $120; - ATA_IDENT_COMMANDSETS = $164; - ATA_IDENT_MAX_LBA_EXT = $200; - - ATA_REG_DATA = $00; - ATA_REG_ERROR = $01; - ATA_REG_FEATURES = $01; - ATA_REG_SECCOUNT = $02; - ATA_REG_LBA0 = $03; - ATA_REG_LBA1 = $04; - ATA_REG_LBA2 = $05; - ATA_REG_HDDEVSEL = $06; - ATA_REG_COMMAND = $07; - ATA_REG_STATUS = $07; - ATA_REG_SECCOUNT1 = $08; - ATA_REG_LBA3 = $09; - ATA_REG_LBA4 = $0A; - ATA_REG_LBA5 = $0B; - ATA_REG_CONTROL = $0C; - ATA_REG_ALTSTATUS = $0C; - ATA_REG_DEVADDRESS = $0D; - - ATA_DEVICE_MASTER = $A0; - ATA_DEVICE_SLAVE = $B0; - - ATA_PRIMARY_BASE = $1F0; - -var - controller : PPCI_Device; - - bar0 : uint32; - bar1 : uint32; - bar4 : uint32; - - IDEDevices : array[0..3] of TIDE_Device; - - buffer : Puint32; - -procedure init(); -function load(ptr : void) : boolean; -function identify_device(bus : uint8; device : uint8) : TIdentResponse; - -// 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 - -procedure dread(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : puint32); -procedure dwrite(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : puint32); - -implementation - -function port_read(register : uint8) : uint8; -begin - port_read:= inb(ATA_PRIMARY_BASE + register); -end; - -procedure port_write(register : uint8; data : uint8); -var - i : uint8; -begin - outb(ATA_PRIMARY_BASE + register, data); - util.psleep(1); - if register = ATA_REG_COMMAND then begin - for i:= 0 to 5 do begin - port_read(ATA_REG_STATUS); - end; - end; -end; - -procedure no_interrupt(device : uint8); -begin - outb($3F6, inb($3f6) or (1 shl 1)); -end; - -procedure device_select(device : uint8); -begin - outb($1F6, device); //TODO clean -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; - - 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 - push_trace('IDE.Identify_Device'); - device_select(device); - no_interrupt(device); - port_write(ATA_REG_CONTROL, 0); - - console.writestringln('[IDE] (IDENTIFY_DEVICE) CHECK FLOATING BUS'); - - //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); - - console.writestringln('[IDE] (IDENTIFY_DEVICE) SEND IDENTIFY COMMAND'); - - port_write(ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - console.writestringln('[IDE] (IDENTIFY_DEVICE) WAIT FOR DRIVE TO BE READY'); - - //check if drive is present - status := port_read(ATA_REG_COMMAND); - if status = $00 then exit; - - console.writestringln('[IDE] (IDENTIFY_DEVICE) WAIT FOR DRIVE TO BE READY'); - - if not is_ready() then exit; - - console.writestringln('[IDE] (IDENTIFY_DEVICE) READ IDENTIFY RESPONSE'); - - for i:=0 to 255 do begin - console.writeint(i); - identResponse[i] := inw(ATA_PRIMARY_BASE + ATA_REG_DATA); - end; - - console.writestringln('[IDE] (IDENTIFY_DEVICE) IDENTIFY RESPONSE RECEIVED'); - - identify_device := identResponse; -end; - -procedure init(); -var - devID : TDeviceIdentifier; -begin - push_trace('ide.init'); - console.writestringln('[IDE] (INIT) BEGIN'); - devID.bus:= biPCI; - devID.id0:= idANY; - devID.id1:= $00000001; - devID.id2:= $00000001; - devID.id3:= idANY; - devID.id4:= idANY; - devID.ex:= nil; - drivermanagement.register_driver('IDE ATA Driver', @devID, @load); - console.writestringln('[IDE] (INIT) END'); -end; - -function load(ptr : void) : boolean; -var - controller : PPCI_Device; - masterDevice : TStorage_Device; - slaveDevice : TStorage_Device; - buffer : puint8; - i : uint8; - test : PStorage_device; - tbuf : puint8; -begin - push_trace('ide.load'); - console.writestringln('[IDE] (LOAD) BEGIN'); - controller := PPCI_Device(ptr); - - console.writestringln('[IDE] (INIT) CHECK FLOATING BUS'); - //check if bus is floating and identify device - if inb($1F7) <> $FF then begin - //outb($3F6, inb($3f6) or (1 shl 1)); // disable interrupts - IDEDevices[0].isMaster:= true; - IDEDevices[0].info := identify_device(0, ATA_DEVICE_MASTER); -e - mastrDevice.controller := ControllerIDE; - masterDevice.controllerId0:= 0; - masterDevice.maxSectorCount:= (IDEDevices[0].info[60] or (IDEDevices[0].info[61] shl 16) ); //LBA28 SATA - - if IDEDevices[0].info[1] = 0 then begin - console.writestringln('[IDE] (INIT) ERROR: DEVICE IDENT FAILED!'); - exit; - end; - - // masterDevice.hpc:= uint32(IDEDevices[0].info[3] DIV IDEDevices[0].info[1]); //TODO wtf is hpc - - masterDevice.sectorSize:= 512; - if masterDevice.maxSectorCount <> 0 then begin - IDEDevices[0].exists:= true; - masterDevice.readCallback:= @dread; - masterDevice.writeCallback:= @dwrite; - // storagemanagement.register_device(@masterDevice); - drivemanager.register_device(@masterDevice); - end; - - end; - - // buffer:= puint8(kalloc(512)); - // buffer[0] := 1; - // buffer[1] := 2; - // buffer[2] := 3; - // buffer[3] := 4; - // buffer[4] := 5; - // buffer[5] := 6; - // writePIO28(0, 3, buffer); - // writePIO28(0, 3, buffer); - // writePIO28(0, 3, buffer); - // writePIO28(0, 4, buffer); - // writePIO28(0, 5, buffer); - // writePIO28(0, 5, buffer); - // writePIO28(0, 5, buffer); - // psleep(1000); - // writePIO28(0, 5, buffer); - // writePIO28(0, 5, buffer); - // writePIO28(0, 5, buffer); - // kfree(puint32(buffer)); - - console.writestringln('[IDE] (LOAD) END'); - - //read first 16 bytes of disk - tbuf:= puint8(kalloc(512)); - - //set buffer to 1F1F repeating - for i:=0 to 200 do begin - tbuf[i] := 31; - end; - - //write buffer to disk - writePIO28(0, 0, tbuf); - - memset(uint32(tbuf), 0, 512); - readPIO28(0, 0, puint8(tbuf)); - console.writestringln('[IDE] (INIT) READ FIRST 4 BYTES OF DISK'); - console.writehexln(tbuf[0]); - console.writehexln(tbuf[1]); - console.writehexln(tbuf[2]); - console.writehexln(tbuf[3]); - kfree(puint32(tbuf)); - - - -end; - -procedure readPIO28(drive : uint8; LBA : uint32; buffer : puint8); -var - status : uint8; - i: uint16; - device: uint8; - data: uint16; -begin - push_trace('IDE.readPIO28'); - - if not validate_28bit_address(LBA) then begin - console.writestringln('IDE (writePIO28) ERROR: Invalid LBA!'); - end; - - // push_trace('IDE.readPIO28.2'); - - //Add last 4 bits of LBA to device port - if IDEDevices[drive].isMaster then begin - device:= ATA_DEVICE_MASTER; - device_select($E0 or ((LBA and $0F000000) shr 24)); //LBA primary master - end - else begin - device:= ATA_DEVICE_SLAVE; - device_select($F0 or ((LBA and $0F000000) shr 24)); //LBA primary slave - end; - - // push_trace('IDE.readPIO28.3'); - - no_interrupt(device); - port_write(ATA_REG_ERROR, 0); - - //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); - - // push_trace('IDE.readPIO28.4'); - - //send read command - port_write(ATA_REG_COMMAND, ATA_CMD_READ_PIO); - if not is_ready() then exit; - - i:=0; - while i < 512 do begin - // if not is_ready() then exit; - - data:= inw(ATA_PRIMARY_BASE + ATA_REG_DATA); - - buffer[i+1] := uint8($00ff and (data shr 8)); - buffer[i] := uint8($00ff and data); - - i:= i + 2; - - if not is_ready() then exit; - end; - - // push_trace('IDE.readPIO28.5'); -end; - -procedure writePIO28(drive : uint8; LBA : uint32; buffer : puint8); -var - status : uint8; - i: uint16; - device: uint8; -begin - push_trace('IDE.WritePIO28'); - if not validate_28bit_address(LBA) then begin - console.writestringln('IDE (writePIO28) ERROR: Invalid LBA!'); - end; - - console.writeintln(uint32(drive)); - console.writeintln(LBA); - - //Add last 4 bits of LBA to device port - if IDEDevices[drive].isMaster then begin - device:= ATA_DEVICE_MASTER; - device_select($E0 or ((LBA and $0F000000) shr 24)); //LBA primary master - end - else begin - device:= ATA_DEVICE_SLAVE; - device_select($F0 or ((LBA and $0F000000) shr 24)); //LBA primary slave - end; - - // no_interrupt(device); - - port_write(ATA_REG_ERROR, 0); - port_write(ATA_REG_CONTROL, 0); - - // check if bus is floating - status := port_read(ATA_REG_COMMAND); - if status = $FF then exit; - - //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); - - //send write command - port_write(ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - //write data - i:=0; - while i < 512 do begin - outw(ATA_PRIMARY_BASE + ATA_REG_DATA, uint16(buffer[i] or (buffer[i+1] shl 8))); - i:= i + 2; - end; - - //flush drive cache - psleep(1); - port_write(ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH); - psleep(1); - if not is_ready() then exit; -end; - -procedure dread(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32); -var - i : uint16; -begin - push_trace('IDE.dread'); - for i:=0 to sectorCount-1 do begin - readPIO28(device^.controllerId0, LBA + i, puint8(@buffer[512*i])); - psleep(100) - end; -end; - -procedure dwrite(device : PStorage_device; LBA : uint32; sectorCount : uint32; buffer : Puint32); -var - i : uint16; -begin - for i:=0 to sectorCount-1 do begin - writePIO28(device^.controllerId0, LBA + i, puint8(@buffer[512*i])); - psleep(100) - end; - // writePIO28(device^.controllerId0, LBA, puint8(buffer)); -end; - -end. \ No newline at end of file