mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-13 06:29:47 -04:00
Safer ATA driver
This commit is contained in:
parent
ea4fbf9a92
commit
e2a7f90342
@ -5,6 +5,8 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
|
#include <lock_guard.hpp>
|
||||||
|
|
||||||
#include "ata.hpp"
|
#include "ata.hpp"
|
||||||
#include "kernel_utils.hpp"
|
#include "kernel_utils.hpp"
|
||||||
#include "timer.hpp"
|
#include "timer.hpp"
|
||||||
@ -14,6 +16,7 @@
|
|||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
#include "errors.hpp"
|
#include "errors.hpp"
|
||||||
#include "disks.hpp"
|
#include "disks.hpp"
|
||||||
|
#include "mutex.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -56,6 +59,11 @@ static constexpr const size_t BLOCK_SIZE = 512;
|
|||||||
|
|
||||||
ata::drive_descriptor* drives;
|
ata::drive_descriptor* drives;
|
||||||
|
|
||||||
|
mutex<> ata_lock;
|
||||||
|
|
||||||
|
mutex<> primary_lock;
|
||||||
|
mutex<> secondary_lock;
|
||||||
|
|
||||||
volatile bool primary_invoked = false;
|
volatile bool primary_invoked = false;
|
||||||
volatile bool secondary_invoked = false;
|
volatile bool secondary_invoked = false;
|
||||||
|
|
||||||
@ -63,35 +71,51 @@ volatile bool secondary_invoked = false;
|
|||||||
//be done with a semaphore
|
//be done with a semaphore
|
||||||
|
|
||||||
void primary_controller_handler(interrupt::syscall_regs*){
|
void primary_controller_handler(interrupt::syscall_regs*){
|
||||||
primary_invoked = true;
|
if(scheduler::is_started()){
|
||||||
|
primary_lock.release();
|
||||||
|
} else {
|
||||||
|
primary_invoked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void secondary_controller_handler(interrupt::syscall_regs*){
|
void secondary_controller_handler(interrupt::syscall_regs*){
|
||||||
secondary_invoked = true;
|
if(scheduler::is_started()){
|
||||||
|
secondary_lock.release();
|
||||||
|
} else {
|
||||||
|
secondary_invoked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ata_wait_irq_primary(){
|
void ata_wait_irq_primary(){
|
||||||
while(!primary_invoked){
|
if(scheduler::is_started()){
|
||||||
asm volatile ("nop");
|
primary_lock.acquire();
|
||||||
asm volatile ("nop");
|
} else {
|
||||||
asm volatile ("nop");
|
while(!primary_invoked){
|
||||||
asm volatile ("nop");
|
asm volatile ("nop");
|
||||||
asm volatile ("nop");
|
asm volatile ("nop");
|
||||||
}
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
}
|
||||||
|
|
||||||
primary_invoked = false;
|
primary_invoked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ata_wait_irq_secondary(){
|
void ata_wait_irq_secondary(){
|
||||||
while(!secondary_invoked){
|
if(scheduler::is_started()){
|
||||||
asm volatile ("nop");
|
secondary_lock.acquire();
|
||||||
asm volatile ("nop");
|
} else {
|
||||||
asm volatile ("nop");
|
while(!secondary_invoked){
|
||||||
asm volatile ("nop");
|
asm volatile ("nop");
|
||||||
asm volatile ("nop");
|
asm volatile ("nop");
|
||||||
}
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
}
|
||||||
|
|
||||||
secondary_invoked = false;
|
secondary_invoked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t wait_for_controller(uint16_t controller, uint8_t mask, uint8_t value, uint16_t timeout){
|
static uint8_t wait_for_controller(uint16_t controller, uint8_t mask, uint8_t value, uint16_t timeout){
|
||||||
@ -127,6 +151,8 @@ bool select_device(ata::drive_descriptor& drive){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool read_write_sector(ata::drive_descriptor& drive, uint64_t start, void* data, bool read){
|
bool read_write_sector(ata::drive_descriptor& drive, uint64_t start, void* data, bool read){
|
||||||
|
std::lock_guard<decltype(ata_lock)> lock(ata_lock);
|
||||||
|
|
||||||
//Select the device
|
//Select the device
|
||||||
if(!select_device(drive)){
|
if(!select_device(drive)){
|
||||||
return false;
|
return false;
|
||||||
@ -324,6 +350,15 @@ void identify(ata::drive_descriptor& drive){
|
|||||||
} //end of anonymous namespace
|
} //end of anonymous namespace
|
||||||
|
|
||||||
void ata::detect_disks(){
|
void ata::detect_disks(){
|
||||||
|
ata_lock.init();
|
||||||
|
|
||||||
|
primary_lock.init(0);
|
||||||
|
secondary_lock.init(0);
|
||||||
|
|
||||||
|
ata_lock.set_name("ata_lock");
|
||||||
|
primary_lock.set_name("ata_primary_lock");
|
||||||
|
secondary_lock.set_name("ata_secondary_lock");
|
||||||
|
|
||||||
drives = new drive_descriptor[4];
|
drives = new drive_descriptor[4];
|
||||||
|
|
||||||
drives[0] = {ATA_PRIMARY, 0xE0, false, MASTER_BIT, false, "", "", ""};
|
drives[0] = {ATA_PRIMARY, 0xE0, false, MASTER_BIT, false, "", "", ""};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user