Page 1 of 1

Cannot setup AHCI

Posted: Mon Feb 26, 2024 4:36 am
by KingVentrix007
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: Select all

#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.

Re: Cannot setup AHCI

Posted: Mon Feb 26, 2024 5:52 am
by iansjack
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.

Re: Cannot setup AHCI

Posted: Mon Mar 04, 2024 3:00 am
by KingVentrix007
Thank you. That was indeed the problem.