License: add license
This commit is contained in:
commit
c35911b79d
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
105
Cargo.lock
generated
Normal file
105
Cargo.lock
generated
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahci"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bitfields",
|
||||||
|
"bitflags",
|
||||||
|
"num-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitfields"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcdbce6688e3ab66aff2ab413b762ccde9f37990e27bba0bb38a4b2ad1b5d877"
|
||||||
|
dependencies = [
|
||||||
|
"bitfields-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitfields-impl"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57413e4b276d883b77fb368b7b33ae6a5eb97692852d49a5394d4f72ba961827"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-derive"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "ahci"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitfields = "1.0.0"
|
||||||
|
bitflags = "2.9.1"
|
||||||
|
num-derive = "0.4.2"
|
18
LICENSE
Normal file
18
LICENSE
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
# GNU Public License v3
|
||||||
|
|
||||||
|
ahci - A Rust library for AHCI related data structures and functions.
|
||||||
|
Copyright (C) 2025 shibedrill
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
16
src/achi/mod.rs
Normal file
16
src/achi/mod.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#[repr(u32)]
|
||||||
|
pub enum SataSignature {
|
||||||
|
Ata = 0x000000101,
|
||||||
|
Atapi = 0xEB140101,
|
||||||
|
Semb = 0xC33C0101,
|
||||||
|
Pm = 0x96690101,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum AchiDevice {
|
||||||
|
Null = 0,
|
||||||
|
Sata = 1,
|
||||||
|
Semb = 2,
|
||||||
|
Pm = 3,
|
||||||
|
Satapi = 4,
|
||||||
|
}
|
98
src/ata/mod.rs
Normal file
98
src/ata/mod.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#[repr(u8)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum AtaCommand {
|
||||||
|
Nop(u8) = 0x0, // No-op
|
||||||
|
CfaReqXErr(u8) = 0x3,
|
||||||
|
DataSetMgmt(u16) = 0x6,
|
||||||
|
DataSetMgmtXL(u16) = 0x7,
|
||||||
|
ReqSenseDataX(u16) = 0xB,
|
||||||
|
GetPhysElemStatus(u16) = 0x12,
|
||||||
|
ReadSector(u8) = 0x20, // Read sectors
|
||||||
|
ReadSectorX(u16) = 0x24, // Read sectors (ext)
|
||||||
|
ReadDmaX(u16) = 0x25,
|
||||||
|
ReadStreamDmaX(u16) = 0x2A,
|
||||||
|
ReadStreamX(u16) = 0x2B,
|
||||||
|
ReadLogX(u16) = 0x2F,
|
||||||
|
WriteSector(u8) = 0x30, // Write sectors
|
||||||
|
WriteSectorX(u16) = 0x34, // Write sectors (ext)
|
||||||
|
WriteDmaX(u16) = 0x35,
|
||||||
|
CfaWriteSectorWOErase(u16) = 0x38,
|
||||||
|
WriteStreamDmaX(u16) = 0x3A,
|
||||||
|
WriteStreamX(u16) = 0x3B,
|
||||||
|
WriteDmaFuaX(u16) = 0x3D,
|
||||||
|
WriteLogX(u16) = 0x3F,
|
||||||
|
ReadVerifySector(u8) = 0x40,
|
||||||
|
ReadVerifySectorX(u16) = 0x42,
|
||||||
|
ZeroX(u16) = 0x44,
|
||||||
|
WriteUnCorrX(u16) = 0x45,
|
||||||
|
ReadLogDmaX(u16) = 0x47,
|
||||||
|
ZacMgmtIn(u16) = 0x4A,
|
||||||
|
CfgStream(u16) = 0x51,
|
||||||
|
WriteLogDmaX(u16) = 0x57,
|
||||||
|
TrustedNonData(u8) = 0x5B,
|
||||||
|
TrustedRecv(u8) = 0x5C,
|
||||||
|
TrustedRecvDma(u8) = 0x5D,
|
||||||
|
TrustedSend(u8) = 0x5E,
|
||||||
|
TrustedSendDma(u8) = 0x5F,
|
||||||
|
ReadFpdmaQueued(u16) = 0x60,
|
||||||
|
WriteFpdmaQueued(u16) = 0x61,
|
||||||
|
NcqNonData(u16) = 0x63,
|
||||||
|
SendFpdmaQueued(u16) = 0x64,
|
||||||
|
RecvFpdmaQueued(u16) = 0x65,
|
||||||
|
SetTimeDateX(u16) = 0x77,
|
||||||
|
AccMaxAddrCfg(u16) = 0x78,
|
||||||
|
RemElemTrunc(u16) = 0x7C,
|
||||||
|
RestElemRebuild(u16) = 0x7D,
|
||||||
|
RemElemModZones(u16) = 0x7E,
|
||||||
|
CfaTranslateSector(u8) = 0x87,
|
||||||
|
ExecDevDiag(u8) = 0x90,
|
||||||
|
InitDevParams(u8) = 0x91,
|
||||||
|
DlUcode(u8) = 0x92,
|
||||||
|
DlUcodeDma(u8) = 0x93,
|
||||||
|
MutateX(u16) = 0x96,
|
||||||
|
ZacMgmtOut(u16) = 0x9F,
|
||||||
|
Smart(u8) = 0xB0,
|
||||||
|
SetSectorCfgX(u16) = 0xB2,
|
||||||
|
SanDev(u16) = 0xB4,
|
||||||
|
ReadDma(u8) = 0xC8,
|
||||||
|
WriteDma(u8) = 0xCA,
|
||||||
|
CfaWriteMultWOErase(u8) = 0xCD,
|
||||||
|
StandbyImm(u8) = 0xE0,
|
||||||
|
IdleImm(u8) = 0xE1,
|
||||||
|
Standby(u8) = 0xE2,
|
||||||
|
Idle(u8) = 0xE3,
|
||||||
|
ReadBuf(u8) = 0xE4,
|
||||||
|
CheckPowerMode(u8) = 0xE5,
|
||||||
|
Sleep(u8) = 0xE6,
|
||||||
|
FLushCache(u8) = 0xE7,
|
||||||
|
WriteBuf(u8) = 0xE8,
|
||||||
|
ReadBufDma(u8) = 0xE9,
|
||||||
|
FlushCacheX(u8) = 0xEA,
|
||||||
|
WriteBufDma(u8) = 0xEB,
|
||||||
|
IdentifyDev(u8) = 0xEC, // Identify
|
||||||
|
IdentifyDevDma(u8) = 0xEE,
|
||||||
|
SetFeatures(u8) = 0xEF,
|
||||||
|
SecSetPwd(u8) = 0xF1,
|
||||||
|
SecUnlock(u8) = 0xF2,
|
||||||
|
SecErasePrep(u8) = 0xF3,
|
||||||
|
SecEraseUnit(u8) = 0xF4,
|
||||||
|
SecFreezeLock(u8) = 0xF5,
|
||||||
|
SecDisablePwd(u8) = 0xF6,
|
||||||
|
ReadNativeMaxAddr(u8) = 0xF8,
|
||||||
|
SetMaxAddr(u8) = 0xF9,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AtaIdentity {
|
||||||
|
device: u16, // Device bitfields
|
||||||
|
num_cylinders: u16,
|
||||||
|
spec_config: u16,
|
||||||
|
num_heads: u16,
|
||||||
|
_reserved_0: [u16; 2],
|
||||||
|
sectors_per_track: u16,
|
||||||
|
vendor: [u16; 3],
|
||||||
|
serial_number: [char; 20],
|
||||||
|
_reserved_1: [u16; 3],
|
||||||
|
firmware_rev: [char; 8],
|
||||||
|
model_num: [char; 40],
|
||||||
|
_pad: [char; 256],
|
||||||
|
}
|
5
src/lib.rs
Normal file
5
src/lib.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#![feature(default_field_values)]
|
||||||
|
|
||||||
|
pub mod achi;
|
||||||
|
pub mod ata;
|
||||||
|
pub mod sata;
|
89
src/sata/fis.rs
Normal file
89
src/sata/fis.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/// Types of Frame Information Structure.
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum FisType {
|
||||||
|
RegH2d = 0x27, // Register FIS - host to device
|
||||||
|
RegD2h = 0x34, // Register FIS - device to host
|
||||||
|
DmaAct = 0x39, // DMA activate FIS - device to host
|
||||||
|
DmaSetup = 0x41, // DMA setup FIS - bidirectional
|
||||||
|
Data = 0x46, // Data FIS - bidirectional
|
||||||
|
Bist = 0x58, // BIST activate FIS - bidirectional
|
||||||
|
PioSetup = 0x5F, // PIO setup FIS - device to host
|
||||||
|
DevBits = 0xA1, // Set device bits FIS - device to host
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RegH2d {
|
||||||
|
fis_type: FisType = FisType::RegH2d,
|
||||||
|
port: u8, // Port information
|
||||||
|
command: u8, // Command register
|
||||||
|
feature_low: u8, // Feature register, 7:0
|
||||||
|
lba_0: u8, // LBA low register, 7:0
|
||||||
|
lba_1: u8, // LBA mid register, 15:8
|
||||||
|
lba_2: u8, // LBA high register, 23:16
|
||||||
|
device: u8, // Device register
|
||||||
|
lba_3: u8, // LBA register, 31:24
|
||||||
|
lba_4: u8, // LBA register, 39:32
|
||||||
|
lba_5: u8, // LBA register, 47:40
|
||||||
|
feature_high: u8, // Feature register, 15:8
|
||||||
|
count_low: u8, // Count register low
|
||||||
|
count_high: u8, // Count register high
|
||||||
|
icc: u8, // Isochronous command completion
|
||||||
|
control: u8, // Control register
|
||||||
|
_reserved_0: [u8;4] = [0;4] // Reserved
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RegD2h {
|
||||||
|
fis_type: FisType = FisType::RegD2h,
|
||||||
|
port: u8, // Port information
|
||||||
|
status: u8, // Status register
|
||||||
|
error: u8, // Error register
|
||||||
|
lba_0: u8, // LBA low register, 7:0
|
||||||
|
lba_1: u8, // LBA mid register, 15:8
|
||||||
|
lba_2: u8, // LBA high register, 23:16
|
||||||
|
device: u8, // Device register
|
||||||
|
lba_3: u8, // LBA register, 31:24
|
||||||
|
lba_4: u8, // LBA register, 39:32
|
||||||
|
lba_5: u8, // LBA register, 47:40
|
||||||
|
_reserved_0: u8, // Reserved
|
||||||
|
count_low: u8, // Count register, 7:0
|
||||||
|
count_high: u8, // Count register, 15:8
|
||||||
|
_reserved_1: [u8;6] = [0;6],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Data {
|
||||||
|
fis_type: FisType = FisType::Data,
|
||||||
|
port: u8, // Port information
|
||||||
|
_reserved_0: [u8;2] = [0;2], // Reserved
|
||||||
|
data: [u32;2048], // Payload
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PioSetup {
|
||||||
|
fis_type: FisType = FisType::PioSetup,
|
||||||
|
port: u8, // Port information
|
||||||
|
status: u8,
|
||||||
|
error: u8,
|
||||||
|
lba_0: u8,
|
||||||
|
lba_1: u8,
|
||||||
|
lba_2: u8,
|
||||||
|
device: u8,
|
||||||
|
lba_3: u8,
|
||||||
|
lba_4: u8,
|
||||||
|
lba_5: u8,
|
||||||
|
_reserved_0: u8,
|
||||||
|
count_low: u8,
|
||||||
|
count_high: u8,
|
||||||
|
_reserved_1: u8,
|
||||||
|
new_status: u8,
|
||||||
|
transfer_count: u16,
|
||||||
|
_reserved_2: [u8;2],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DmaSetup {
|
||||||
|
fis_type: FisType = FisType::DmaSetup,
|
||||||
|
port: u8, // Port information
|
||||||
|
_reserved_0: [u8;2],
|
||||||
|
dma_buffer_id: u64,
|
||||||
|
_reserved_1: [u8;4],
|
||||||
|
dmu_buffer_offset: u32,
|
||||||
|
transfer_count: u32,
|
||||||
|
_reserved_2: [u8;4],
|
||||||
|
}
|
61
src/sata/hba.rs
Normal file
61
src/sata/hba.rs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
use crate::sata::fis;
|
||||||
|
pub struct CommandHeader {
|
||||||
|
fis_data: u8,
|
||||||
|
port: u8,
|
||||||
|
prdtl: u16, // Physical region descriptor table length in entries
|
||||||
|
prdbc: u32, // Physical region descriptor byte count transferred
|
||||||
|
ctba_lower: u32, // Command table descriptor base address
|
||||||
|
ctba_upper: u32, // Command table descriptor base address upper 32 bits
|
||||||
|
_reserved_0: [u32; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Port {
|
||||||
|
clb_lower: u32, // 0x00, command list base address, 1K-byte aligned
|
||||||
|
clb_upper: u32, // 0x04, command list base address upper 32 bits
|
||||||
|
fis_lower: u32, // 0x08, FIS base address, 256-byte aligned
|
||||||
|
fis_upper: u32, // 0x0C, FIS base address upper 32 bits
|
||||||
|
interrupt_status: u32, // 0x10, interrupt status
|
||||||
|
interrupt_enable: u32, // 0x14, interrupt enable
|
||||||
|
command_status: u32, // 0x18, command and status
|
||||||
|
_reserved_0: u32, // 0x1C, Reserved
|
||||||
|
task_file_data: u32, // 0x20, task file data
|
||||||
|
signature: u32, // 0x24, signature
|
||||||
|
sata_status: u32, // 0x28, SATA status (SCR0:SStatus)
|
||||||
|
sata_control: u32, // 0x2C, SATA control (SCR2:SControl)
|
||||||
|
sata_error: u32, // 0x30, SATA error (SCR1:SError)
|
||||||
|
sata_active: u32, // 0x34, SATA active (SCR3:SActive)
|
||||||
|
command_issue: u32, // 0x38, command issue
|
||||||
|
sata_notif: u32, // 0x3C, SATA notification (SCR4:SNotification)
|
||||||
|
fis_switch_control: u32, // 0x40, FIS-based switch control
|
||||||
|
_reserved_1: [u32;11] = [0;11], // 0x44 ~ 0x6F, Reserved
|
||||||
|
vendor_specific: [u32;4], // 0x70 ~ 0x7F, vendor specific
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Memory {
|
||||||
|
capabilities: u32, // 0x00, Host capability
|
||||||
|
global_host_control: u32, // 0x04, Global host control
|
||||||
|
interrupt_status: u32, // 0x08, Interrupt status
|
||||||
|
port_implemented: u32, // 0x0C, Port implemented
|
||||||
|
version: u32, // 0x10, Version
|
||||||
|
ccc_control: u32, // 0x14, Command completion coalescing control
|
||||||
|
ccc_ports: u32, // 0x18, Command completion coalescing ports
|
||||||
|
em_location: u32, // 0x1C, Enclosure management location
|
||||||
|
em_control: u32, // 0x20, Enclosure management control
|
||||||
|
capabilities_ext: u32, // 0x24, Host capabilities extended
|
||||||
|
handoff_control_status: u32, // 0x28, BIOS/OS handoff control and status
|
||||||
|
_reserved_0: [u8; 0xA0 - 0x2C],
|
||||||
|
vendor_specific: [u8; 0x100 - 0xA0],
|
||||||
|
ports: [Port; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Fis {
|
||||||
|
dma_setup_fis: fis::DmaSetup,
|
||||||
|
_reserved_0: [u8;4] = [0;4],
|
||||||
|
pio_setup_fis: fis::PioSetup,
|
||||||
|
_reserved_1: [u8;12] = [0;12],
|
||||||
|
reg_d2h_fis: fis::RegD2h,
|
||||||
|
_reserved_2: [u8;4] = [0;4],
|
||||||
|
set_bits_fis: u32,
|
||||||
|
ufis: [u8;64],
|
||||||
|
_reserved_3: [u8;0x100 - 0xA0],
|
||||||
|
}
|
4
src/sata/mod.rs
Normal file
4
src/sata/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
mod fis;
|
||||||
|
mod hba;
|
Loading…
Reference in New Issue
Block a user