Max OS 0.3
Loading...
Searching...
No Matches
MaxOS::drivers::disk::AdvancedTechnologyAttachment Class Reference

Driver for the ATA controller, handles the reading and writing of data to the hard drive. More...

#include <ata.h>

Inheritance diagram for MaxOS::drivers::disk::AdvancedTechnologyAttachment:
MaxOS::drivers::disk::Disk MaxOS::drivers::Driver

Public Member Functions

 AdvancedTechnologyAttachment (uint16_t port_base, bool master)
 Constructor for the AdvancedTechnologyAttachment class.
 
bool identify ()
 Identify the ATA device.
 
void read (uint32_t sector, common::buffer_t *data_buffer, size_t amount) final
 read a sector from the ATA device
 
void write (uint32_t sector, common::buffer_t *data, size_t count) final
 write to a sector on the ATA device
 
void flush () final
 Flush the cache of the ATA device.
 
string device_name () final
 Get the device name.
 
string vendor_name () final
 Get the vendor name.
 
- Public Member Functions inherited from MaxOS::drivers::disk::Disk
void read (uint32_t sector, common::buffer_t *data_buffer)
 read data from the disk into a buffer (max capacity 512 bytes)
 
void write (uint32_t sector, common::buffer_t *data)
 write data to the disk from a buffer (max capacity 512 bytes)
 
void activate () override
 Activate the disk driver.
 
string device_name () override
 Get the device name.
 
string vendor_name () override
 Get the vendor name.
 
- Public Member Functions inherited from MaxOS::drivers::Driver
virtual void deactivate ()
 Deactivate the driver.
 
virtual void initialise ()
 Initialise the driver.
 
virtual uint32_t reset ()
 Reset the driver.
 

Detailed Description

Driver for the ATA controller, handles the reading and writing of data to the hard drive.

Definition at line 25 of file ata.h.

Constructor & Destructor Documentation

◆ AdvancedTechnologyAttachment()

AdvancedTechnologyAttachment::AdvancedTechnologyAttachment ( uint16_t  port_base,
bool  master 
)

Constructor for the AdvancedTechnologyAttachment class.

Parameters
port_baseThe base port for the ATA device
masterTrue if the device is master, false if slave

Definition at line 23 of file ata.cpp.

24 : m_data_port(port_base),
25 m_error_port(port_base + 1),
26 m_sector_count_port(port_base + 2),
27 m_LBA_low_port(port_base + 3),
28 m_LBA_mid_port(port_base + 4),
29 m_LBA_high_Port(port_base + 5),
30 m_device_port(port_base + 6),
31 m_command_port(port_base + 7),
32 m_control_port(port_base + 0x206),
33 m_is_master(master) {
34
35}
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22

Member Function Documentation

◆ device_name()

string AdvancedTechnologyAttachment::device_name ( )
finalvirtual

Get the device name.

Returns
The name of the device

Reimplemented from MaxOS::drivers::Driver.

Definition at line 248 of file ata.cpp.

248 {
249 return "Advanced Technology Attachment";
250}

◆ flush()

void AdvancedTechnologyAttachment::flush ( )
finalvirtual

Flush the cache of the ATA device.

Reimplemented from MaxOS::drivers::disk::Disk.

Definition at line 219 of file ata.cpp.

219 {
220
221 // Select the device (master or slave)
222 m_device_port.write(m_is_master ? 0xE0 : 0xF0);
223
224 // Send the flush command
225 m_command_port.write(0xE7);
226
227 // Make sure the device is there
228 uint8_t status = m_command_port.read();
229 if (status == 0x00)
230 return;
231
232 // Wait for the device to be ready or for an error to occur
233 while (((status & 0x80) == 0x80) && ((status & 0x01) != 0x01))
234 status = m_command_port.read();
235
236 // Check for an error
237 if (status & 0x01)
238 return;
239
240 // ...
241}
virtual uint8_t read()
read a byte from the port
Definition port.cpp:51
virtual void write(uint8_t data)
write a byte to the port
Definition port.cpp:41

References MaxOS::hardwarecommunication::Port8Bit::read(), and MaxOS::hardwarecommunication::Port8Bit::write().

Referenced by write().

◆ identify()

bool AdvancedTechnologyAttachment::identify ( )

Identify the ATA device.

Returns
True if the device is present, false otherwise

Definition at line 44 of file ata.cpp.

44 {
45
46 // Select the device (master or slave)
47 m_device_port.write(m_is_master ? 0xA0 : 0xB0);
48
49 // Reset the High Order Byte
50 m_control_port.write(0);
51
52 // Check if the master is present
53 m_device_port.write(0xA0);
54 uint8_t status = m_command_port.read();
55 if (status == 0xFF) {
56 Logger::WARNING() << "ATA Device: Invalid status";
57 return false;
58 }
59
60 // Select the device (master or slave)
61 m_device_port.write(m_is_master ? 0xA0 : 0xB0);
62
63 // Clear the ports
64 m_sector_count_port.write(0);
65 m_LBA_low_port.write(0);
66 m_LBA_mid_port.write(0);
67 m_LBA_high_Port.write(0);
68
69 // Check if the device is present
70 m_command_port.write(0x0EC);
71 status = m_command_port.read();
72 if (status == 0x00)
73 return false;
74
75 // Wait for the device to be ready or for an error to occur
76 while (((status & 0x80) == 0x80) && ((status & 0x01) != 0x01))
77 status = m_command_port.read();
78
79 //Check for any errors
80 if (status & 0x01) {
81 Logger::WARNING() << "ATA Device: Error reading status\n";
82 return false;
83 }
84
85 // Read the rest of the data as a whole sector needs to be read (force the compiler to do so)
86 for (uint16_t i = 0; i < 256; ++i) {
87 volatile uint16_t data = m_data_port.read();
88 (void) data;
89 }
90
91
92 // Device is present and ready
93 return true;
94}
static Logger WARNING()
Gets active logger set to WARNING level.
Definition logger.cpp:205
virtual uint16_t read()
read a word from the port
Definition port.cpp:105

References MaxOS::hardwarecommunication::Port8Bit::read(), MaxOS::hardwarecommunication::Port16Bit::read(), MaxOS::Logger::WARNING(), and MaxOS::hardwarecommunication::Port8Bit::write().

◆ read()

void AdvancedTechnologyAttachment::read ( uint32_t  sector,
common::buffer_t data_buffer,
size_t  amount 
)
finalvirtual

read a sector from the ATA device

Parameters
sectorThe sector to read
data_bufferThe data to read into
amountThe amount of bytes to read from that sector

Reimplemented from MaxOS::drivers::disk::Disk.

Definition at line 103 of file ata.cpp.

103 {
104
105 // Don't allow reading more than a sector
106 if (sector & 0xF0000000 || amount > m_bytes_per_sector)
107 return;
108
109 // Select the device (master or slave)
110 m_device_port.write((m_is_master ? 0xE0 : 0xF0) | ((sector & 0x0F000000) >> 24));
111
112 // Device is busy @todo yield
113 while ((m_command_port.read() & 0x80) != 0);
114
115 // Reset the device
116 m_error_port.write(0);
117 m_sector_count_port.write(1);
118
119 // Split the sector into the ports
120 m_LBA_low_port.write(sector & 0x000000FF);
121 m_LBA_mid_port.write((sector & 0x0000FF00) >> 8);
122 m_LBA_high_Port.write((sector & 0x00FF0000) >> 16);
123
124 // Tell the device to prepare for reading
125 m_command_port.write(0x20);
126
127 // Make sure the device is there
128 uint8_t status = m_command_port.read();
129 if (status == 0x00)
130 return;
131
132 // Wait for the device to be ready or for an error to occur @todo Userspace block here
133 while (((status & 0x80) == 0x80) && ((status & 0x01) != 0x01))
134 status = m_command_port.read();
135
136 //Check for any errors
137 if (status & 0x01)
138 return;
139
140 for (size_t i = 0; i < amount; i += 2) {
141
142 // Read from the disk (2 bytes) and store the first byte
143 uint16_t read_data = m_data_port.read();
144 data_buffer->write(read_data & 0x00FF);
145
146 // Place the second byte in the array if there is one
147 if (i + 1 < amount)
148 data_buffer->write((read_data >> 8) & 0x00FF);
149 }
150
151 // Read the remaining bytes as a full sector has to be read
152 for (uint16_t i = amount + (amount % 2); i < m_bytes_per_sector; i += 2)
153 m_data_port.read();
154}

References MaxOS::hardwarecommunication::Port8Bit::read(), MaxOS::hardwarecommunication::Port16Bit::read(), and MaxOS::hardwarecommunication::Port8Bit::write().

◆ vendor_name()

string AdvancedTechnologyAttachment::vendor_name ( )
finalvirtual

Get the vendor name.

Returns
The name of the vendor

Reimplemented from MaxOS::drivers::Driver.

Definition at line 257 of file ata.cpp.

257 {
258 return "IDE";
259}

◆ write()

void AdvancedTechnologyAttachment::write ( uint32_t  sector,
common::buffer_t data,
size_t  count 
)
finalvirtual

write to a sector on the ATA device

Parameters
sectorThe sector to write to
dataThe data to write
countThe amount of data to write to that sector

Reimplemented from MaxOS::drivers::disk::Disk.

Definition at line 163 of file ata.cpp.

163 {
164
165 // Don't allow writing more than a sector
166 if (sector > 0x0FFFFFFF || count > m_bytes_per_sector)
167 return;
168
169 // Select the device (master or slave)
170 m_device_port.write(m_is_master ? 0xE0 : 0xF0 | ((sector & 0x0F000000) >> 24));
171
172 // Device is busy @todo YIELD
173 while ((m_command_port.read() & 0x80) != 0);
174
175 // Reset the device
176 m_error_port.write(0);
177 m_sector_count_port.write(1);
178
179 // Split the sector into the ports
180 m_LBA_low_port.write(sector & 0x000000FF);
181 m_LBA_mid_port.write((sector & 0x0000FF00) >> 8);
182 m_LBA_high_Port.write((sector & 0x00FF0000) >> 16);
183
184 // Send the write command
185 m_command_port.write(0x30);
186
187 // Wait for the device be ready writing @todo YIELD
188 uint8_t status = m_command_port.read();
189 while ((status & 0x80) != 0 || (status & 0x08) == 0)
190 status = m_command_port.read();
191
192 // Write the data to the device
193 for (size_t i = 0; i < m_bytes_per_sector; i += 2) {
194
195 uint16_t write_data = data->read();
196
197 // Place the next byte in the array if there is one
198 if (i + 1 < count)
199 write_data |= (uint16_t) (data->read()) << 8;
200
201 m_data_port.write(write_data);
202 }
203
204 // Write the remaining bytes as a full sector has to be written
205 for (size_t i = count + (count % 2); i < m_bytes_per_sector; i += 2)
206 m_data_port.write(0x0000);
207
208 // Wait for the device to finish writing @todo YIELD
209 status = m_command_port.read();
210 while ((status & 0x80) != 0 || (status & 0x08) != 0)
211 status = m_command_port.read();
212
213 flush();
214}
void flush() final
Flush the cache of the ATA device.
Definition ata.cpp:219
virtual void write(uint16_t data)
write a word to the port
Definition port.cpp:95

References flush(), MaxOS::common::Buffer::read(), MaxOS::hardwarecommunication::Port8Bit::read(), MaxOS::hardwarecommunication::Port16Bit::write(), and MaxOS::hardwarecommunication::Port8Bit::write().


The documentation for this class was generated from the following files: