CS350 COS
COS
Loading...
Searching...
No Matches
ahci.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/kassert.h>
#include <sys/kdebug.h>
#include <sys/kmem.h>
#include <sys/pci.h>
#include <sys/sga.h>
#include "ata.h"
#include "sata.h"
Include dependency graph for ahci.c:

Go to the source code of this file.

Data Structures

struct  AHCIDevice
 
struct  AHCIHostControl
 
struct  AHCIPort
 
struct  AHCICommandHeader
 
struct  AHCICommandList
 
struct  AHCIPRDT
 
struct  AHCICommandTable
 
struct  AHCIRecvFIS
 
struct  AHCI
 

Macros

#define AHCI_CAP_S64A   0x80000000 /* Supports 64-bit Addressing */
 
#define AHCI_CAP_SNCQ   0x40000000 /* Supports NCQ */
 
#define AHCI_GHC_AE   0x80000000
 
#define AHCI_GHC_IE   0x00000002
 
#define AHCI_GHC_HR   0x00000001
 
#define AHCIPORT_CMD_ICCMASK   0xF0000000 /* Interface Communication Control */
 
#define AHCIPORT_CMD_ICCSLUMBER   0x60000000 /* ICC Slumber */
 
#define AHCIPORT_CMD_ICCPARTIAL   0x20000000 /* ICC Partial */
 
#define AHCIPORT_CMD_ICCACTIVE   0x10000000 /* ICC Active */
 
#define AHCIPORT_CMD_ICCIDLE   0x00000000 /* ICC Idle */
 
#define AHCIPORT_CMD_ASP   0x08000000 /* Aggressive Slumber/Partial */
 
#define AHCIPORT_CMD_ALPE   0x04000000 /* Aggressive Link PM Enable */
 
#define AHCIPORT_CMD_DLAE   0x02000000 /* Drive LED on ATAPI Enable */
 
#define AHCIPORT_CMD_ATAPI   0x01000000 /* Device is ATAPI */
 
#define AHCIPORT_CMD_CPD   0x00100000 /* Cold Presence Detection */
 
#define AHCIPORT_CMD_ISP   0x00080000 /* Interlock Switch Attached */
 
#define AHCIPORT_CMD_HPCP   0x00040000 /* Hot Plug Capable Port */
 
#define AHCIPORT_CMD_PMA   0x00020000 /* Port Multiplier Attached */
 
#define AHCIPORT_CMD_CPS   0x00010000 /* Cold Presence State */
 
#define AHCIPORT_CMD_CR   0x00008000 /* Command List Running */
 
#define AHCIPORT_CMD_FR   0x00004000 /* FIS Receive Running */
 
#define AHCIPORT_CMD_ISS   0x00002000 /* Interlock Switch State */
 
#define AHCIPORT_CMD_FRE   0x00000010 /* FIS Receive Enable */
 
#define AHCIPORT_CMD_CLO   0x00000008 /* Command List Override */
 
#define AHCIPORT_CMD_POD   0x00000004 /* Power On Device */
 
#define AHCIPORT_CMD_SUD   0x00000002 /* Spin-Up Device */
 
#define AHCIPORT_CMD_ST   0x00000001 /* Start */
 
#define AHCIPORT_TFD_BSY   0x00000080 /* Port Busy */
 
#define AHCIPORT_TFD_DRQ   0x00000004 /* Data Transfer Requested */
 
#define AHCIPORT_TFD_ERR   0x00000001 /* Error during Transfer */
 
#define AHCIPORT_SSTS_DETMASK   0x0000000F /* Device Detection (DET) Mask */
 
#define AHCIPORT_SSTS_DETNP   0x00000000 /* DET: Not Present */
 
#define AHCIPORT_SSTS_DETNOTEST   0x00000001 /* DET: Phy not established */
 
#define AHCIPORT_SSTS_DETPE   0x00000003 /* DET: Present and Established */
 
#define AHCIPORT_SSTS_DETNE   0x00000004 /* DET: Not Enabled or in BIST mode */
 
#define AHCI_ABAR   5
 
#define AHCI_PORT_OFFSET   0x100
 
#define AHCI_PORT_LENGTH   0x80
 
#define AHCI_MAX_PORTS   8
 
#define AHCI_MAX_CMDS   32
 
#define PGSIZE   4096
 

Typedefs

typedef struct AHCIDevice AHCIDevice
 
typedef struct AHCIHostControl AHCIHostControl
 
typedef struct AHCIPort AHCIPort
 
typedef struct AHCICommandHeader AHCICommandHeader
 
typedef struct AHCICommandList AHCICommandList
 
typedef struct AHCIPRDT AHCIPRDT
 
typedef struct AHCICommandTable AHCICommandTable
 
typedef struct AHCIRecvFIS AHCIRecvFIS
 
typedef struct AHCI AHCI
 

Functions

void AHCI_Configure (PCIDevice dev)
 
void AHCI_Init (uint32_t bus, uint32_t slot, uint32_t func)
 
void AHCI_Dump (AHCI *ahci)
 
void AHCI_DumpPort (AHCI *ahci, int port)
 
uint64_t AHCI_IssueCommand (AHCI *ahci, int port, SGArray *sga, void *cfis, int len)
 
void AHCI_WaitPort (AHCI *ahci, int port)
 
void AHCI_IdentifyPort (AHCI *ahci, int port)
 
void AHCI_ResetPort (AHCI *ahci, int port)
 
void AHCI_Reset (AHCI *ahci)
 

Variables

static AHCIDevice deviceList []
 

Data Structure Documentation

◆ AHCIDevice

struct AHCIDevice

Definition at line 19 of file ahci.c.

Collaboration diagram for AHCIDevice:
[legend]
Data Fields
uint32_t device
uint32_t flags
const char * name

◆ AHCIHostControl

struct AHCIHostControl

Definition at line 32 of file ahci.c.

Collaboration diagram for AHCIHostControl:
[legend]
Data Fields
uint32_t cap
uint32_t ghc
uint32_t is
uint32_t pi
uint32_t vs

◆ AHCIPort

struct AHCIPort

Definition at line 48 of file ahci.c.

Collaboration diagram for AHCIPort:
[legend]
Data Fields
uint32_t _rsvd
uint32_t _rsvd2
uint32_t ci
uint64_t clba
uint32_t cmd
uint64_t fb
uint32_t ie
uint32_t is
uint32_t sact
uint32_t sctl
uint32_t serr
uint32_t sig
uint32_t ssts
uint32_t tfd

◆ AHCICommandHeader

struct AHCICommandHeader

Definition at line 109 of file ahci.c.

Collaboration diagram for AHCICommandHeader:
[legend]
Data Fields
uint64_t _rsvd[2]
uint32_t cmdStatus
uint64_t ctba
uint16_t flag
uint16_t prdtl

◆ AHCICommandList

struct AHCICommandList

Definition at line 118 of file ahci.c.

Collaboration diagram for AHCICommandList:
[legend]
Data Fields
AHCICommandHeader cmds[AHCI_MAX_CMDS]

◆ AHCIPRDT

struct AHCIPRDT

Definition at line 126 of file ahci.c.

Collaboration diagram for AHCIPRDT:
[legend]
Data Fields
uint32_t _rsvd
uint64_t dba
uint32_t descInfo

◆ AHCICommandTable

struct AHCICommandTable

Definition at line 139 of file ahci.c.

Collaboration diagram for AHCICommandTable:
[legend]
Data Fields
uint8_t _rsvd[32]
uint8_t acmd[32]
uint8_t cfis[64]
AHCIPRDT prdt[248]

◆ AHCIRecvFIS

struct AHCIRecvFIS

Definition at line 151 of file ahci.c.

Collaboration diagram for AHCIRecvFIS:
[legend]
Data Fields
uint8_t _rsvd0[0x4]
uint8_t _rsvd1[0xc]
uint8_t _rsvd2[0x4]
uint8_t _rsvd3[0x60]
uint8_t dsfis[0x1c]
uint8_t psfis[0x14]
uint8_t rfis[0x14]
uint8_t sdbfis[0x8]
uint8_t ufis[0x40]

◆ AHCI

struct AHCI

Definition at line 168 of file ahci.c.

Collaboration diagram for AHCI:
[legend]
Data Fields
AHCICommandList * clst[AHCI_MAX_PORTS]
AHCICommandTable * ctbl[AHCI_MAX_PORTS][AHCI_MAX_CMDS]
PCIDevice dev
AHCIHostControl * hc
AHCIPort * port[AHCI_MAX_PORTS]
AHCIRecvFIS * rfis[AHCI_MAX_PORTS]

Macro Definition Documentation

◆ AHCI_ABAR

#define AHCI_ABAR   5

Definition at line 99 of file ahci.c.

◆ AHCI_CAP_S64A

#define AHCI_CAP_S64A   0x80000000 /* Supports 64-bit Addressing */

Definition at line 41 of file ahci.c.

◆ AHCI_CAP_SNCQ

#define AHCI_CAP_SNCQ   0x40000000 /* Supports NCQ */

Definition at line 42 of file ahci.c.

◆ AHCI_GHC_AE

#define AHCI_GHC_AE   0x80000000

Definition at line 44 of file ahci.c.

◆ AHCI_GHC_HR

#define AHCI_GHC_HR   0x00000001

Definition at line 46 of file ahci.c.

◆ AHCI_GHC_IE

#define AHCI_GHC_IE   0x00000002

Definition at line 45 of file ahci.c.

◆ AHCI_MAX_CMDS

#define AHCI_MAX_CMDS   32

Definition at line 103 of file ahci.c.

◆ AHCI_MAX_PORTS

#define AHCI_MAX_PORTS   8

Definition at line 102 of file ahci.c.

◆ AHCI_PORT_LENGTH

#define AHCI_PORT_LENGTH   0x80

Definition at line 101 of file ahci.c.

◆ AHCI_PORT_OFFSET

#define AHCI_PORT_OFFSET   0x100

Definition at line 100 of file ahci.c.

◆ AHCIPORT_CMD_ALPE

#define AHCIPORT_CMD_ALPE   0x04000000 /* Aggressive Link PM Enable */

Definition at line 72 of file ahci.c.

◆ AHCIPORT_CMD_ASP

#define AHCIPORT_CMD_ASP   0x08000000 /* Aggressive Slumber/Partial */

Definition at line 71 of file ahci.c.

◆ AHCIPORT_CMD_ATAPI

#define AHCIPORT_CMD_ATAPI   0x01000000 /* Device is ATAPI */

Definition at line 74 of file ahci.c.

◆ AHCIPORT_CMD_CLO

#define AHCIPORT_CMD_CLO   0x00000008 /* Command List Override */

Definition at line 84 of file ahci.c.

◆ AHCIPORT_CMD_CPD

#define AHCIPORT_CMD_CPD   0x00100000 /* Cold Presence Detection */

Definition at line 75 of file ahci.c.

◆ AHCIPORT_CMD_CPS

#define AHCIPORT_CMD_CPS   0x00010000 /* Cold Presence State */

Definition at line 79 of file ahci.c.

◆ AHCIPORT_CMD_CR

#define AHCIPORT_CMD_CR   0x00008000 /* Command List Running */

Definition at line 80 of file ahci.c.

◆ AHCIPORT_CMD_DLAE

#define AHCIPORT_CMD_DLAE   0x02000000 /* Drive LED on ATAPI Enable */

Definition at line 73 of file ahci.c.

◆ AHCIPORT_CMD_FR

#define AHCIPORT_CMD_FR   0x00004000 /* FIS Receive Running */

Definition at line 81 of file ahci.c.

◆ AHCIPORT_CMD_FRE

#define AHCIPORT_CMD_FRE   0x00000010 /* FIS Receive Enable */

Definition at line 83 of file ahci.c.

◆ AHCIPORT_CMD_HPCP

#define AHCIPORT_CMD_HPCP   0x00040000 /* Hot Plug Capable Port */

Definition at line 77 of file ahci.c.

◆ AHCIPORT_CMD_ICCACTIVE

#define AHCIPORT_CMD_ICCACTIVE   0x10000000 /* ICC Active */

Definition at line 69 of file ahci.c.

◆ AHCIPORT_CMD_ICCIDLE

#define AHCIPORT_CMD_ICCIDLE   0x00000000 /* ICC Idle */

Definition at line 70 of file ahci.c.

◆ AHCIPORT_CMD_ICCMASK

#define AHCIPORT_CMD_ICCMASK   0xF0000000 /* Interface Communication Control */

Definition at line 66 of file ahci.c.

◆ AHCIPORT_CMD_ICCPARTIAL

#define AHCIPORT_CMD_ICCPARTIAL   0x20000000 /* ICC Partial */

Definition at line 68 of file ahci.c.

◆ AHCIPORT_CMD_ICCSLUMBER

#define AHCIPORT_CMD_ICCSLUMBER   0x60000000 /* ICC Slumber */

Definition at line 67 of file ahci.c.

◆ AHCIPORT_CMD_ISP

#define AHCIPORT_CMD_ISP   0x00080000 /* Interlock Switch Attached */

Definition at line 76 of file ahci.c.

◆ AHCIPORT_CMD_ISS

#define AHCIPORT_CMD_ISS   0x00002000 /* Interlock Switch State */

Definition at line 82 of file ahci.c.

◆ AHCIPORT_CMD_PMA

#define AHCIPORT_CMD_PMA   0x00020000 /* Port Multiplier Attached */

Definition at line 78 of file ahci.c.

◆ AHCIPORT_CMD_POD

#define AHCIPORT_CMD_POD   0x00000004 /* Power On Device */

Definition at line 85 of file ahci.c.

◆ AHCIPORT_CMD_ST

#define AHCIPORT_CMD_ST   0x00000001 /* Start */

Definition at line 87 of file ahci.c.

◆ AHCIPORT_CMD_SUD

#define AHCIPORT_CMD_SUD   0x00000002 /* Spin-Up Device */

Definition at line 86 of file ahci.c.

◆ AHCIPORT_SSTS_DETMASK

#define AHCIPORT_SSTS_DETMASK   0x0000000F /* Device Detection (DET) Mask */

Definition at line 93 of file ahci.c.

◆ AHCIPORT_SSTS_DETNE

#define AHCIPORT_SSTS_DETNE   0x00000004 /* DET: Not Enabled or in BIST mode */

Definition at line 97 of file ahci.c.

◆ AHCIPORT_SSTS_DETNOTEST

#define AHCIPORT_SSTS_DETNOTEST   0x00000001 /* DET: Phy not established */

Definition at line 95 of file ahci.c.

◆ AHCIPORT_SSTS_DETNP

#define AHCIPORT_SSTS_DETNP   0x00000000 /* DET: Not Present */

Definition at line 94 of file ahci.c.

◆ AHCIPORT_SSTS_DETPE

#define AHCIPORT_SSTS_DETPE   0x00000003 /* DET: Present and Established */

Definition at line 96 of file ahci.c.

◆ AHCIPORT_TFD_BSY

#define AHCIPORT_TFD_BSY   0x00000080 /* Port Busy */

Definition at line 89 of file ahci.c.

◆ AHCIPORT_TFD_DRQ

#define AHCIPORT_TFD_DRQ   0x00000004 /* Data Transfer Requested */

Definition at line 90 of file ahci.c.

◆ AHCIPORT_TFD_ERR

#define AHCIPORT_TFD_ERR   0x00000001 /* Error during Transfer */

Definition at line 91 of file ahci.c.

◆ PGSIZE

#define PGSIZE   4096

Typedef Documentation

◆ AHCI

typedef struct AHCI AHCI

◆ AHCICommandHeader

◆ AHCICommandList

◆ AHCICommandTable

◆ AHCIDevice

typedef struct AHCIDevice AHCIDevice

◆ AHCIHostControl

◆ AHCIPort

typedef struct AHCIPort AHCIPort

◆ AHCIPRDT

typedef struct AHCIPRDT AHCIPRDT

◆ AHCIRecvFIS

typedef struct AHCIRecvFIS AHCIRecvFIS

Function Documentation

◆ AHCI_Configure()

void AHCI_Configure ( PCIDevice  dev)

Definition at line 419 of file ahci.c.

420{
421 AHCI *ahci = (AHCI *)PAlloc_AllocPage();
422 volatile AHCIHostControl *hc;
423
424 PCI_Configure(&dev);
425
426 kprintf("AHCI: IRQ %d\n", dev.irq);
427
428 // MMIO
429 int bar;
430 for (bar = 0; bar < PCI_MAX_BARS; bar++) {
431 if (dev.bars[bar].size == 0)
432 continue;
433
434 kprintf("AHCI: BAR%d base=%08x size=%08x %s\n",
435 bar, dev.bars[bar].base, dev.bars[bar].size,
436 dev.bars[bar].type == PCIBAR_TYPE_IO ? "IO" : "Mem");
437 }
438
439 // Copy PCIDevice structure
440 memcpy(&ahci->dev, &dev, sizeof(dev));
441
442 // XXX: Register IRQ
443
444 // Setup
445 hc = (volatile AHCIHostControl *)(uintptr_t)dev.bars[AHCI_ABAR].base;
446 ahci->hc = (AHCIHostControl *)hc;
447
448 uint32_t caps = hc->cap;
449 uint32_t ports = hc->pi;
450 uint32_t vers = hc->vs;
451
452 kprintf("AHCI: Version %d.%d, Ports: 0x%08x\n",
453 vers >> 16, vers & 0xFFFF, ports);
454 if (ports > ((1 << AHCI_MAX_PORTS) - 1))
455 {
456 kprintf("AHCI: Currently only supports %d ports\n", AHCI_MAX_PORTS);
457 }
458
459 if (caps & AHCI_CAP_S64A) {
460 kprintf("AHCI: Supports 64-bit Addressing\n");
461 } else {
462 kprintf("AHCI: Controller does not support 64-bit addressing!\n");
463 return;
464 }
465
466 if (caps & AHCI_CAP_SNCQ)
467 kprintf("AHCI: Supports NCQ\n");
468
469 // Disable Interrupts
470 hc->ghc &= ~AHCI_GHC_IE;
471
472 // Enable AHCI Controller
473 hc->ghc |= AHCI_GHC_AE;
474
475 int p;
476 for (p = 0; p < AHCI_MAX_PORTS; p++)
477 {
478 if (ports & (1 << p))
479 {
480 ahci->port[p] = (AHCIPort *)(uintptr_t)(dev.bars[AHCI_ABAR].base +
482 } else {
483 ahci->port[p] = 0;
484 }
485 }
486
487 // Allocate memory and setup pointers
488 for (p = 0; p < AHCI_MAX_PORTS; p++)
489 {
490 volatile AHCIPort *port = ahci->port[p];
491 if (port != 0) {
492 int c;
493 for (c = 0; c < AHCI_MAX_CMDS; c++)
494 {
495 ahci->ctbl[p][c] = (AHCICommandTable *)PAlloc_AllocPage();
496 memset(ahci->ctbl[p][c], 0, sizeof(AHCICommandTable));
497 // XXX: VA2PA
498 ahci->clst[p]->cmds[c].ctba = (uint64_t)ahci->ctbl[p][c];
499 }
500
501 ahci->clst[p] = (AHCICommandList *)PAlloc_AllocPage();
502 memset(ahci->clst[p], 0, sizeof(AHCICommandList));
503 // XXX: VA2PA
504 port->clba = (uint64_t)ahci->clst[p];
505
506 ahci->rfis[p] = (AHCIRecvFIS *)PAlloc_AllocPage();
507 memset(ahci->rfis[p], 0, sizeof(AHCIRecvFIS));
508 // XXX: VA2PA
509 port->fb = (uint64_t)ahci->rfis[p];
510 }
511 }
512
513 // Reset controller and ports
514 AHCI_Reset(ahci);
515}
AHCIPort * port[AHCI_MAX_PORTS]
Definition: ahci.c:173
AHCIRecvFIS * rfis[AHCI_MAX_PORTS]
Definition: ahci.c:177
#define AHCI_MAX_PORTS
Definition: ahci.c:102
PCIDevice dev
Definition: ahci.c:170
#define AHCI_PORT_LENGTH
Definition: ahci.c:101
uint32_t vs
Definition: ahci.c:38
uint32_t cap
Definition: ahci.c:34
#define AHCI_MAX_CMDS
Definition: ahci.c:103
#define AHCI_PORT_OFFSET
Definition: ahci.c:100
#define AHCI_ABAR
Definition: ahci.c:99
uint64_t clba
Definition: ahci.c:50
#define AHCI_CAP_SNCQ
Definition: ahci.c:42
uint32_t ghc
Definition: ahci.c:35
AHCICommandHeader cmds[AHCI_MAX_CMDS]
Definition: ahci.c:120
AHCIHostControl * hc
Definition: ahci.c:172
void AHCI_Reset(AHCI *ahci)
Definition: ahci.c:383
#define AHCI_GHC_AE
Definition: ahci.c:44
#define AHCI_CAP_S64A
Definition: ahci.c:41
uint32_t pi
Definition: ahci.c:37
uint64_t fb
Definition: ahci.c:51
AHCICommandTable * ctbl[AHCI_MAX_PORTS][AHCI_MAX_CMDS]
Definition: ahci.c:176
AHCICommandList * clst[AHCI_MAX_PORTS]
Definition: ahci.c:175
uint64_t ctba
Definition: ahci.c:114
Definition: ahci.c:169
Definition: ahci.c:49
void PCI_Configure(PCIDevice *dev)
Definition: pci.c:249
int kprintf(const char *fmt,...)
Definition: printf.c:210
void * PAlloc_AllocPage()
Definition: palloc.c:188
#define PCI_MAX_BARS
Definition: pci.h:24
uint8_t irq
Definition: pci.h:64
#define PCIBAR_TYPE_IO
Definition: pci.h:45
PCIBAR bars[PCI_MAX_BARS]
Definition: pci.h:66
uint32_t base
Definition: pci.h:50
uint32_t size
Definition: pci.h:51
uint32_t type
Definition: pci.h:52
void * memset(void *dst, int c, size_t len)
Definition: string.c:164
void * memcpy(void *dst, const void *src, size_t len)
Definition: string.c:177
unsigned int uint32_t
Definition: types.h:12
uint64_t uintptr_t
Definition: types.h:16
unsigned long uint64_t
Definition: types.h:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_Dump()

void AHCI_Dump ( AHCI ahci)

Definition at line 222 of file ahci.c.

223{
224 volatile AHCIHostControl *hc = ahci->hc;
225
226 kprintf("CAP: 0x%08x\n", hc->cap);
227 kprintf("GHC: 0x%08x\n", hc->ghc);
228 kprintf("IS: 0x%08x\n", hc->is);
229 kprintf("PI: 0x%08x\n", hc->pi);
230 kprintf("VS: 0x%08x\n", hc->vs);
231}
uint32_t is
Definition: ahci.c:36
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_DumpPort()

void AHCI_DumpPort ( AHCI ahci,
int  port 
)

Definition at line 234 of file ahci.c.

235{
236 volatile AHCIPort *p = ahci->port[port];
237
238 kprintf("Port %d\n", port);
239 kprintf("CLBA: 0x%016llx\n", p->clba);
240 kprintf("FB: 0x%016llx\n", p->fb);
241 kprintf("IS: 0x%08x\n", p->is);
242 kprintf("IE: 0x%08x\n", p->ie);
243 kprintf("CMD: 0x%08x\n", p->cmd);
244 kprintf("TFD: 0x%08x\n", p->tfd);
245 kprintf("SIG: 0x%08x\n", p->sig);
246 kprintf("SSTS: 0x%08x\n", p->ssts);
247 kprintf("SCTL: 0x%08x\n", p->sctl);
248 kprintf("SERR: 0x%08x\n", p->serr);
249 kprintf("SACT: 0x%08x\n", p->sact);
250 kprintf("CI: 0x%08x\n", p->ci);
251}
uint32_t cmd
Definition: ahci.c:54
uint32_t sctl
Definition: ahci.c:59
uint32_t sig
Definition: ahci.c:57
uint32_t ssts
Definition: ahci.c:58
uint32_t tfd
Definition: ahci.c:56
uint32_t serr
Definition: ahci.c:60
uint32_t is
Definition: ahci.c:52
uint32_t sact
Definition: ahci.c:61
uint32_t ci
Definition: ahci.c:62
uint32_t ie
Definition: ahci.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_IdentifyPort()

void AHCI_IdentifyPort ( AHCI ahci,
int  port 
)

Definition at line 299 of file ahci.c.

300{
301 volatile AHCIPort *p = ahci->port[port];
302 SGArray sga;
303 SATAFIS_REG_H2D fis;
304 ATAIdentifyDevice ident;
305
306 kprintf("AHCI: Signature %08x\n", p->sig);
307
308 memset(&fis, 0, sizeof(fis));
312
313 sga.len = 1;
314 // VA2PA
315 sga.entries[0].offset = (uintptr_t)&ident;
316 sga.entries[0].length = 512;
317
318 AHCI_IssueCommand(ahci, port, &sga, &fis, sizeof(fis));
319 kprintf("AHCI: Identify Issued Port %d\n", port);
320 AHCI_WaitPort(ahci, port);
321
322 kprintf("AHCI: Identify Succeeded Port %d\n", port);
323 Debug_PrintHex((const char *)&ident, 512, 0, 512);
324 AHCI_DumpPort(ahci, port);
325 uint64_t val = (uint64_t)&ident;
326 Debug_PrintHex((const char *)&val, 8, 0, 8);
327
328 return;
329}
void AHCI_DumpPort(AHCI *ahci, int port)
Definition: ahci.c:234
uint64_t AHCI_IssueCommand(AHCI *ahci, int port, SGArray *sga, void *cfis, int len)
Definition: ahci.c:254
void AHCI_WaitPort(AHCI *ahci, int port)
Definition: ahci.c:285
void Debug_PrintHex(const char *data, size_t length, off_t off, size_t limit)
Definition: debug.c:30
uint8_t flag
Definition: sata.h:10
uint8_t command
Definition: sata.h:11
#define SATAFIS_CMD_IDENTIFY
Definition: sata.h:32
uint8_t type
Definition: sata.h:9
#define SATAFIS_REG_H2D_FLAG_COMMAND
Definition: sata.h:28
#define SATAFIS_TYPE_REG_H2D
Definition: sata.h:30
uint64_t length
Definition: sga.h:10
SGEntry entries[SGARRAY_MAX_ENTRIES]
Definition: sga.h:16
uint32_t len
Definition: sga.h:15
uint64_t offset
Definition: sga.h:9
Definition: sga.h:14
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_Init()

void AHCI_Init ( uint32_t  bus,
uint32_t  slot,
uint32_t  func 
)

Definition at line 183 of file ahci.c.

184{
185 PCIDevice dev;
186
187 dev.bus = bus;
188 dev.slot = slot;
189 dev.func = func;
190 dev.vendor = PCI_GetVendorID(&dev);
191 dev.device = PCI_GetDeviceID(&dev);
192
193 uint32_t device = dev.vendor << 16 | dev.device;
194
195 uint8_t progif = PCI_CfgRead8(&dev, PCI_OFFSET_PROGIF);
196 if (progif != 0x01)
197 {
198 kprintf("Unsupported SATA Controller PROGIF=%02x\n", progif);
199 return;
200 }
201
202 // XXX: Temporary until we have a slab allocator
203#define PGSIZE 4096
204 ASSERT(sizeof(AHCI) <= PGSIZE);
205 ASSERT(sizeof(AHCICommandList) <= PGSIZE);
206 ASSERT(sizeof(AHCIRecvFIS) <= PGSIZE);
207 ASSERT(sizeof(ATAIdentifyDevice) == 512);
208
209 int deviceIdx = 0;
210 while (deviceList[deviceIdx].device != 0x0) {
211 if (deviceList[deviceIdx].device == device) {
212 kprintf("AHCI: Found %s\n", deviceList[deviceIdx].name);
213 // Configure and add disks
214 AHCI_Configure(dev);
215 }
216
217 deviceIdx++;
218 }
219}
void AHCI_Configure(PCIDevice dev)
Definition: ahci.c:419
static AHCIDevice deviceList[]
Definition: ahci.c:26
#define PGSIZE
uint16_t PCI_GetVendorID(PCIDevice *dev)
Definition: pci.c:107
uint16_t PCI_GetDeviceID(PCIDevice *dev)
Definition: pci.c:101
uint8_t PCI_CfgRead8(PCIDevice *dev, uint32_t reg)
Definition: pci.c:65
#define ASSERT(_x)
Definition: kassert.h:8
#define PCI_OFFSET_PROGIF
Definition: pci.h:7
uint8_t slot
Definition: pci.h:61
uint16_t device
Definition: pci.h:58
uint8_t func
Definition: pci.h:62
uint16_t vendor
Definition: pci.h:57
uint8_t bus
Definition: pci.h:60
Definition: pci.h:56
unsigned char uint8_t
Definition: types.h:10
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_IssueCommand()

uint64_t AHCI_IssueCommand ( AHCI ahci,
int  port,
SGArray sga,
void *  cfis,
int  len 
)

Definition at line 254 of file ahci.c.

255{
256 // XXX: support multiple commands
257 volatile AHCICommandList *cl = ahci->clst[port];
258 volatile AHCICommandTable *ct = ahci->ctbl[port][0];
259 volatile AHCIPort *p = ahci->port[port];
260
261 // Copy Command FIS
262 memcpy((void *)&ct->cfis[0], cfis, len);
263
264 // Convert SGArray into PRDT
265 int i;
266 for (i = 0; i < sga->len; i++)
267 {
268 ct->prdt[i].dba = sga->entries[i].offset;
269 ct->prdt[i].descInfo = sga->entries[i].length - 1;
270 // Must be a multiple of word size
271 ASSERT(sga->entries[i].length % 2 == 0);
272 }
273
274 // Specify cfis length and prdt entries;
275 // XXX: support multiple commands
276 cl->cmds[0].prdtl = sga->len;
277 cl->cmds[0].flag = len >> 2;
278
279 p->ci = 1;
280
281 return 0;
282}
uint16_t flag
Definition: ahci.c:111
uint64_t dba
Definition: ahci.c:128
uint16_t prdtl
Definition: ahci.c:112
uint32_t descInfo
Definition: ahci.c:130
AHCIPRDT prdt[248]
Definition: ahci.c:144
uint8_t cfis[64]
Definition: ahci.c:141
uint64_t len
Definition: multiboot.h:2
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_Reset()

void AHCI_Reset ( AHCI ahci)

Definition at line 383 of file ahci.c.

384{
385 int port;
386 volatile AHCIHostControl *hc = ahci->hc;
387
388 AHCI_Dump(ahci);
389
390 // Reset controller
391 //uint32_t caps = hc->cap;
392 //uint32_t pi = hc->pi;
393
394 hc->ghc |= AHCI_GHC_AE;
395 hc->ghc |= AHCI_GHC_HR;
396 while (1) {
397 if ((hc->ghc & AHCI_GHC_HR) == 0)
398 break;
399 }
400 hc->ghc |= AHCI_GHC_AE;
401
402 AHCI_Dump(ahci);
403
404 // Reset ports
405 for (port = 0; port < AHCI_MAX_PORTS; port++)
406 {
407 if (ahci->port[port] != 0) {
408 AHCI_ResetPort(ahci, port);
409 }
410 }
411
412 // XXX: Clear interrupts
413
414 // Enable Interrupts
415 hc->ghc = AHCI_GHC_IE;
416}
#define AHCI_GHC_HR
Definition: ahci.c:46
#define AHCI_GHC_IE
Definition: ahci.c:45
void AHCI_ResetPort(AHCI *ahci, int port)
Definition: ahci.c:332
void AHCI_Dump(AHCI *ahci)
Definition: ahci.c:222
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_ResetPort()

void AHCI_ResetPort ( AHCI ahci,
int  port 
)

Definition at line 332 of file ahci.c.

333{
334 volatile AHCIPort *p = ahci->port[port];
335 uint32_t cmd = p->cmd;
338
339 // Wait for controller to be idle
340 if ((cmd & cmd_mask) != 0) {
341 int tries;
342 for (tries = 0; tries < 2; tries++) {
343 cmd = cmd & ~(AHCIPORT_CMD_ST | AHCIPORT_CMD_FRE);
344 p->cmd = cmd;
345 // sleep 500ms
346 cmd = p->cmd;
347 if ((cmd & cmd_mask) != 0) {
348 kprintf("AHCI: failed to reset port %d\n", port);
349 }
350 }
351 }
352
353 // Reset interrupts
354 p->is = 0xFFFFFFFF;
355 p->is = 0x00000000;
356
357 // Reset error
358 p->serr = 0xFFFFFFFF;
359 p->serr = 0x00000000;
360
363
364 // Check port
365 uint32_t ssts = p->ssts;
367 kprintf("AHCI: Device not present on port %d\n", port);
368 return;
369 }
371 kprintf("AHCI: Phys communication not established on port %d\n", port);
372 return;
373 }
375 kprintf("AHCI: Port %d not enabled\n", port);
376 return;
377 }
378
379 AHCI_IdentifyPort(ahci, port);
380}
#define AHCIPORT_CMD_ST
Definition: ahci.c:87
#define AHCIPORT_CMD_FRE
Definition: ahci.c:83
#define AHCIPORT_SSTS_DETNP
Definition: ahci.c:94
void AHCI_IdentifyPort(AHCI *ahci, int port)
Definition: ahci.c:299
#define AHCIPORT_CMD_CR
Definition: ahci.c:80
#define AHCIPORT_CMD_FR
Definition: ahci.c:81
#define AHCIPORT_CMD_SUD
Definition: ahci.c:86
#define AHCIPORT_SSTS_DETNOTEST
Definition: ahci.c:95
#define AHCIPORT_SSTS_DETMASK
Definition: ahci.c:93
#define AHCIPORT_SSTS_DETNE
Definition: ahci.c:97
#define AHCIPORT_CMD_ICCACTIVE
Definition: ahci.c:69
#define AHCIPORT_CMD_POD
Definition: ahci.c:85
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AHCI_WaitPort()

void AHCI_WaitPort ( AHCI ahci,
int  port 
)

Definition at line 285 of file ahci.c.

286{
287 volatile AHCIPort *p = ahci->port[port];
288 while (1) {
289 uint32_t tfd = p->tfd & AHCIPORT_TFD_BSY;
290 if ((tfd == 0) && (p->ci == 0)) {
291 return;
292 }
293
294 // implement timeouts
295 }
296}
#define AHCIPORT_TFD_BSY
Definition: ahci.c:89
Here is the caller graph for this function:

Variable Documentation

◆ deviceList

AHCIDevice deviceList[]
static
Initial value:
=
{
{ 0x80862922, "ICH9", 0 },
{ 0, "", 0 },
}

Definition at line 26 of file ahci.c.