Kernel: ATA now uses irqs instead of polling
Reading is now much slower at ~500 kB/s it was around 3 MB/s.
This is probably mostly due semaphore blocking taking atleast
until next reschedule (1 ms itervals). This will be a problem
as long as we are using only single processor.
I could try to use {READ/WRITE}_MULTIPLE commands, but since
most of the disk reads are 2 sectors (inode block size) this
will at most double the speed.
Most efficient speed up would of course be caching disk access
data and inodes overall.
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/SpinLock.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
||||
68
kernel/include/kernel/Storage/ATABus.h
Normal file
68
kernel/include/kernel/Storage/ATABus.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Errors.h>
|
||||
#include <kernel/Semaphore.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
#include <kernel/Storage/ATAController.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class ATADevice;
|
||||
|
||||
class ATABus
|
||||
{
|
||||
public:
|
||||
enum class DeviceType
|
||||
{
|
||||
None,
|
||||
ATA,
|
||||
ATAPI,
|
||||
};
|
||||
|
||||
public:
|
||||
static ATABus* create(ATAController*, uint16_t base, uint16_t ctrl, uint8_t irq);
|
||||
|
||||
BAN::ErrorOr<void> read(ATADevice*, uint64_t, uint8_t, uint8_t*);
|
||||
BAN::ErrorOr<void> write(ATADevice*, uint64_t, uint8_t, const uint8_t*);
|
||||
|
||||
ATAController* controller() { return m_controller; }
|
||||
|
||||
void on_irq();
|
||||
|
||||
private:
|
||||
ATABus(ATAController* controller, uint16_t base, uint16_t ctrl)
|
||||
: m_controller(controller)
|
||||
, m_base(base)
|
||||
, m_ctrl(ctrl)
|
||||
{}
|
||||
void initialize(uint8_t irq);
|
||||
|
||||
void select_device(const ATADevice*);
|
||||
DeviceType identify(const ATADevice*, uint16_t*);
|
||||
|
||||
void block_until_irq();
|
||||
uint8_t device_index(const ATADevice*) const;
|
||||
|
||||
uint8_t io_read(uint16_t);
|
||||
void io_write(uint16_t, uint8_t);
|
||||
void read_buffer(uint16_t, uint16_t*, size_t);
|
||||
void write_buffer(uint16_t, const uint16_t*, size_t);
|
||||
BAN::ErrorOr<void> wait(bool);
|
||||
BAN::Error error();
|
||||
|
||||
private:
|
||||
ATAController* m_controller;
|
||||
const uint16_t m_base;
|
||||
const uint16_t m_ctrl;
|
||||
SpinLock m_lock;
|
||||
Semaphore m_semaphore;
|
||||
|
||||
bool m_has_got_irq { false };
|
||||
|
||||
ATADevice* m_devices[2] { nullptr, nullptr };
|
||||
|
||||
friend class ATAController;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -8,24 +8,24 @@
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class ATADevice;
|
||||
class ATABus;
|
||||
|
||||
class ATAController final : public StorageController
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<ATAController*> create(const PCIDevice&);
|
||||
|
||||
virtual BAN::Vector<StorageDevice*> devices() override;
|
||||
|
||||
uint8_t next_device_index() const;
|
||||
|
||||
private:
|
||||
ATAController() = default;
|
||||
BAN::ErrorOr<void> initialize(const PCIDevice& device);
|
||||
|
||||
BAN::ErrorOr<void> read(ATADevice*, uint64_t, uint8_t, uint8_t*);
|
||||
BAN::ErrorOr<void> write(ATADevice*, uint64_t, uint8_t, const uint8_t*);
|
||||
|
||||
private:
|
||||
SpinLock m_lock;
|
||||
|
||||
friend class ATADevice;
|
||||
ATABus* m_buses[2] { nullptr, nullptr };
|
||||
friend class ATABus;
|
||||
|
||||
public:
|
||||
virtual ino_t ino() const override { return 0; }
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/Storage/ATABus.h>
|
||||
#include <kernel/Storage/StorageDevice.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class ATAController;
|
||||
|
||||
class ATADevice final : public StorageDevice
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<ATADevice*> create(ATAController*, uint16_t, uint16_t, uint8_t);
|
||||
ATADevice(ATABus* bus) : m_bus(bus) { }
|
||||
BAN::ErrorOr<void> initialize(ATABus::DeviceType, const uint16_t*);
|
||||
|
||||
virtual BAN::ErrorOr<void> read_sectors(uint64_t, uint8_t, uint8_t*) override;
|
||||
virtual BAN::ErrorOr<void> write_sectors(uint64_t, uint8_t, const uint8_t*) override;
|
||||
@@ -20,36 +20,10 @@ namespace Kernel
|
||||
BAN::StringView model() const { return m_model; }
|
||||
|
||||
private:
|
||||
ATADevice(ATAController* controller, uint16_t base, uint16_t ctrl, uint8_t index)
|
||||
: m_controller(controller)
|
||||
, m_base(base)
|
||||
, m_ctrl(ctrl)
|
||||
, m_index(index)
|
||||
, m_slave_bit((index & 0x01) << 4)
|
||||
{ }
|
||||
BAN::ErrorOr<void> initialize();
|
||||
ATABus* m_bus;
|
||||
uint8_t m_index;
|
||||
|
||||
uint8_t io_read(uint16_t);
|
||||
void io_write(uint16_t, uint8_t);
|
||||
void read_buffer(uint16_t, uint16_t*, size_t);
|
||||
void write_buffer(uint16_t, const uint16_t*, size_t);
|
||||
BAN::ErrorOr<void> wait(bool);
|
||||
BAN::Error error();
|
||||
|
||||
private:
|
||||
enum class DeviceType
|
||||
{
|
||||
ATA,
|
||||
ATAPI,
|
||||
};
|
||||
|
||||
ATAController* m_controller;
|
||||
const uint16_t m_base;
|
||||
const uint16_t m_ctrl;
|
||||
const uint8_t m_index;
|
||||
const uint8_t m_slave_bit;
|
||||
|
||||
DeviceType m_type;
|
||||
ATABus::DeviceType m_type;
|
||||
uint16_t m_signature;
|
||||
uint16_t m_capabilities;
|
||||
uint32_t m_command_set;
|
||||
@@ -57,7 +31,7 @@ namespace Kernel
|
||||
uint64_t m_lba_count;
|
||||
char m_model[41];
|
||||
|
||||
friend class ATAController;
|
||||
friend class ATABus;
|
||||
|
||||
public:
|
||||
virtual ino_t ino() const override { return m_index; }
|
||||
@@ -68,7 +42,7 @@ namespace Kernel
|
||||
virtual off_t size() const override { return 0; }
|
||||
virtual blksize_t blksize() const override { return sector_size(); }
|
||||
virtual blkcnt_t blocks() const override { return 0; }
|
||||
virtual dev_t dev() const override;
|
||||
virtual dev_t dev() const override { return m_bus->controller()->dev(); }
|
||||
virtual dev_t rdev() const override { return 0x5429; }
|
||||
|
||||
virtual BAN::StringView name() const override { return BAN::StringView(m_device_name, sizeof(m_device_name) - 1); }
|
||||
|
||||
@@ -8,18 +8,7 @@ namespace Kernel
|
||||
class StorageController : public CharacterDevice
|
||||
{
|
||||
public:
|
||||
BAN::Vector<StorageDevice*>& devices() { return m_devices; }
|
||||
const BAN::Vector<StorageDevice*>& devices() const { return m_devices; }
|
||||
|
||||
protected:
|
||||
void add_device(StorageDevice* device)
|
||||
{
|
||||
ASSERT(device);
|
||||
MUST(m_devices.push_back(device));
|
||||
}
|
||||
|
||||
private:
|
||||
BAN::Vector<StorageDevice*> m_devices;
|
||||
virtual BAN::Vector<StorageDevice*> devices() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user