blob: d091941863b18b360526dfabbc33472cb8021844 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
#include <sata.h>
#include <libk/string.h>
#include <libk/stdio.h>
#include <heap.h>
#include <paging.h>
#include <pci.h>
#include <ahci.h>
// 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 probe_port(HBA_MEM *abar)
{
// Search disk in implemented ports
uint32_t pi = abar->pi;
int i = 0;
while (i < 32) {
if (pi & 1) {
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);
}
}
pi >>= 1;
i++;
}
}
void ahci()
{
pci_dev_list_t *pos;
list_for_each_entry(pos, (&pci_dev_list.list), list) {
pci_dev_t *dev = &pos->dev->pci_dev;
if (dev->class_ != 0x1 || dev->subclass != 0x6)
continue;
HBA_MEM *abar = (HBA_MEM *)(uint64_t)pos->dev->bar[5];
printf("AHCI: %x\n", abar);
map_addr((uint64_t)abar, (uint64_t)abar,
FLAG_PRESENT | FLAG_WRITABLE | FLAG_HUGE);
probe_port(abar);
}
}
|