ATA driver

This commit is contained in:
Baptiste Wicht 2014-03-08 13:47:15 +01:00
parent fdf93f927d
commit 25c70c9359
4 changed files with 135 additions and 14 deletions

View File

@ -12,9 +12,13 @@
#include "thor.hpp"
#include "interrupts.hpp"
#include "console.hpp"
#include "errors.hpp"
#include "disks.hpp"
namespace {
static constexpr const size_t BLOCK_SIZE = 512;
//IDE Controllers
#define ATA_PRIMARY 0x1F0
#define ATA_SECONDARY 0x170
@ -351,20 +355,134 @@ ata::drive_descriptor& ata::drive(uint8_t disk){
return drives[disk];
}
size_t ata::ata_driver::read(void* data, char* buffer, size_t count, size_t offset, size_t& read){
//TODO
size_t ata::ata_driver::read(void* data, char* destination, size_t count, size_t offset, size_t& read){
if(count % BLOCK_SIZE != 0){
return std::ERROR_INVALID_COUNT;
}
size_t ata::ata_driver::write(void* data, const char* buffer, size_t count, size_t offset, size_t& written){
//TODO
if(offset % BLOCK_SIZE != 0){
return std::ERROR_INVALID_OFFSET;
}
size_t ata::ata_part_driver::read(void* data, char* buffer, size_t count, size_t offset, size_t& read){
//TODO
read = 0;
auto sectors = count % BLOCK_SIZE;
auto start = offset % BLOCK_SIZE;
auto descriptor = reinterpret_cast<disks::disk_descriptor*>(data);
auto disk = reinterpret_cast<ata::drive_descriptor*>(descriptor->descriptor);
auto buffer = reinterpret_cast<uint8_t*>(destination);
for(size_t i = 0; i < sectors; ++i){
if(!read_write_sector(*disk, start + i, buffer, true)){
return std::ERROR_FAILED;
}
size_t ata::ata_part_driver::write(void* data, const char* buffer, size_t count, size_t offset, size_t& written){
//TODO
buffer += BLOCK_SIZE;
read += BLOCK_SIZE;
}
return 0;
}
size_t ata::ata_driver::write(void* data, const char* source, size_t count, size_t offset, size_t& written){
if(count % BLOCK_SIZE != 0){
return std::ERROR_INVALID_COUNT;
}
if(offset % BLOCK_SIZE != 0){
return std::ERROR_INVALID_OFFSET;
}
written = 0;
auto sectors = count % BLOCK_SIZE;
auto start = offset % BLOCK_SIZE;
auto descriptor = reinterpret_cast<disks::disk_descriptor*>(data);
auto disk = reinterpret_cast<ata::drive_descriptor*>(descriptor->descriptor);
auto buffer = reinterpret_cast<uint8_t*>(const_cast<char*>(source));
for(size_t i = 0; i < sectors; ++i){
if(!read_write_sector(*disk, start + i, buffer, false)){
return std::ERROR_FAILED;
}
buffer += BLOCK_SIZE;
written += BLOCK_SIZE;
}
return 0;
}
size_t ata::ata_part_driver::read(void* data, char* destination, size_t count, size_t offset, size_t& read){
if(count % BLOCK_SIZE != 0){
return std::ERROR_INVALID_COUNT;
}
if(offset % BLOCK_SIZE != 0){
return std::ERROR_INVALID_OFFSET;
}
read = 0;
auto sectors = count % BLOCK_SIZE;
auto start = offset % BLOCK_SIZE;
auto part_descriptor = reinterpret_cast<disks::partition_descriptor*>(data);
auto descriptor = part_descriptor->disk;
auto disk = reinterpret_cast<ata::drive_descriptor*>(descriptor->descriptor);
start += part_descriptor->start;
auto buffer = reinterpret_cast<uint8_t*>(destination);
for(size_t i = 0; i < sectors; ++i){
if(!read_write_sector(*disk, start + i, buffer, true)){
return std::ERROR_FAILED;
}
buffer += BLOCK_SIZE;
read += BLOCK_SIZE;
}
return 0;
}
size_t ata::ata_part_driver::write(void* data, const char* source, size_t count, size_t offset, size_t& written){
if(count % BLOCK_SIZE != 0){
return std::ERROR_INVALID_COUNT;
}
if(offset % BLOCK_SIZE != 0){
return std::ERROR_INVALID_OFFSET;
}
written = 0;
auto sectors = count % BLOCK_SIZE;
auto start = offset % BLOCK_SIZE;
auto part_descriptor = reinterpret_cast<disks::partition_descriptor*>(data);
auto descriptor = part_descriptor->disk;
auto disk = reinterpret_cast<ata::drive_descriptor*>(descriptor->descriptor);
start += part_descriptor->start;
auto buffer = reinterpret_cast<uint8_t*>(const_cast<char*>(source));
for(size_t i = 0; i < sectors; ++i){
if(!read_write_sector(*disk, start + i, buffer, false)){
return std::ERROR_FAILED;
}
buffer += BLOCK_SIZE;
written += BLOCK_SIZE;
}
return 0;
}
bool ata::read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination){
@ -375,7 +493,7 @@ bool ata::read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, v
return false;
}
buffer += 512;
buffer += BLOCK_SIZE;;
}
return true;
@ -389,7 +507,7 @@ bool ata::write_sectors(drive_descriptor& drive, uint64_t start, uint8_t count,
return false;
}
buffer += 512;
buffer += BLOCK_SIZE;
}
return true;

View File

@ -67,14 +67,14 @@ void disks::detect_disks(){
std::string name = "cd";
name += cdrom++;
devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, atapi_driver, &descriptor);
devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, atapi_driver, &_disks[number_of_disks]);
} else {
_disks[number_of_disks] = {number_of_disks, disks::disk_type::ATA, &descriptor};
std::string name = "hd";
name += disk++;
devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, ata_driver, &descriptor);
devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, ata_driver, &_disks[number_of_disks]);
char part = '1';

View File

@ -61,8 +61,8 @@ std::string partition_type_to_string(vfs::partition_type type){
std::vector<mounted_fs> mount_point_list;
void mount_root(){
//TODO Get information about the root from a confgiuration file
mount(vfs::partition_type::FAT32, "/", "TODO");
//TODO Get information about the root from a configuration file
mount(vfs::partition_type::FAT32, "/", "/dev/hda1");
}
void mount_sys(){

View File

@ -28,6 +28,7 @@ constexpr const size_t ERROR_DISK_FULL = 12;
constexpr const size_t ERROR_PERMISSION_DENIED = 13;
constexpr const size_t ERROR_INVALID_OFFSET = 14;
constexpr const size_t ERROR_UNSUPPORTED = 15;
constexpr const size_t ERROR_INVALID_COUNT = 16;
inline const char* error_message(size_t error){
switch(error){
@ -61,6 +62,8 @@ inline const char* error_message(size_t error){
return "The offset is not valid";
case ERROR_UNSUPPORTED:
return "Unsupported operation: May not be implemented yet";
case ERROR_INVALID_COUNT:
return "The count is not valid";
default:
return "Unknonwn error";
}