OSDev.org
https://forum.osdev.org/

Cannot setup AHCI
https://forum.osdev.org/viewtopic.php?f=1&t=57133
Page 1 of 1

Author:  KingVentrix007 [ Mon Feb 26, 2024 4:36 am ]
Post subject:  Cannot setup AHCI

Hello everyone, I am trying to add support for AHCI to my OS. But for some reason, the code hangs whenever I try to acces a vlaue of the HBA_MEM sturct, specificlly at uint32_t pi = abar->pi;
Am i supposed to map the value of bar5 to a virtual adress?

Code:
#include <stdio.h>

#include "fis.h"
#include "ahci.h"
#include "read.h"
#include "write.h"
#include "pci_io.h"
#include "isr.h"
#include "vmm.h"
uint32_t HBA_MEM_BASE_ADDRESS;
static int check_type(HBA_PORT *port);
void ahci_handler(REGISTERS *r);
void probe_port(HBA_MEM *abar);
void print_HBA_PORT(const HBA_PORT *port);
void print_HBA_MEM(const HBA_MEM *mem);
#define   SATA_SIG_ATA   0x00000101   // SATA drive
#define   SATA_SIG_ATAPI   0xEB140101   // SATAPI drive
#define   SATA_SIG_SEMB   0xC33C0101   // Enclosure management bridge
#define   SATA_SIG_PM   0x96690101   // Port multiplier

#define AHCI_DEV_NULL 0
#define AHCI_DEV_SATA 1
#define AHCI_DEV_SEMB 2
#define AHCI_DEV_PM 3
#define AHCI_DEV_SATAPI 4

#define HBA_PORT_IPM_ACTIVE 1
#define HBA_PORT_DET_PRESENT 3

int ahci_main(void) {
   printf("ACHI MAIN\n");
   uint32_t mem_port = get_ahci_abar();
   
   // HBA_MEM* hba_mem_ptr = (HBA_MEM*)(uintptr_t)();
   isr_register_interrupt_handler(IRQ_BASE+11,ahci_handler);
   // setup(hba_mem_ptr);
   uint32_t va = 0xFF56F;
   // map(va,mem_port,PAGE_PRESENT | PAGE_WRITE);
   probe_port((HBA_MEM *)mem_port);
   // printf("setup done\n");
   // hba_mem_ptr->ports[PORT_NUM].clb = 0x2000000;
   // hba_mem_ptr->ports[PORT_NUM].fb  = 0x3000000;

   // hba_mem_ptr->ports[PORT_NUM].cmd = (1 << 4);
   // printf("Pre loop\n");
   // while ((hba_mem_ptr->ports[PORT_NUM].cmd & ((1<<15))) == 0);
   // printf("Post loop\n");
   // hba_mem_ptr->ports[PORT_NUM].cmd = 1;

   // debug_HBA_MEM(hba_mem_ptr);
   // printf("Read\n");
   // // testWrite(hba_mem_ptr);
   // testRead(hba_mem_ptr);
}
void probe_port(HBA_MEM *abar)
{
    if(abar == NULL)
    {
        printf("error: probe_port failed\n");
        return;
    }
    printf("probe_port at 0x%0X\n", abar);
   // print_HBA_MEM(abar);
    // Search disk in implemented ports
    uint32_t pi = abar->pi;
    printf("PI %u\n", pi);
    int i = 0;
    while (i < 32)
    {
        if (pi & 1)
        {
            printf("%d\n", i);
            int dt = check_type(&abar->ports[i]);
            if (dt == AHCI_DEV_SATA)
            {
                printf("SATA drive found at port %d\n", i);
            }
            else if (dt == AHCI_DEV_SATAPI)
            {
                printf("SATAPI drive found at port %d\n", i);
            }
            else if (dt == AHCI_DEV_SEMB)
            {
                printf("SEMB drive found at port %d\n", i);
            }
            else if (dt == AHCI_DEV_PM)
            {
                printf("PM drive found at port %d\n", i);
            }
            else
            {
                printf("No drive found at port %d\n", i);
            }
        }

        pi >>= 1;
        i++;
    }
}


// Check device type
static int check_type(HBA_PORT *port)
{
   uint32_t ssts = port->ssts;

   uint8_t ipm = (ssts >> 8) & 0x0F;
   uint8_t det = ssts & 0x0F;

   if (det != HBA_PORT_DET_PRESENT)   // Check drive status
      return AHCI_DEV_NULL;
   if (ipm != HBA_PORT_IPM_ACTIVE)
      return AHCI_DEV_NULL;

   switch (port->sig)
   {
   case SATA_SIG_ATAPI:
      return AHCI_DEV_SATAPI;
   case SATA_SIG_SEMB:
      return AHCI_DEV_SEMB;
   case SATA_SIG_PM:
      return AHCI_DEV_PM;
   default:
      return AHCI_DEV_SATA;
   }
}
void ahci_handler(REGISTERS *r)
{
   printf("Called AHCI handler\n");
}
void print_HBA_PORT(const HBA_PORT *port) {
    printf("clb: 0x%08X\n", port->clb);
    printf("clbu: 0x%08X\n", port->clbu);
    printf("fb: 0x%08X\n", port->fb);
    printf("fbu: 0x%08X\n", port->fbu);
    printf("is: 0x%08X\n", port->is);
    printf("ie: 0x%08X\n", port->ie);
    printf("cmd: 0x%08X\n", port->cmd);
    printf("rsv0: 0x%08X\n", port->rsv0);
    printf("tfd: 0x%08X\n", port->tfd);
    printf("sig: 0x%08X\n", port->sig);
    printf("ssts: 0x%08X\n", port->ssts);
    printf("sctl: 0x%08X\n", port->sctl);
    printf("serr: 0x%08X\n", port->serr);
    printf("sact: 0x%08X\n", port->sact);
    printf("ci: 0x%08X\n", port->ci);
    printf("sntf: 0x%08X\n", port->sntf);
    printf("fbs: 0x%08X\n", port->fbs);
    for (int i = 0; i < 11; ++i) {
        printf("rsv1[%d]: 0x%08X\n", i, port->rsv1[i]);
    }
    for (int i = 0; i < 4; ++i) {
        printf("vendor[%d]: 0x%08X\n", i, port->vendor[i]);
    }
}
void print_HBA_MEM(const HBA_MEM *mem)
{
   printf("les goo\n");
    printf("cap: 0x%08X\n", mem->cap);
    printf("ghc: 0x%08X\n", mem->ghc);
    printf("is: 0x%08X\n", mem->is);
    printf("pi: 0x%08X\n", mem->pi);
    printf("vs: 0x%08X\n", mem->vs);
    printf("ccc_ctl: 0x%08X\n", mem->ccc_ctl);
    printf("ccc_pts: 0x%08X\n", mem->ccc_pts);
    printf("em_loc: 0x%08X\n", mem->em_loc);
    printf("em_ctl: 0x%08X\n", mem->em_ctl);
    printf("cap2: 0x%08X\n", mem->cap2);
    printf("bohc: 0x%08X\n", mem->bohc);
    // Print the values of vendor specific registers if needed
    for (int i = 0; i < 4; ++i)
    {
        printf("vendor[%d]: 0x%08X\n", i, mem->vendor[i]);
    }
    // Print the values of port control registers
    for (int i = 0; i < 32; ++i)
    {
        printf("Port %d:\n", i + 1);
        print_HBA_PORT(&mem->ports[i]);
    }
}


Sorry if this question is stupid.

Author:  iansjack [ Mon Feb 26, 2024 5:52 am ]
Post subject:  Re: Cannot setup AHCI

If you have enabled paging in your OS then you must create a virtual-address mapping for any memory address that you wish to access.

Author:  KingVentrix007 [ Mon Mar 04, 2024 3:00 am ]
Post subject:  Re: Cannot setup AHCI

Thank you. That was indeed the problem.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/