From 6a3ebf1387801ad6346c9b3430c7d22ca9bc098f Mon Sep 17 00:00:00 2001
From: Aaron <ah@aaronhance.me>
Date: Sat, 15 Mar 2025 20:13:33 +0000
Subject: [PATCH] ahci progress

---
 compile_sources.sh                    |   2 +-
 src/driver/storage/AHCI.pas           | 296 --------------------------
 src/driver/storage/AHCI/AHCI.pas      | 127 ++++++++++-
 src/driver/storage/AHCI/AHCITypes.pas | 124 ++++++-----
 src/driver/storage/AHCIold.pas        | 296 ++++++++++++++++++++++++++
 src/kernel.pas                        |   6 +-
 src/lmemorymanager.pas                |   6 +
 7 files changed, 503 insertions(+), 354 deletions(-)
 delete mode 100644 src/driver/storage/AHCI.pas
 create mode 100644 src/driver/storage/AHCIold.pas

diff --git a/compile_sources.sh b/compile_sources.sh
index c8f6db32..a15cf3eb 100644
--- a/compile_sources.sh
+++ b/compile_sources.sh
@@ -4,4 +4,4 @@ echo "======================="
 echo " "
 echo "Compiling FPC Sources..."
 echo " "
-fpc -Aelf -gw -n -va -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* src/kernel.pas
\ No newline at end of file
+fpc -Aelf -gw -n -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/storage/* -Fusrc/driver/storage/AHCI/* -Fusrc/driver/* -Fusrc/driver/net/*  src/kernel.pas
\ No newline at end of file
diff --git a/src/driver/storage/AHCI.pas b/src/driver/storage/AHCI.pas
deleted file mode 100644
index 3cac039f..00000000
--- a/src/driver/storage/AHCI.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 <ah@aaronhance.me>)
-}
-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/AHCI/AHCI.pas b/src/driver/storage/AHCI/AHCI.pas
index c008d9e8..ab62ac25 100644
--- a/src/driver/storage/AHCI/AHCI.pas
+++ b/src/driver/storage/AHCI/AHCI.pas
@@ -34,10 +34,11 @@ uses
     lists;
 
 var
-    ahciControllers : PDLList;
+    ahciControllers : PDList;
+    page_base : puint32;
 
 procedure init();
-procedure load();
+function load(ptr : void) : boolean;
 
 implementation
 
@@ -57,19 +58,117 @@ begin
     //TODO check IDE devices in ide for sata devices
 end;
 
+procedure stop_port(port : PHBA_Port);
+begin
+    port^.cmd_sts := port^.cmd_sts and not $1; ///maybe also bit 4
+    while (port^.cmd_sts and $1) = 1 do begin
+        //wait for the port to stop
+    end;
+end;
+
+procedure start_port(port : PHBA_Port);
+begin
+    port^.cmd_sts := port^.cmd_sts or $1; ///maybe also bit 4
+    while (port^.cmd_sts and $1) = 0 do begin
+        //wait for the port to start
+    end;
+end;
+
+
+{
+    Check the ports on the controller and setup the command list, FIS, and command table
+}
 procedure check_ports(controller : PAHCI_Controller);
 var
     i : uint32;
     port : PHBA_Port;
+    device : PAHCI_Device;
+    cmd_list_base : puint32;
+    fis_base : puint32;
+    cmd_table_base : puint32;
+    cmd_header : PHBA_CMD_HEADER;
 begin
+
+    for i:=0 to 31 do begin
+        if (controller^.mio^.port_implemented shr i) = 1 then begin
+            port := @controller^.mio^.ports[i];
+            console.writestring('AHCI: Port ');
+            console.writeint(i);
+            console.writestring(' implemented on controller ');
+            console.writehexln(uint32(controller^.pci_device^.address5));
+
+            //NEEED TO STOP the port before doing anything
+
+            device := PAHCI_Device(DL_Add(controller^.devices));
+            device^.port := port;
+
+            //allocate memory for the command list and ensure it is aligned to 1024 bytes
+            cmd_list_base := kalloc(sizeof(THBA_CMD_HEADER) * 64);
+            cmd_list_base := puint32((uint32(cmd_list_base) + 1023) and $FFFFFC00);
+
+            //allocate memory for the FIS and ensure it is aligned to 256 bytes
+            fis_base := kalloc(sizeof(THBA_FIS) * 8);
+            fis_base := puint32((uint32(fis_base) + 255) and $FFFFFF00);
+
+            //set the command list base address
+            port^.cmd_list_base := uint32(vtop(cmd_list_base)); //todo set virtual address in device
+            port^.cmd_list_base_upper := 0;
+
+            memset(uint32(cmd_list_base), 0, sizeof(THBA_CMD_HEADER));
+
+            device^.command_list := PHBA_CMD_HEADER(cmd_list_base);
+
+            //set the FIS base address
+            port^.fis_base := uint32(vtop(fis_base));
+            port^.fis_base_upper := 0;
+
+            memset(uint32(fis_base), 0, sizeof(THBA_FIS));
+
+            device^.fis := PHBA_FIS(fis_base);
+            //todo check how many simultaneous commands are supported
+
+            //allocate memory for the command table and ensure it is aligned to 1024 bytes
+            cmd_table_base := kalloc(sizeof(THBA_CMD_TABLE) * 64);
+            cmd_table_base := puint32((uint32(cmd_table_base) + 1023) and $FFFFFC00);
+
+            device^.command_table := PHBA_CMD_TABLE(cmd_table_base);
+
+            //set the command table base address and setup command table
+            for i:=0 to 31 do begin
+                //set command header locations
+                command_header := PHBA_CMD_HEADER(uint32(cmd_list_base) + (i * sizeof(THBA_CMD_HEADER)));
+
+                command_header^.prdtl := 32;
+                //TODO do i need to set prdbc byte count here?
+                command_header^.cmd_table_base := uint32(vtop(cmd_table_base) + (i * sizeof(THBA_CMD_TABLE));
+                command_header^.cmd_table_base_upper := 0;
+                memset(uint32(cmd_table_base) + (i * sizeof(THBA_CMD_TABLE)), 0, sizeof(THBA_CMD_TABLE));
+            end;
+
+            start_port(port);
+        end;
+    end;
+
+
 end;
 
-procedure load(ptr : void);
+// procedure identify_device(controller : PAHCI_Controller; port : uint32);
+// var
+//     fis : PFIS_REG_H2D;
+//     cmd : uint32;
+//     i : uint32;
+// begin
+// end;
+
+function load(ptr : void) : boolean;
 var 
     device : PPCI_Device;
     controller : PAHCI_Controller;
     i : uint32;
     base : PHBA_Memory;
+    cmd_list_base : puint32;
+    fis_base : puint32;
+    cmd_table_base : puint32;
 begin
     console.writestringln('AHCI: initilizing a new controller');
 
@@ -80,19 +179,32 @@ begin
 
     device := PPCI_Device(ptr);
 
-    controller := DL_Add(ahciControllers);
-    controller^.device := device;
+    controller := PAHCI_Controller(DL_Add(ahciControllers));
+    controller^.devices := DL_New(SizeOf(TAHCI_Device));
 
-    base: PHBA_Memory(kpalloc(device^.address5)); // get the base address of the controller
+    controller^.pci_device := PPCI_Device(device);
+
+
+    //get the base address of the controller
+    page_base := kpalloc(device^.address5); // TODO MEM memory manager need to be improved
+    base := PHBA_Memory(device^.address5);
     controller^.mio := base;
 
+    console.writestring('AHCI: Controller at: ');
+    console.writehexln(device^.address5);
+    console.writehexln(uint32(page_base));
+
     //enable AHCI mode, TODO check if is not already in AHCI mode and enable it, also perhaps remove if loaded as IDE
-    base^.ghc := base^.ghc or AHCI_CONTROLLER_MODE;
+    base^.global_ctrl := base^.global_ctrl or AHCI_CONTROLLER_MODE;
 
     //clear any pending interrupts
     base^.int_status := $FFFFFFFF;
 
 
+    
+
+    check_ports(controller);
+
 
 
 
@@ -109,4 +221,5 @@ begin
 end;
 
 
+
 end.
diff --git a/src/driver/storage/AHCI/AHCITypes.pas b/src/driver/storage/AHCI/AHCITypes.pas
index 3be083b2..dfce51c5 100644
--- a/src/driver/storage/AHCI/AHCITypes.pas
+++ b/src/driver/storage/AHCI/AHCITypes.pas
@@ -26,11 +26,18 @@ uses
     drivermanagement,
     lmemorymanager,
     console,
-    vmemorymanager;
+    vmemorymanager,
+    idetypes,
+    lists;
 
 const
     AHCI_CONTROLLER_MODE = $80000000;
 
+    CMD_LIST_ALIGN = 1024;
+    CMD_TBL_ALIGN = 128;
+
+    NUM_CMD_ENTRIES = 32;
+
     //device type signatures
     SATA_SIG_ATA = $00000101;
     SATA_SIG_ATAPI = $EB140101;
@@ -75,17 +82,19 @@ type
         rsv1: array[0..10] of uint32;
     end;
 
+    PHBA_Port = ^THBA_Port;
+
     { 
         AHCI Host Bus Adapter (HBA) Memory-Mapped Register Interface
-        This structure is used to access the AHCI HBA's memory-mapped registers. 
-        The AHCI HBA's memory-mapped registers are used to configure the HBA and
-        to issue commands to the SATA devices connected to the HBA.
+        This structure is used to access the AHCI's memory-mapped registers.
+        The AHCI's memory-mapped registers are used to configure the HBA and to
+        issue commands to the SATA devices connected to the HBA.
     }
     THBA_Memory = bitpacked record 
         capabilites: uint32;    // Host Capabilities
         global_ctrl: uint32;    // Global Host Control
         int_status: uint32;     // Interrupt Status
-        ports_implemented: uint32; // Ports Implemented
+        ports_implimented: uint32;// Ports Implemented 
         version: uint32;        // Version
         ccc_control: uint32;    // Command Completion Coalescing Control
         ccc_ports: uint32;      // Command Completion Coalescing Ports
@@ -93,7 +102,7 @@ type
         em_control: uint32;     // Enclosure Management Control
         capabilites2: uint32;   // Host Capabilities Extended
         bohc: uint32;           // BIOS/OS Handoff Control and Status
-        rsv0: array[0..0x210] of boolean;
+        rsv0: array[0..$210] of boolean;
         ports: array[0..31] of THBA_Port;
     end;
 
@@ -102,26 +111,26 @@ type
     { 
         AHCI Host Bus Adapter (HBA) FIS (Frame Information Structure) Interface
         This structure is used to access the AHCI HBA's FIS (Frame Information Structure)
-        memory-mapped registers. The AHCI HBA's FIS memory-mapped registers are used to
-        configure the HBA and to issue commands to the SATA devices connected to the HBA.
+        memory-mapped registers. 
     }
     THBA_FIS = bitpacked record 
-        dsfis: array[0..0x1F] of uint32; // DMA Setup FIS
-        rsv0: array[0..0x1F] of uint32;
-        psfis: array[0..0x1F] of uint32; // PIO Setup FIS
-        rsv1: array[0..0x1F] of uint32;
-        rfis: array[0..0x1F] of uint32;  // D2H Register FIS
-        rsv2: array[0..0x1F] of uint32;
-        sdbfis: array[0..0xF] of uint32; // Set Device Bits FIS
-        ufis: array[0..0x1F] of uint32;  // Unknown FIS
-        rsv3: array[0..0x67] of uint32;
+        dsfis: array[0..$1F] of uint32; // DMA Setup FIS
+        rsv0: array[0..$1F] of uint32;
+        psfis: array[0..$1F] of uint32; // PIO Setup FIS
+        rsv1: array[0..$1F] of uint32;
+        rfis: array[0..$1F] of uint32;  // D2H Register FIS
+        rsv2: array[0..$1F] of uint32;
+        sdbfis: array[0..$F] of uint32; // Set Device Bits FIS
+        ufis: array[0..$1F] of uint32;  // Unknown FIS
+        rsv3: array[0..$67] of uint32;
     end;
 
+    PHBA_FIS = ^THBA_FIS;
+
     { 
         AHCI Host Bus Adapter (HBA) Command Header Interface
         This structure is used to access the AHCI HBA's Command Header memory-mapped
-        registers. The AHCI HBA's Command Header memory-mapped registers are used to
-        configure the HBA and to issue commands to the SATA devices connected to the HBA.
+        registers.
     }
     THBA_CMD_HEADER = bitpacked record 
         cmd_fis_length: uint8;   // Command FIS Length
@@ -139,6 +148,8 @@ type
         rsv0: array[0..4] of uint32;
     end;
 
+    PHBA_CMD_HEADER = ^THBA_CMD_HEADER;
+
     { 
         AHCI Host Bus Adapter (HBA) Command Table Interface
         This structure is used to access the AHCI HBA's Command Table memory-mapped
@@ -147,15 +158,19 @@ type
     }
     THBA_CMD_TABLE = bitpacked record 
         cmd_fis: THBA_FIS;       // Command FIS
-        acmd: array[0..0x1F] of uint8; // ATAPI Command
-        rsv0: array[0..0x30] of uint8;
+        acmd: array[0..$1F] of uint8; // ATAPI Command
+        rsv0: array[0..$30] of uint8;
     end;
 
+    PHBA_CMD_TABLE = ^THBA_CMD_TABLE;
+
+    TCMD_LIST = array[0..255] of THBA_CMD_HEADER;
+    PCMD_LIST = ^TCMD_LIST;
+
     { 
         AHCI Host Bus Adapter (HBA) Command Table Interface
         This structure is used to access the AHCI HBA's Command Table memory-mapped
-        registers. The AHCI HBA's Command Table memory-mapped registers are used to
-        configure the HBA and to issue commands to the SATA devices connected to the HBA.
+        registers. 
     }
     THBA_PRD = bitpacked record 
         dba: uint32;             // Data Base Address
@@ -168,24 +183,22 @@ type
     { 
         AHCI Host Bus Adapter (HBA) Command Table Interface
         This structure is used to access the AHCI HBA's Command Table memory-mapped
-        registers. The AHCI HBA's Command Table memory-mapped registers are used to
-        configure the HBA and to issue commands to the SATA devices connected to the HBA.
+        registers. 
     }
     THBA_CMD = bitpacked record 
         header: THBA_CMD_HEADER; // Command Header
         table: THBA_CMD_TABLE;   // Command Table
-        prd: array[0..0x7] of THBA_PRD; // Physical Region Descriptor Table
+        prd: array[0..31] of THBA_PRD; // Physical Region Descriptor Table
     end;
 
     { 
         AHCI Host Bus Adapter (HBA) Command Table Interface
         This structure is used to access the AHCI HBA's Command Table memory-mapped
-        registers. The AHCI HBA's Command Table memory-mapped registers are used to
-        configure the HBA and to issue commands to the SATA devices connected to the HBA.
+        registers. 
     }
     THBA = bitpacked record 
         memory: THBA_Memory; // HBA Memory
-        cmd: array[0..0x7FF] of THBA_CMD; // Command List
+        cmd: array[0..$7FF] of THBA_CMD; // Command List
     end;
 
     PHBA = ^THBA;
@@ -204,20 +217,35 @@ type
         PM
     );
 
+    {
+        AHCI device reference
+    }
+    TAHCI_Device = bitpacked record
+        port : PHBA_Port;
+        device_type : TDeviceType;
+        ata_info : TIdentResponse;
+        command_list : PHBA_CMD_HEADER;
+        fis : PHBA_FIS;
+        command_table : PHBA_CMD_TABLE;
+    end;
+
+    PAHCI_Device = ^TAHCI_Device;
+
     {
         controller reference
     }
     TAHCI_Controller = bitpacked record
         pci_device : PPCI_Device;
         mio: PHBA_Memory;
-        devices : array[0..31] of uint8; //TODO type for devices
+        ata_info : TIdentResponse;
+        devices : PDList;
     end;
 
     PAHCI_Controller = ^TAHCI_Controller;
 
      
  function get_device_type(sig : uint32) : TDeviceType;
- function get_device_type_string(deive_type : TDeviceType) : string;
+//  function get_device_type_string(deive_type : TDeviceType) : string;
 
 implementation
 
@@ -239,23 +267,23 @@ begin
     end;
 end;
 
-function get_device_type_string(deive_type : TDeviceType) : string;
-begin
-    case deive_type of
-        SATA: begin
-            get_device_type_string := 'SATA';
-        end;
-        ATAPI: begin
-            get_device_type_string := 'ATAPI';
-        end;
-        SEMB: begin
-            get_device_type_string := 'SEMB';
-        end;
-        PM: begin
-            get_device_type_string := 'PM';
-        end;
-    end;
-end;
+// function get_device_type_string(deive_type : TDeviceType) : string;
+// begin
+//     case deive_type of
+//         SATA: begin
+//             get_device_type_string := 'SATA';
+//         end;
+//         ATAPI: begin
+//             get_device_type_string := 'ATAPI';
+//         end;
+//         SEMB: begin
+//             get_device_type_string := 'SEMB';
+//         end;
+//         PM: begin
+//             get_device_type_string := 'PM';
+//         end;
+//     end;
+// end;
 
 end.
 
diff --git a/src/driver/storage/AHCIold.pas b/src/driver/storage/AHCIold.pas
new file mode 100644
index 00000000..c100c5a7
--- /dev/null
+++ b/src/driver/storage/AHCIold.pas
@@ -0,0 +1,296 @@
+// //  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 <ah@aaronhance.me>)
+// }
+// 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/kernel.pas b/src/kernel.pas
index 2bcd88b7..bc802a61 100644
--- a/src/kernel.pas
+++ b/src/kernel.pas
@@ -57,7 +57,8 @@ uses
      base64,
      rand,
      terminal,
-     hashmap, vfs;
+     hashmap, vfs,
+     AHCI;
  
 procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
  
@@ -228,7 +229,8 @@ begin
      mouse.init();
      testdriver.init();
      E1000.init();
-     IDE.init();
+    //  IDE.init();
+     AHCI.init();
      console.outputln('KERNEL', 'DEVICE DRIVERS: INIT END.');
 
      { Bus Drivers }
diff --git a/src/lmemorymanager.pas b/src/lmemorymanager.pas
index 7339e6e8..534a13f0 100644
--- a/src/lmemorymanager.pas
+++ b/src/lmemorymanager.pas
@@ -57,6 +57,7 @@ var
 
 procedure init;
 function kalloc(size : uint32) : void;
+function kalloc(size : uint32; isPersistent : boolean) : void;
 function klalloc(size : uint32) : void;
 procedure klfree(size : uint32); //Todo ??? Profit?
 function kpalloc(address : uint32) : void;
@@ -217,6 +218,11 @@ begin
     //pop_trace;
 end;
 
+function kalloc(size : uint32; isPersistent : boolean) : void;
+begin
+    kalloc:= kalloc(size);
+end;
+
 procedure kfree(area : void);
 var
     hp : PHeapPage;