-
Notifications
You must be signed in to change notification settings - Fork 1
/
ata.hpp
152 lines (125 loc) · 3.72 KB
/
ata.hpp
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#pragma once
// http://www.t13.org/Documents/UploadedDocuments/docs2013/d2161r5-ATAATAPI_Command_Set_-_3.pdf
#include "cpuio.hpp"
namespace ata {
using namespace cpuio;
enum DriveType {
master, slave
};
namespace stdData {
// uses weird names because you are not supposed to rely on these except primary
namespace driveTypeId {
constexpr uint8_t master = 0xa0;
constexpr uint8_t slave = 0xb0;
}
namespace statusBitMask {
constexpr uint8_t err = 1 << 0;
constexpr uint8_t drq = 1 << 3;
constexpr uint8_t srv = 1 << 4;
constexpr uint8_t df = 1 << 5;
constexpr uint8_t rdy = 1 << 6;
constexpr uint8_t bsy = 1 << 7;
}
namespace portOffset {
constexpr port_t data = 0;
constexpr port_t features = 1;
constexpr port_t err = 1;
constexpr port_t secCount = 2;
constexpr port_t sec = 3;
constexpr port_t LBAlo = 3;
constexpr port_t cylLo = 4;
constexpr port_t LBAmid = 4;
constexpr port_t cylHi = 5;
constexpr port_t LBAhi = 5;
constexpr port_t drive = 6;
constexpr port_t head = 6;
constexpr port_t command = 7;
constexpr port_t status = 7;
}
namespace command {
constexpr uint8_t read = 0x20;
constexpr uint8_t identify = 0xec;
}
namespace bus {
namespace irq {
constexpr uint8_t primary = 14;
constexpr uint8_t secondary = 15;
}
namespace ioport {
constexpr port_t primary = 0x1f0;
constexpr port_t secondary = 0x170;
constexpr port_t tertiary = 0x1e8;
constexpr port_t quaternary = 0x168;
// device control register / alternative status
namespace dcr_altstatus {
constexpr port_t primary = 0x3f6;
constexpr port_t secondary = 0x376;
constexpr port_t tertiary = 0x3e6;
constexpr port_t quaternary = 0x366;
}
}
}
}
struct DriveStatus {
public:
DriveStatus(const uint8_t s);
bool err() const;
bool drq() const;
bool srv() const;
bool df () const;
bool rdy() const;
bool bsy() const;
uint8_t raw() const;
private:
uint8_t s_;
};
struct Bus;
struct Drive {
public:
Drive(const port_t port, const DriveType type, const Bus& bus);
void writeData (const uint16_t v) const;
void writeSecCount(const uint8_t v) const;
void writeSec (const uint8_t v) const;
void writeCylLo (const uint8_t v) const;
void writeCylHi (const uint8_t v) const;
void writeHead (const uint8_t v) const;
void writeCommand (const uint8_t v) const;
uint16_t readData () const;
uint8_t readSecCount() const;
uint8_t readSec () const;
uint8_t readCylLo () const;
uint8_t readCylHi () const;
uint8_t readHead () const;
uint8_t readStatus () const;
void ensureSelected() const;
private:
port_t port_;
DriveType type_;
const Bus& bus_;
};
struct MaybeDrive {
public:
MaybeDrive(const port_t port, const DriveType type, const Bus& bus);
Drive* lookforDrive();
private:
bool found_; // fixme: what if drive is disconnected?
Drive d_;
};
struct Bus {
public:
Bus(const port_t port);
void selectMaster() const;
void selectSlave () const;
void selectDrive(DriveType t) const;
bool isOnMaster() const;
bool isOnSlave () const;
DriveType cur() const;
MaybeDrive master() const;
MaybeDrive slave() const;
private:
port_t port_;
MaybeDrive master_;
MaybeDrive slave_;
DriveType curDrive_;
};
}