ahci_drv: basic support for exynos 5

This is a first version of the AHCI driver. It supports SATA HDDs
with UDMA-133 only, up to 6 Gbps and native command queueing.
The more blocks one transfers with one command, the higher is the
chance that the driver produces a fatal handshake error. Nevertheless
the driver is stable with one block per ATA command. Although NCQ is
used the driver doesn't queue multiple commands simultanously.

The driver was tested with a western digital HDD "WDC WD2500BEVS-08VAT1
13.01A13" (250 GB) with hw_arndale (run/ahci) and foc_arndale
(run/ahci, run/l4linux: dd). SSDs were not tested.

Fix #706
This commit is contained in:
Martin Stein 2013-05-18 10:44:38 +02:00 committed by Norman Feske
parent 1c38667a96
commit e164671cd1
3 changed files with 1878 additions and 0 deletions

17
os/lib/mk/exynos5/ahci.mk Normal file
View File

@ -0,0 +1,17 @@
#
# \brief Toolchain configurations for AHCI on Exynos
# \author Martin Stein <martin.stein@genode-labs.com>
# \date 2013-05-17
#
# add C++ sources
SRC_CC += ahci_driver.cc
# add include directories
INC_DIR += $(REP_DIR)/src/drivers/ahci/exynos5
# declare source paths
vpath ahci_driver.cc $(REP_DIR)/src/drivers/ahci/exynos5
# insert configurations that are less specific
include $(REP_DIR)/lib/mk/ahci.inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
/*
* \brief AHCI driver declaration
* \author Martin Stein <martin.stein@genode-labs.com>
* \date 2013-04-10
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _AHCI_DRIVER_H_
#define _AHCI_DRIVER_H_
/* Genode includes */
#include <block/driver.h>
#include <ram_session/ram_session.h>
/**
* AHCI driver
*/
class Ahci_driver : public Block::Driver
{
/* import Genode symbols */
typedef Genode::size_t size_t;
typedef Genode::addr_t addr_t;
typedef Genode::Ram_dataspace_capability Ram_dataspace_capability;
int _ncq_command(size_t const block_nr, size_t const block_cnt,
addr_t const phys, bool const w);
public:
/**
* Constructor
*/
Ahci_driver();
/*****************************
** Block::Driver interface **
*****************************/
size_t block_size();
size_t block_count();
bool dma_enabled() { return 1; }
void write(size_t, size_t, char const *);
void read(size_t, size_t, char *);
Ram_dataspace_capability alloc_dma_buffer(size_t size);
void read_dma(size_t block_nr, size_t block_cnt, addr_t phys)
{
if (_ncq_command(block_nr, block_cnt, phys, 0))
throw Io_error();
}
void write_dma(size_t block_nr, size_t block_cnt, addr_t phys)
{
if (_ncq_command(block_nr, block_cnt, phys, 1))
throw Io_error();
}
};
#endif /* _AHCI_DRIVER_H_ */