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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
/* -------------------------------------------
Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
------------------------------------------- */
/**
* @file neboot-ahci-driver.cc
* @author Amlal EL Mahrouss (amlal@nekernel.org)
* @brief SATA Disk support, via AHCI.
* @version 0.2
* @date 2024-01-16
*
* @copyright Copyright (c) 2024-2025, Amlal EL Mahrouss.
*
*/
#include <lib/boot.h>
#include <lib/pci-tree.h>
#define NB_AHCI_DRIVER_NAME ("@sata")
/// BUGS: 0
/// @brief AHCI support for PowerPC.
/// @brief AHCI HBA port.
typedef struct cb_hba_port {
uint32_t clb; // 0x00, command list base address, 1K-byte aligned
uint32_t clbu; // 0x04, command list base address upper 32 bits
uint32_t fb; // 0x08, FIS base address, 256-byte aligned
uint32_t fbu; // 0x0C, FIS base address upper 32 bits
uint32_t is; // 0x10, interrupt status
uint32_t ie; // 0x14, interrupt enable
uint32_t cmd; // 0x18, command and status
uint32_t reserved0; // 0x1C, Reserved
uint32_t tfd; // 0x20, task file data
uint32_t sig; // 0x24, signature
uint32_t ssts; // 0x28, SATA status (SCR0:SStatus)
uint32_t sctl; // 0x2C, SATA control (SCR2:SControl)
uint32_t serr; // 0x30, SATA error (SCR1:SError)
uint32_t sact; // 0x34, SATA active (SCR3:SActive)
uint32_t ci; // 0x38, command issue
uint32_t sntf; // 0x20, SATA notification (SCR4:SNotification)
uint32_t fbs; // 0x40, FIS-based switch control
uint32_t reserved1[11]; // 0x44 ~ 0x6F, Reserved
uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific
} cb_hba_port_t;
/// @brief Check if port is active.
/// @param port host bus address port.
/// @return whether sact is active or not.
static boolean cb_hba_port_active(volatile cb_hba_port_t* port) {
if (!port) return false;
return port->sact;
}
/// @brief Start HBA command processor.
/// @param port host bus address port.
/// @return whether it was successful or not.
static boolean cb_hba_start_cmd(volatile cb_hba_port_t* port) {
if (!port) return false;
size_t timeout = 1000000;
while ((port->cmd & 0x8000)) {
if (!timeout) return false;
--timeout;
}
port->cmd |= 0x0001;
port->cmd |= 0x0010;
return true;
}
/// @brief Stop HBA command from processing.
/// @param port host bus address port.
/// @return whether it was successful or not.
static boolean cb_hba_stop_cmd(volatile cb_hba_port_t* port) {
if (!port) return false;
port->cmd &= ~0x0001;
port->cmd &= ~0x0010;
while (yes) {
if ((port->cmd & 0x8000)) continue;
if ((port->cmd & 0x4000)) continue;
break;
}
return true;
}
|