From 76ad585e56e8f7b1da2bb259e41196fba0771154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Thu, 10 Apr 2025 15:45:26 +0200 Subject: [PATCH] Remove Block::Driver interface This commit removes the aged Block::Driver interface that has already been superseded by the Block::Request_stream API for some time now. It is solely used by components whose existence is made redundant, like 'lx_block', or old drivers, like the SD-Card driver for PL180 and old i.MX53/6 systems or the RPi 1, that have not seen active use other than in the nightly CI runs. Fixes #5522. --- repos/os/include/block/component.h | 336 ----------- repos/os/include/block/driver.h | 261 --------- repos/os/run/sd_card.run | 76 --- repos/os/run/sd_card_bench.run | 103 ---- repos/os/src/driver/sd_card/adma2.cc | 65 --- repos/os/src/driver/sd_card/adma2.h | 97 ---- repos/os/src/driver/sd_card/benchmark.h | 166 ------ repos/os/src/driver/sd_card/driver_base.h | 56 -- repos/os/src/driver/sd_card/main.cc | 71 --- repos/os/src/driver/sd_card/pl180/driver.cc | 240 -------- repos/os/src/driver/sd_card/pl180/driver.h | 161 ------ repos/os/src/driver/sd_card/pl180/target.mk | 4 - repos/os/src/driver/sd_card/sd_card.h | 593 -------------------- repos/os/src/driver/sd_card/target.inc | 6 - tool/autopilot.list | 1 - 15 files changed, 2236 deletions(-) delete mode 100644 repos/os/include/block/component.h delete mode 100644 repos/os/include/block/driver.h delete mode 100644 repos/os/run/sd_card.run delete mode 100644 repos/os/run/sd_card_bench.run delete mode 100644 repos/os/src/driver/sd_card/adma2.cc delete mode 100644 repos/os/src/driver/sd_card/adma2.h delete mode 100644 repos/os/src/driver/sd_card/benchmark.h delete mode 100644 repos/os/src/driver/sd_card/driver_base.h delete mode 100644 repos/os/src/driver/sd_card/main.cc delete mode 100644 repos/os/src/driver/sd_card/pl180/driver.cc delete mode 100644 repos/os/src/driver/sd_card/pl180/driver.h delete mode 100644 repos/os/src/driver/sd_card/pl180/target.mk delete mode 100644 repos/os/src/driver/sd_card/sd_card.h delete mode 100644 repos/os/src/driver/sd_card/target.inc diff --git a/repos/os/include/block/component.h b/repos/os/include/block/component.h deleted file mode 100644 index ed93a19a75..0000000000 --- a/repos/os/include/block/component.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * \brief Block-session component - * \author Christian Helmuth - * \author Stefan Kalkowski - * \date 2011-05-20 - */ - -/* - * Copyright (C) 2011-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _INCLUDE__BLOCK__COMPONENT_H_ -#define _INCLUDE__BLOCK__COMPONENT_H_ - -#include -#include -#include -#include -#include -#include - -namespace Block { - - using namespace Genode; - - class Session_component_base; - class Session_component; - class Root; -}; - - -/** - * We have a hen and egg situation that makes this base class necessary. - * The Block::Session_rpc_object construction depends on a dataspace for - * the packet stream. The dataspace on the other hand is constructed by - * the driver, which is created on demand when creating a session. - * When creating the driver, and dataspace outside the Session_component - * constructor within _create_session of the root component, we would have - * to destroy the driver and dataspace within the destructor body of - * Session_component, which will lead to problems, because the packet stream - * destructors will be called after the shared memory already vanished. - */ -class Block::Session_component_base -{ - protected: - - Driver_factory &_driver_factory; - Driver &_driver; - Driver::Dma_buffer _rq; - - Session_component_base(Driver_factory &factory, size_t tx_buf_size) - : - _driver_factory(factory), - _driver(*factory.create()), - _rq(_driver.alloc_dma_buffer(tx_buf_size, UNCACHED)) - { } - - ~Session_component_base() - { - _driver.free_dma_buffer(_rq.ds); - _driver_factory.destroy(&_driver); - } -}; - - -class Block::Session_component : public Block::Session_component_base, - public Block::Driver_session -{ - private: - - addr_t _rq_phys; - Signal_handler _sink_ack; - Signal_handler _sink_submit; - bool _req_queue_full = false; - bool _ack_queue_full = false; - Packet_descriptor _p_to_handle { }; - unsigned _p_in_fly; - Info const _info { _driver.info() }; - bool const _writeable; - - /** - * Acknowledge a packet already handled - */ - inline void _ack_packet(Packet_descriptor &packet) - { - if (!tx_sink()->ready_to_ack()) - error("not ready to ack!"); - - tx_sink()->acknowledge_packet(packet); - _p_in_fly--; - } - - /** - * Range check packet request - */ - inline bool _range_check(Packet_descriptor &p) { - return p.block_number() + p.block_count() - 1 - < _info.block_count; } - - /** - * Handle a single request - */ - void _handle_packet(Packet_descriptor packet) - { - _p_to_handle = packet; - _p_to_handle.succeeded(false); - - /* ignore invalid packets */ - bool const valid = _range_check(_p_to_handle) - && tx_sink()->packet_valid(packet) - && aligned(packet.offset(), (unsigned)_info.align_log2); - if (!valid) { - _ack_packet(_p_to_handle); - return; - } - - try { - switch (_p_to_handle.operation()) { - - case Block::Packet_descriptor::READ: - if (_driver.dma_enabled()) - _driver.read_dma(packet.block_number(), - packet.block_count(), - _rq_phys + packet.offset(), - _p_to_handle); - else - _driver.read(packet.block_number(), - packet.block_count(), - tx_sink()->packet_content(packet), - _p_to_handle); - break; - - case Block::Packet_descriptor::WRITE: - if (!_writeable) { - _ack_packet(_p_to_handle); - break; - } - if (_driver.dma_enabled()) - _driver.write_dma(packet.block_number(), - packet.block_count(), - _rq_phys + packet.offset(), - _p_to_handle); - else - _driver.write(packet.block_number(), - packet.block_count(), - tx_sink()->packet_content(packet), - _p_to_handle); - break; - - case Block::Packet_descriptor::SYNC: - - /* perform (blocking) sync */ - _driver.sync(); - - _p_to_handle.succeeded(true); - _ack_packet(_p_to_handle); - _p_to_handle = Packet_descriptor(); - break; - - case Block::Packet_descriptor::TRIM: - - /* trim is a nop */ - _p_to_handle.succeeded(true); - _ack_packet(_p_to_handle); - _p_to_handle = Packet_descriptor(); - break; - - default: - throw Driver::Io_error(); - } - } catch (Driver::Request_congestion) { - _req_queue_full = true; - } catch (Driver::Io_error) { - _ack_packet(_p_to_handle); - } catch (Genode::Packet_descriptor::Invalid_packet) { - _p_to_handle = Packet_descriptor(); - Genode::error("dropping invalid Block packet"); - } - } - - /** - * Called whenever a signal from the packet-stream interface triggered - */ - void _signal() - { - /* - * as long as more packets are available, and we're able to ack - * them, and the driver's request queue isn't full, - * direct the packet request to the driver backend - */ - for (_ack_queue_full = (_p_in_fly >= tx_sink()->ack_slots_free()); - !_req_queue_full && !_ack_queue_full - && tx_sink()->packet_avail(); - _ack_queue_full = (++_p_in_fly >= tx_sink()->ack_slots_free())) - _handle_packet(tx_sink()->get_packet()); - } - - public: - - /** - * Constructor - * - * \param driver_factory factory to create and destroy driver objects - * \param ep entrypoint handling this session component - * \param buf_size size of packet-stream payload buffer - */ - Session_component(Driver_factory &driver_factory, - Genode::Entrypoint &ep, - Genode::Env::Local_rm &rm, - size_t buf_size, - bool writeable) - : Session_component_base(driver_factory, buf_size), - Driver_session(rm, _rq.ds, ep.rpc_ep()), - _rq_phys(_rq.dma_addr), - _sink_ack(ep, *this, &Session_component::_signal), - _sink_submit(ep, *this, &Session_component::_signal), - _req_queue_full(false), - _p_in_fly(0), - _writeable(writeable && _info.writeable) - { - _tx.sigh_ready_to_ack(_sink_ack); - _tx.sigh_packet_avail(_sink_submit); - - _driver.session(this); - } - - ~Session_component() { _driver.session(nullptr); } - - /** - * Acknowledges a packet processed by the driver to the client - * - * \param packet the packet to acknowledge - * \param success indicated whether the processing was successful - * - * \throw Ack_congestion - */ - void ack_packet(Packet_descriptor &packet, bool success) override - { - packet.succeeded(success); - _ack_packet(packet); - - if (!_req_queue_full && !_ack_queue_full) - return; - - /* - * when the driver's request queue was full, - * handle last unprocessed packet taken out of submit queue - */ - if (_req_queue_full) { - _req_queue_full = false; - _handle_packet(_p_to_handle); - } - - /* resume packet processing */ - _signal(); - } - - - /******************************* - ** Block session interface ** - *******************************/ - - Info info() const override { return _driver.info(); } -}; - - -/** - * Root component, handling new session requests - */ -class Block::Root : public Genode::Root_component -{ - private: - - Driver_factory &_driver_factory; - Genode::Entrypoint &_ep; - Genode::Env::Local_rm &_rm; - bool const _writeable; - - protected: - - /** - * Always returns the singleton block-session component - */ - Session_component *_create_session(const char *args) override - { - size_t ram_quota = - Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); - size_t tx_buf_size = - Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); - - /* - * Check if donated ram quota suffices for both - * communication buffers. Also check both sizes separately - * to handle a possible overflow of the sum of both sizes. - */ - if (tx_buf_size > ram_quota) { - error("insufficient 'ram_quota', got ", ram_quota, ", need ", - tx_buf_size); - throw Insufficient_ram_quota(); - } - - bool writeable = _writeable - ? Arg_string::find_arg(args, "writeable").bool_value(true) - : false; - - return new (md_alloc()) Session_component(_driver_factory, - _ep, _rm, tx_buf_size, - writeable); - } - - public: - - /** - * Constructor - * - * \param ep entrypoint handling this root component - * \param md_alloc allocator to allocate session components - * \param rm region map - * \param driver_factory factory to create and destroy driver backend - */ - Root(Genode::Entrypoint &ep, - Allocator &md_alloc, - Genode::Env::Local_rm &rm, - Driver_factory &driver_factory, - bool writeable) - : - Root_component(ep, md_alloc), - _driver_factory(driver_factory), _ep(ep), _rm(rm), _writeable(writeable) - { } -}; - -#endif /* _INCLUDE__BLOCK__COMPONENT_H_ */ diff --git a/repos/os/include/block/driver.h b/repos/os/include/block/driver.h deleted file mode 100644 index 4a061e9444..0000000000 --- a/repos/os/include/block/driver.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - * \brief Block-driver interface - * \author Christian Helmuth - * \author Sebastian Sumpf - * \author Stefan kalkowski - * \date 2011-05-23 - */ - -/* - * Copyright (C) 2011-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _INCLUDE__BLOCK__DRIVER_H_ -#define _INCLUDE__BLOCK__DRIVER_H_ - -#include -#include -#include -#include -#include - -namespace Block { - class Driver_session_base; - class Driver_session; - class Driver; - struct Driver_factory; -}; - - -struct Block::Driver_session_base : Genode::Interface -{ - /** - * Acknowledges a packet processed by the driver to the client - * - * \param packet the packet to acknowledge - * \param success indicated whether the processing was successful - * - * \throw Ack_congestion - */ - virtual void ack_packet(Packet_descriptor &packet, - bool success) = 0; -}; - - -class Block::Driver_session : public Driver_session_base, - public Block::Session_rpc_object -{ - public: - - /** - * Constructor - * - * \param rm region map of local address space, used to attach - * the packet-stream buffer to the local address space - * \param tx_ds dataspace used as communication buffer - * for the tx packet stream - * \param ep entry point used for packet-stream channel - */ - Driver_session(Genode::Env::Local_rm &rm, - Genode::Dataspace_capability tx_ds, - Genode::Rpc_entrypoint &ep) - : Session_rpc_object(rm, tx_ds, ep) { } -}; - - -/** - * Interface to be implemented by the device-specific driver code - */ -class Block::Driver : Genode::Interface -{ - private: - - /* - * Noncopyable - */ - Driver(Driver const &); - Driver &operator = (Driver const &); - - Genode::Ram_allocator &_ram; - - Driver_session_base *_session = nullptr; - - public: - - /** - * Exceptions - */ - class Io_error : public ::Genode::Exception { }; - class Request_congestion : public ::Genode::Exception { }; - - /** - * Constructor - */ - Driver(Genode::Ram_allocator &ram) : _ram(ram) { } - - /** - * Destructor - */ - virtual ~Driver() { } - - /** - * Request block-device information - */ - virtual Session::Info info() const = 0; - - /** - * Read from medium - * - * \param block_number number of first block to read - * \param block_count number of blocks to read - * \param buffer output buffer for read request - * \param packet packet descriptor from the client - * - * \throw Request_congestion - * - * Note: should be overridden by DMA non-capable devices - */ - virtual void read(sector_t /* block_number */, - Genode::size_t /* block_count */, - char * /* buffer */, - Packet_descriptor & /* packet */) { - throw Io_error(); } - - /** - * Write to medium - * - * \param block_number number of first block to write - * \param block_count number of blocks to write - * \param buffer buffer for write request - * \param packet packet descriptor from the client - * - * \throw Request_congestion - * - * Note: should be overridden by DMA non-capable, non-ROM devices - */ - virtual void write(sector_t /* block_number */, - Genode::size_t /* block_count */, - const char * /* buffer */, - Packet_descriptor & /* packet */) { - throw Io_error(); } - - /** - * Read from medium using DMA - * - * \param block_number number of first block to read - * \param block_count number of blocks to read - * \param phys phyiscal address of read buffer - * \param packet packet descriptor from the client - * - * \throw Request_congestion - * - * Note: should be overridden by DMA capable devices - */ - virtual void read_dma(sector_t /* block_number */, - Genode::size_t /* block_count */, - Genode::addr_t /* phys */, - Packet_descriptor & /* packet */) { - throw Io_error(); } - - /** - * Write to medium using DMA - * - * \param block_number number of first block to write - * \param block_count number of blocks to write - * \param phys physical address of write buffer - * \param packet packet descriptor from the client - * - * \throw Request_congestion - * - * Note: should be overridden by DMA capable, non-ROM devices - */ - virtual void write_dma(sector_t /* block_number */, - Genode::size_t /* block_count */, - Genode::addr_t /* phys */, - Packet_descriptor & /* packet */) { - throw Io_error(); } - - /** - * Check if DMA is enabled for driver - * - * \return true if DMA is enabled, false otherwise - * - * Note: has to be overriden by DMA-capable devices - */ - virtual bool dma_enabled() { return false; } - - struct Dma_buffer - { - Genode::Ram_dataspace_capability ds; - Genode::addr_t dma_addr; - }; - - /** - * Allocate buffer which is suitable for DMA. - * - * Note: has to be overriden by DMA-capable devices - */ - virtual Dma_buffer alloc_dma_buffer(Genode::size_t, Genode::Cache) = 0; - - /** - * Free buffer which is suitable for DMA. - * - * Note: has to be overriden by DMA-capable devices - */ - virtual void free_dma_buffer(Genode::Ram_dataspace_capability c) { - return _ram.free(c); } - - /** - * Synchronize with device. - * - * Note: should be overriden by (e.g. intermediate) components, - * which cache data - */ - virtual void sync() {} - - /** - * Informs the driver that the client session was closed - * - * Note: drivers with state (e.g. asynchronously working) - * should override this method, and reset their internal state - */ - virtual void session_invalidated() { } - - /** - * Set single session component of the driver - * - * Session might get used to acknowledge requests. - */ - void session(Driver_session_base *session) { - if (!(_session = session)) session_invalidated(); } - - /** - * Acknowledge a packet after processing finished to the client - * - * \param p packet to acknowledge - */ - void ack_packet(Packet_descriptor &p, bool success = true) { - if (_session) _session->ack_packet(p, success); } -}; - - -/** - * Interface for constructing the driver object - */ -struct Block::Driver_factory : Genode::Interface -{ - /** - * Construct new driver - */ - virtual Driver *create() = 0; - - /** - * Destroy driver - */ - virtual void destroy(Driver *driver) = 0; -}; - -#endif /* _BLOCK__DRIVER_H_ */ diff --git a/repos/os/run/sd_card.run b/repos/os/run/sd_card.run deleted file mode 100644 index 5c05b40908..0000000000 --- a/repos/os/run/sd_card.run +++ /dev/null @@ -1,76 +0,0 @@ -assert {[have_board pbxa9]} - -create_boot_directory -import_from_depot [depot_user]/src/[base_src] \ - [depot_user]/src/init \ - [depot_user]/src/platform \ - [depot_user]/raw/pbxa9-devices - -build { driver/sd_card app/block_tester } - -install_config { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } - -build_boot_image [build_artifacts] - -set disk_image "bin/sd_card.img" -if { [file exists $disk_image] == 0 } then { - # create empty block device file - catch { exec dd if=/dev/zero of=$disk_image bs=1M count=512 } -} -append qemu_args "-drive file=$disk_image,format=raw,if=sd,cache=writeback -nographic " -run_genode_until {.*child "block_tester" exited with exit value 0.*\n} 30 - -exec rm $disk_image - -# vi: set ft=tcl : diff --git a/repos/os/run/sd_card_bench.run b/repos/os/run/sd_card_bench.run deleted file mode 100644 index 7b763c9981..0000000000 --- a/repos/os/run/sd_card_bench.run +++ /dev/null @@ -1,103 +0,0 @@ -# -# Check for platform support -# -if {[have_cmd_switch --autopilot]} { - assert {![have_board virt_qemu_riscv] && ![have_board rpi]} \ - "Autopilot mode is not supported on this platform." -} - -proc buffer_size_kib {} { - if {[have_board pbxa9]} { return [expr 12 * 1024] } - if {[have_board imx6q_sabrelite]} { return [expr 1024] } - if {[have_board imx53_qsb]} { return [expr 1024] } - if {[have_board imx53_qsb_tz]} { return [expr 1024] } - if {[have_board rpi]} { return [expr 4 * 1024] } - assert {false} "Run script is not supported on this platform." -} - -proc sd_card {} { - if {[have_board pbxa9]} { return pl180_sd_card } - if {[have_board imx6q_sabrelite]} { return imx6_sd_card } - if {[have_board imx53_qsb]} { return imx53_sd_card } - if {[have_board imx53_qsb_tz]} { return imx53_sd_card } - if {[have_board rpi]} { return rpi_sd_card } - assert {false} "Run script is not supported on this platform." -} - -create_boot_directory -import_from_depot [depot_user]/src/[base_src] \ - [depot_user]/src/init \ - [depot_user]/src/platform - -install_config { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } - -file copy [select_from_repositories board/[board]/devices] [run_dir]/genode/devices - -build { driver/sd_card } - -build_boot_image [build_artifacts] - - -# -# Run and evaluate the test -# -# If we run on qemu, provide a virtual disk -# - -set disk_image "bin/sd_card.img" -if {[have_include power_on/qemu]} { - - if { [file exists $disk_image] == 0 } then { - catch { exec dd if=/dev/zero of=$disk_image bs=1M count=512 } } - - append qemu_args "-drive file=$disk_image,format=raw,if=sd,cache=writeback " - append qemu_args "-nographic " -} - -run_genode_until "--- SD card benchmark finished ---" 120 - -if {[have_include power_on/qemu]} { - if { [file exists $disk_image] != 0 } then { - exec rm -f $disk_image - } -} diff --git a/repos/os/src/driver/sd_card/adma2.cc b/repos/os/src/driver/sd_card/adma2.cc deleted file mode 100644 index 5eec9355a0..0000000000 --- a/repos/os/src/driver/sd_card/adma2.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* - * \brief Advanced DMA 2 - * \author Martin Stein - * \date 2015-02-05 - */ - -/* - * Copyright (C) 2015-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include -#include - -/* local includes */ -#include - -using namespace Adma2; - - -Table::Table(Platform::Connection &platform) -: - _ds(platform, _ds_size, UNCACHED), - _base_virt(_ds.local_addr()) -{ } - - -int Table::setup_request(size_t const size, addr_t const buffer_phys) -{ - /* sanity check */ - static size_t constexpr max_size = _max_desc * Desc::Length::max; - if (size > max_size) { - Genode::error("block request too large"); - return -1; - } - /* install new descriptors till they cover all requested bytes */ - addr_t consumed = 0; - for (int index = 0; consumed < size; index++) { - - /* clamp current request to maximum request size */ - size_t const remaining = size - consumed; - size_t const curr = min(Desc::Length::max, remaining); - - /* assemble new descriptor */ - Desc::access_t desc = 0; - Desc::Address::set(desc, buffer_phys + consumed); - Desc::Length::set(desc, curr); - Desc::Act1::set(desc, 0); - Desc::Act2::set(desc, 1); - Desc::Valid::set(desc, 1); - - /* let last descriptor generate transfer-complete signal */ - if (consumed + curr == size) { Desc::End::set(desc, 1); } - - /* install and account descriptor */ - _base_virt[index] = desc; - consumed += curr; - } - /* ensure that all descriptor writes were actually executed */ - Genode::memory_barrier(); - return 0; -} diff --git a/repos/os/src/driver/sd_card/adma2.h b/repos/os/src/driver/sd_card/adma2.h deleted file mode 100644 index 3f7797114b..0000000000 --- a/repos/os/src/driver/sd_card/adma2.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * \brief Advanced DMA 2 - * \author Martin Stein - * \date 2015-02-05 - */ - -/* - * Copyright (C) 2015-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _ADMA2_H_ -#define _ADMA2_H_ - -/* Genode includes */ -#include -#include - -namespace Adma2 -{ - using namespace Genode; - - class Desc; - class Table; -} - -/** - * Descriptor layout - */ -struct Adma2::Desc : Register<64> -{ - struct Valid : Bitfield<0, 1> { }; - struct End : Bitfield<1, 1> { }; - struct Int : Bitfield<2, 1> { }; - struct Act1 : Bitfield<4, 1> { }; - struct Act2 : Bitfield<5, 1> { }; - struct Length : Bitfield<16, 16> - { - /* - * According to the 'SD Specifications, Part A2, SD Host - * Controller, Simplified Specification, Version 2.00, February 8, - * 2007, Table 1-10', a maximum length of 65536 bytes is achieved - * by value 0. However, if we do so, the completion host-signal - * times out now and then. Thus, we use the next lower possible - * value. - */ - static constexpr addr_t align_log2 = 2; - static constexpr size_t max = (1 << WIDTH) - (1 << align_log2); - }; - struct Address : Bitfield<32, 32> { }; -}; - - -/** - * Descriptor table - */ -class Adma2::Table -{ - private: - - static size_t constexpr _max_desc = 1024; - static size_t constexpr _ds_size = _max_desc * sizeof(Desc::access_t); - - Platform::Dma_buffer _ds; - Desc::access_t * const _base_virt; - - /* - * Noncopyable - */ - Table(Table const &); - Table &operator = (Table const &); - - public: - - Table(Platform::Connection &platform); - - /** - * Marshal descriptors according to block request - * - * \param size request size in bytes - * \param buffer_phys physical base of transfer buffer - * - * \retval 0 success - * \retval -1 error - */ - int setup_request(size_t const size, addr_t const buffer_phys); - - /* - * Accessors - */ - - addr_t base_dma() const { return _ds.dma_addr(); } -}; - -#endif /* _ADMA2_H_ */ diff --git a/repos/os/src/driver/sd_card/benchmark.h b/repos/os/src/driver/sd_card/benchmark.h deleted file mode 100644 index c336a43e28..0000000000 --- a/repos/os/src/driver/sd_card/benchmark.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * \brief SD-card benchmark - * \author Norman Feske - * \author Martin Stein - * \date 2012-07-19 - */ - -/* - * Copyright (C) 2012-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include -#include -#include -#include - -/* local includes */ -#include - -using namespace Genode; - - -struct Benchmark -{ - using Packet_descriptor = Block::Packet_descriptor; - - struct Block_operation_failed : Exception { }; - - enum Operation { READ, WRITE }; - - struct Driver_session : Block::Driver_session_base - { - Signal_transmitter sig; - unsigned long nr_of_acks { 0 }; - - Driver_session(Signal_context_capability sig) : sig(sig) { } - - void ack_packet(Packet_descriptor &, bool success) override - { - if (!success) { - throw Block_operation_failed(); } - nr_of_acks++; - sig.submit(); - } - }; - - Env &env; - Platform::Connection platform { env }; - Attached_rom_dataspace config { env, "config" }; - Packet_descriptor pkt { }; - uint64_t time_before_ms { }; - Timer::Connection timer { env }; - Operation operation { READ }; - Signal_handler ack_handler { env.ep(), *this, &Benchmark::update_state }; - Driver_session drv_session { ack_handler }; - Sd_card::Driver drv { env, platform }; - size_t const buf_size_kib { config.xml().attribute_value("buffer_size_kib", - (size_t)0) }; - size_t const buf_size { buf_size_kib * 1024 }; - Platform::Dma_buffer buf { platform, buf_size, UNCACHED }; - char *buf_virt { buf.local_addr() }; - size_t buf_off_done { 0 }; - size_t buf_off_pend { 0 }; - unsigned req_size_id { 0 }; - size_t req_sizes[9] { 512, 1024, 1024 * 2, 1024 * 4, - 1024 * 8, 1024 * 16, 1024 * 32, - 1024 * 64, 1024 * 128 }; - - size_t req_size() const { return req_sizes[req_size_id]; } - - void update_state() - { - /* raise done counter and check if the buffer is full */ - buf_off_done += drv_session.nr_of_acks * req_size(); - drv_session.nr_of_acks = 0; - if (buf_off_done == buf_size) { - - /* print stats for the current request size */ - uint64_t const time_after_ms = timer.elapsed_ms(); - uint64_t const duration_ms = time_after_ms - time_before_ms; - size_t const kib_per_sec = (size_t)((1000 * buf_size_kib) - / duration_ms); - log(" duration: ", duration_ms, " ms"); - log(" amount: ", buf_size_kib, " KiB"); - log(" throughput: ", kib_per_sec, " KiB/sec"); - - /* go to next request size */ - buf_off_pend = 0; - buf_off_done = 0; - req_size_id++; - - /* check if we have done all request sizes for an operation */ - if (req_size_id == sizeof(req_sizes)/sizeof(req_sizes[0])) { - - /* go to next operation or end the test */ - log(""); - req_size_id = 0; - switch (operation) { - case READ: - operation = WRITE; - log("-- writing to SD card --"); - break; - case WRITE: - log("--- SD card benchmark finished ---"); - return; - } - } - log(" request size ", req_size(), " bytes"); - time_before_ms = timer.elapsed_ms(); - } - /* issue as many requests for the current request size as possible */ - try { - size_t const block_size = drv.info().block_size; - size_t const cnt = req_size() / block_size; - for (; buf_off_pend < buf_size; buf_off_pend += req_size()) { - - /* calculate block offset */ - addr_t const nr = buf_off_pend / block_size; - - if (drv.dma_enabled()) { - - /* request with DMA */ - addr_t const phys = buf.dma_addr() + buf_off_pend; - switch (operation) { - case READ: drv.read_dma(nr, cnt, phys, pkt); break; - case WRITE: drv.write_dma(nr, cnt, phys, pkt); break; } - - } else { - - /* request without DMA */ - char *const virt = buf_virt + buf_off_pend; - switch (operation) { - case READ: drv.read(nr, cnt, virt, pkt); break; - case WRITE: drv.write(nr, cnt, virt, pkt); break; } - } - } - } catch (Block::Driver::Request_congestion) { } - } - - Benchmark(Env &env) : env(env) - { - log(""); - log("--- SD card benchmark (", drv.dma_enabled() ? "with" : "no", " DMA) ---"); - - drv.session(&drv_session); - - /* start issuing requests */ - log(""); - log("-- reading from SD card --"); - log(" request size ", req_size(), " bytes"); - time_before_ms = timer.elapsed_ms(); - update_state(); - } - - private: - - /* - * Noncopyable - */ - Benchmark(Benchmark const &); - Benchmark &operator = (Benchmark const &); -}; diff --git a/repos/os/src/driver/sd_card/driver_base.h b/repos/os/src/driver/sd_card/driver_base.h deleted file mode 100644 index e64343b42e..0000000000 --- a/repos/os/src/driver/sd_card/driver_base.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * \brief Generic parts of an SD card block-driver - * \author Norman Feske - * \author Timo Wischer - * \author Martin Stein - * \date 2017-01-03 - */ - -/* - * Copyright (C) 2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _DRIVER_BASE_H_ -#define _DRIVER_BASE_H_ - -/* Genode includes */ -#include - -/* local includes */ -#include - -namespace Sd_card { class Driver_base; } - - -class Sd_card::Driver_base : public Block::Driver, - protected Host_controller -{ - protected: - - Genode::size_t _block_size() const { return 512; } - - Block::sector_t _block_count() const { - return card_info().capacity_mb() * 1024 * 2; } - - public: - - Driver_base(Genode::Ram_allocator &ram) - : Block::Driver(ram) { } - - /******************* - ** Block::Driver ** - *******************/ - - Block::Session::Info info() const override - { - return { .block_size = _block_size(), - .block_count = _block_count(), - .align_log2 = Genode::log2(_block_size()), - .writeable = true }; - } -}; - -#endif /* _DRIVER_BASE_H_ */ diff --git a/repos/os/src/driver/sd_card/main.cc b/repos/os/src/driver/sd_card/main.cc deleted file mode 100644 index 7cca85968d..0000000000 --- a/repos/os/src/driver/sd_card/main.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * \brief SD-card driver - * \author Martin Stein - * \author Sebastian Sumpf - * \date 2013-03-06 - */ - -/* - * Copyright (C) 2013-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include -#include -#include -#include -#include - -/* local includes */ -#include -#include - -using namespace Genode; - -struct Main -{ - Env & env; - Heap heap { env.ram(), env.rm() }; - Platform::Connection platform { env }; - - struct Factory : Block::Driver_factory - { - Env & env; - Heap & heap; - Platform::Connection & platform; - - Factory(Env &env, Heap &heap, Platform::Connection &platform) - : env(env), heap(heap), platform(platform) { } - - Block::Driver *create() override { - return new (&heap) Sd_card::Driver(env, platform); } - - void destroy(Block::Driver *driver) override { - Genode::destroy(&heap, static_cast(driver)); } - - } factory { env, heap, platform }; - - Block::Root root { env.ep(), heap, env.rm(), factory, true }; - - Main(Genode::Env &env) : env(env) - { - Genode::log("--- SD card driver ---"); - env.parent().announce(env.ep().manage(root)); - } -}; - - -void Component::construct(Genode::Env &env) -{ - bool benchmark = false; - try { - Attached_rom_dataspace config { env, "config" }; - benchmark = config.xml().attribute_value("benchmark", false); - } catch(...) {} - - if (benchmark) static Benchmark bench(env); - else static Main main(env); -} diff --git a/repos/os/src/driver/sd_card/pl180/driver.cc b/repos/os/src/driver/sd_card/pl180/driver.cc deleted file mode 100644 index 1c80fa449b..0000000000 --- a/repos/os/src/driver/sd_card/pl180/driver.cc +++ /dev/null @@ -1,240 +0,0 @@ -/* - * \brief PL180-specific implementation of the Block::Driver interface - * \author Christian Helmuth - * \author Martin Stein - * \date 2011-05-19 - */ - -/* - * Copyright (C) 2011-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* local includes */ -#include - -using namespace Genode; -using namespace Sd_card; - - -void Driver::_write_command(unsigned cmd_index, bool resp) -{ - enum Bits { - CmdIndex = 0x3f, - Response = 1 << 6, - Enable = 1 << 10 - }; - cmd_index = (cmd_index & CmdIndex) | Enable; - cmd_index |= (resp ? Response : 0); - - _write_reg(Command, cmd_index); - - while (!(_read_reg(Status) & (CmdRespEnd | CmdSent))) ; -} - - -void Driver::_request(unsigned char cmd, - unsigned *out_resp) -{ - _write_reg(Argument, 0); - _write_command(cmd, (out_resp != 0)); - if (out_resp) - *out_resp = _read_reg(Response0); - _clear_status(); -} - - -void Driver::_request(unsigned char cmd, - unsigned arg, - unsigned *out_resp) -{ - _write_reg(Argument, arg); - _write_command(cmd, (out_resp != 0)); - if (out_resp) - *out_resp = _read_reg(Response0); - _clear_status(); -} - - -void Driver::_read_request(unsigned char cmd, - unsigned arg, - unsigned length, - unsigned *out_resp) -{ - /* - * FIXME on real hardware the blocksize must be written into - * DataCtrl:BlockSize. - */ - enum { CTRL_ENABLE = 0x01, CTRL_READ = 0x02 }; - - _write_reg(DataLength, length); - _write_reg(DataCtrl, CTRL_ENABLE | CTRL_READ); - - _write_reg(Argument, arg); - _write_command(cmd, (out_resp != 0)); - if (out_resp) - *out_resp = _read_reg(Response0); - _clear_status(); -} - - -void Driver::_write_request(unsigned char cmd, - unsigned arg, - unsigned length, - unsigned *out_resp) -{ - /* - * FIXME on real hardware the blocksize must be written into - * DataCtrl:BlockSize. - */ - enum { CTRL_ENABLE = 0x01 }; - - _write_reg(DataLength, length); - _write_reg(DataCtrl, CTRL_ENABLE); - - _write_reg(Argument, arg); - _write_command(cmd, (out_resp != 0)); - if (out_resp) - *out_resp = _read_reg(Response0); - _clear_status(); -} - - -void Driver::_read_data(unsigned length, - char *out_buffer) -{ - unsigned *buf = reinterpret_cast(out_buffer); - for (unsigned count = 0; count < length / 4; ) { - /* - * The FIFO contains at least 'remainder - FifoCnt' words. - */ - int chunk = length / 4 - count - _read_reg(FifoCnt); - count += chunk; - for ( ; chunk > 0; --chunk) - buf[count - chunk] = _read_reg(FIFO); - } - _clear_status(); -} - - -void Driver::_write_data(unsigned length, - char const *buffer) -{ - enum { FIFO_SIZE = 16 }; - - unsigned const *buf = reinterpret_cast(buffer); - for (unsigned count = 0; count < length / 4; ) { - uint32_t status; - while (!((status = _read_reg(Status)) & TxFifoHalfEmpty)) ; - - int chunk = (status & TxFifoEmpty) ? FIFO_SIZE : FIFO_SIZE / 2; - count += chunk; - for ( ; chunk > 0; --chunk) - _write_reg(FIFO, buf[count - chunk]); - } - _clear_status(); -} - - -Driver::Driver(Env &env, Platform::Connection & platform) -: - Block::Driver(env.ram()), - Platform::Device(platform), - Platform::Device::Mmio(*this, { 0 }), - _platform(platform), - _timer(env) -{ - enum { POWER_UP = 2, POWER_ON = 3 }; - - _write_reg(Power, POWER_UP); - _timer.msleep(10); - _write_reg(Power, POWER_ON); - _timer.msleep(10); - _clear_status(); - - /* CMD0: go idle state */ - _request(0, 0); - - /* - * CMD8: send interface condition - * - * XXX only one hard-coded value currently. - */ - unsigned resp; - _request(8, 0x1aa, &resp); - - /* - * ACMD41: card send operating condition - * - * This is an application-specific command and, therefore, consists - * of prefix command CMD55 + CMD41. - */ - _request(55, 0, &resp); - _request(41, 0x4000, &resp); - - /* CMD2: all send card identification (CID) */ - _request(2, &resp); - - /* CMD3: send relative card address (RCA) */ - _request(3, &resp); - unsigned short rca = (short)(resp >> 16); - - /* - * Now, the card is in transfer mode... - */ - - /* CMD7: select card */ - _request(7, rca << 16, &resp); -} - - -Driver::~Driver() { } - - -void Driver::read(Block::sector_t block_number, - size_t block_count, - char *buffer, - Block::Packet_descriptor &packet) -{ - unsigned resp; - unsigned length = _block_size; - - for (size_t i = 0; i < block_count; ++i) { - /* - * CMD17: read single block - * - * SDSC cards use a byte address as argument while SDHC/SDSC uses a - * block address here. - */ - _read_request(17, (uint32_t)((block_number + i) * _block_size), - length, &resp); - _read_data(length, buffer + (i * _block_size)); - } - ack_packet(packet); -} - - -void Driver::write(Block::sector_t block_number, - size_t block_count, - char const *buffer, - Block::Packet_descriptor &packet) -{ - unsigned resp; - unsigned length = _block_size; - - for (size_t i = 0; i < block_count; ++i) { - /* - * CMD24: write single block - * - * SDSC cards use a byte address as argument while SDHC/SDSC uses a - * block address here. - */ - _write_request(24, (uint32_t)((block_number + i) * _block_size), - length, &resp); - _write_data(length, buffer + (i * _block_size)); - } - ack_packet(packet); -} - diff --git a/repos/os/src/driver/sd_card/pl180/driver.h b/repos/os/src/driver/sd_card/pl180/driver.h deleted file mode 100644 index 564876fdb5..0000000000 --- a/repos/os/src/driver/sd_card/pl180/driver.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * \brief PL180-specific implementation of the Block::Driver interface - * \author Christian Helmuth - * \author Martin Stein - * \date 2011-05-19 - */ - -/* - * Copyright (C) 2011-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _DRIVER_H_ -#define _DRIVER_H_ - -/* local includes */ -#include -#include -#include - -namespace Sd_card { - - using namespace Genode; - - class Driver; -} - - -class Sd_card::Driver : public Block::Driver, - private Platform::Device, - private Platform::Device::Mmio<0> -{ - private: - - /* - * Noncopyable - */ - Driver(Driver const &); - Driver &operator = (Driver const &); - - enum Register { - Power = 0x000, /* power control */ - Argument = 0x008, /* argument for command */ - Command = 0x00c, /* command index and type */ - Response0 = 0x014, /* command response (card status, read only) */ - DataLength = 0x028, /* number of bytes in data transfer (block size) */ - DataCtrl = 0x02c, /* data transfer control */ - Status = 0x034, /* controller status flags (read only) */ - Clear = 0x038, /* status clear (write only) */ - Mask0 = 0x03c, /* interrupt 0 mask */ - Mask1 = 0x040, /* interrupt 1 mask */ - FifoCnt = 0x048, /* data FIFO counter (in words, read only) */ - FIFO = 0x080, /* data FIFO */ - }; - - enum Flag { - CmdCrcFail = 0x000001, /* command response received (CRC failed) */ - DataCrcFail = 0x000002, /* data block sent/received (CRC failed) */ - CmdTimeOut = 0x000004, /* command response timeout */ - DataTimeOut = 0x000008, /* data timeout */ - TxUnderrun = 0x000010, /* tx fifo underrun */ - RxUnderrun = 0x000020, /* rx fifo underrun */ - CmdRespEnd = 0x000040, /* command response received (CRC ok) */ - CmdSent = 0x000080, /* command sent (no response required) */ - DataEnd = 0x000100, /* data counter zero */ - StartBitErr = 0x000200, /* start bit not detected */ - DataBlockEnd = 0x000400, /* data block sent/received (CRC ok) */ - CmdActive = 0x000800, /* command transfer in progress */ - TxActive = 0x001000, /* data tx in progress */ - RxActive = 0x002000, /* data rx in progress */ - TxFifoHalfEmpty = 0x004000, - RxFifoHalfFull = 0x008000, - TxFifoFull = 0x010000, - RxFifoFull = 0x020000, - TxFifoEmpty = 0x040000, - RxFifoEmpty = 0x080000, - TxDataAvlbl = 0x100000, - RxDataAvlbl = 0x200000, - }; - - Platform::Connection & _platform; - Timer::Connection _timer; - - uint32_t volatile *_base { local_addr() }; - - uint32_t _read_reg(Register reg) const { return _base[reg >> 2]; } - - void _write_reg(Register reg, uint32_t v) { _base[reg >> 2] = v; } - - void _clear_status() { _write_reg(Clear, ~0); } - - void _request(unsigned char cmd, - unsigned *out_resp); - - void _request(unsigned char cmd, - unsigned arg, - unsigned *out_resp); - - void _read_request(unsigned char cmd, - unsigned arg, - unsigned length, - unsigned *out_resp); - - void _write_request(unsigned char cmd, - unsigned arg, - unsigned length, - unsigned *out_resp); - - void _read_data(unsigned length, char *out_buffer); - void _write_data(unsigned length, char const *buffer); - void _write_command(unsigned cmd_index, bool resp); - - /* - * TODO report (and support) real capacity not just 512M - */ - size_t const _block_size = 512; - Block::sector_t const _block_count = 0x20000000 / _block_size; - - public: - - Driver(Env &env, Platform::Connection & platform); - ~Driver(); - - - /****************** - ** Block-driver ** - ******************/ - - Dma_buffer alloc_dma_buffer(size_t size, Cache cache) override - { - Ram_dataspace_capability ds = - _platform.retry_with_upgrade(Ram_quota{4096}, Cap_quota{2}, - [&] () { return _platform.alloc_dma_buffer(size, cache); }); - - return { .ds = ds, - .dma_addr = _platform.dma_addr(ds) }; - } - - Block::Session::Info info() const override - { - return { .block_size = _block_size, - .block_count = _block_count, - .align_log2 = log2(_block_size), - .writeable = true }; - } - - void read(Block::sector_t block_number, - size_t block_count, - char *buffer, - Block::Packet_descriptor &packet) override; - - void write(Block::sector_t block_number, - size_t block_count, - char const *buffer, - Block::Packet_descriptor &packet) override; - -}; - -#endif /* _DRIVER_H_ */ diff --git a/repos/os/src/driver/sd_card/pl180/target.mk b/repos/os/src/driver/sd_card/pl180/target.mk deleted file mode 100644 index c5916ed003..0000000000 --- a/repos/os/src/driver/sd_card/pl180/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = pl180_sd_card -REQUIRES = arm_v7 - -include $(REP_DIR)/src/driver/sd_card/target.inc diff --git a/repos/os/src/driver/sd_card/sd_card.h b/repos/os/src/driver/sd_card/sd_card.h deleted file mode 100644 index 75447741c2..0000000000 --- a/repos/os/src/driver/sd_card/sd_card.h +++ /dev/null @@ -1,593 +0,0 @@ -/* - * \brief SD card protocol definitions - * \author Norman Feske - * \author Sebastian Sumpf - * \date 2012-07-06 - */ - -/* - * Copyright (C) 2012-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _SD_CARD_H_ -#define _SD_CARD_H_ - -/* Genode includes */ -#include - -namespace Sd_card { - - using namespace Genode; - - /** - * Structure of the first word of a native mode R1 response - */ - struct R1_response_0 : Register<32> - { - struct Ready_for_data : Bitfield<8, 1> { }; - struct State : Bitfield<9, 4> - { - enum { PROGRAM = 7 }; - }; - struct Error : Bitfield<19, 1> { }; - - /** - * Return wether the card is ready for data - * - * \param resp R1 response, word 0 - */ - static bool card_ready(access_t const resp) - { - /* - * Check both ready bit and state because not all cards handle - * the status bits correctly. - */ - return Ready_for_data::get(resp) && - State::get(resp) != State::PROGRAM; - } - }; - - /** - * Returned by 'Sd_send_op_cond' - */ - struct Ocr : Register<32> - { - struct Busy : Bitfield<31, 1> { }; - }; - - struct Cid - { - uint32_t raw_0, raw_1, raw_2, raw_3; - - void print(Output &out) const - { - Genode::print(out, Hex(raw_3), " ", Hex(raw_2), " ", - Hex(raw_1), " ", Hex(raw_0)); - } - }; - - struct Csd0 : Register<32> - { - }; - - struct Csd1 : Register<32> - { - enum { BIT_BASE = 1*sizeof(access_t)*8 }; - - struct V2_device_size_lo : Bitfield<48 - BIT_BASE, 16> { }; - - struct V1_c_size_lo : Bitfield<62 - BIT_BASE, 2> { }; - struct V1_c_size_mult : Bitfield<47 - BIT_BASE, 3> { }; - }; - - struct Csd2 : Register<32> - { - enum { BIT_BASE = 2*sizeof(access_t)*8 }; - - struct V2_device_size_hi : Bitfield<64 - BIT_BASE, 6> { }; - - struct V1_read_bl_len : Bitfield<80 - BIT_BASE, 4> { }; - struct V1_c_size_hi : Bitfield<64 - BIT_BASE, 10> { }; - }; - - struct Csd3 : Register<32> - { - enum { BIT_BASE = 3*sizeof(access_t)*8 }; - - struct Version : Bitfield<126 - BIT_BASE, 2> - { - enum Type { STANDARD_CAPACITY = 0, HIGH_CAPACITY = 1, EXT_CSD = 3 }; - }; - - struct Mmc_spec_vers : Bitfield<122 - BIT_BASE, 4> { }; - }; - - struct Csd - { - Csd0::access_t csd0; - Csd1::access_t csd1; - Csd2::access_t csd2; - Csd3::access_t csd3; - }; - - - struct Ext_csd : Mmio<0xd8> - { - using Mmio::Mmio; - - struct Revision : Register<0xc0, 8> { }; - struct Sector_count : Register<0xd4, 32> { }; - }; - - struct Arg : Register<32> { }; - - enum Response { RESPONSE_NONE, - RESPONSE_136_BIT, - RESPONSE_48_BIT, - RESPONSE_48_BIT_WITH_BUSY }; - - enum Transfer { TRANSFER_NONE, TRANSFER_READ, TRANSFER_WRITE }; - - struct Command_base - { - unsigned index; /* command opcode */ - Arg::access_t arg; /* argument */ - Response rsp_type; /* response type */ - Transfer transfer; /* data transfer type */ - - Command_base(unsigned op, Response rsp_type, Transfer transfer) - : - index(op), arg(0), rsp_type(rsp_type), transfer(transfer) - { } - - void print(Output &out) const - { - using Genode::print; - print(out, "index=", index, ", arg=", arg, ", rsp_type="); - switch (rsp_type) { - case RESPONSE_NONE: print(out, "NONE"); break; - case RESPONSE_136_BIT: print(out, "136_BIT"); break; - case RESPONSE_48_BIT: print(out, "48_BIT"); break; - case RESPONSE_48_BIT_WITH_BUSY: print(out, "48_BIT_WITH_BUSY"); break; - } - } - }; - - template - struct Command : Command_base - { - enum { INDEX = _INDEX }; - Command() : Command_base(_INDEX, RSP_TYPE, TRANSFER) { } - }; - - template - struct Prefixed_command : private Command_base - { - Prefixed_command() : Command_base(INDEX, RSP_TYPE, TRANSFER) { } - - using Command_base::arg; - - /** - * Used by ACMD overload of 'issue_command()' - */ - Command_base const &base() const { return *this; } - }; - - struct Go_idle_state : Command<0, RESPONSE_NONE> { }; - - struct All_send_cid : Command<2, RESPONSE_136_BIT> { }; - - struct Send_relative_addr : Command<3, RESPONSE_48_BIT> - { - struct Response : Sd_card::Arg - { - struct Rca : Bitfield<16, 16> { }; - }; - - Send_relative_addr(unsigned rca = 0) - { - Response::Rca::set(arg, rca); - } - }; - - struct Send_status : Command<13, RESPONSE_48_BIT> - { - struct Arg : Sd_card::Arg - { - struct Rca : Bitfield<16, 16> { }; - }; - }; - - struct Select_card : Command<7, RESPONSE_48_BIT> - { - struct Arg : Sd_card::Arg - { - struct Rca : Bitfield<16, 16> { }; - }; - - Select_card(unsigned rca) - { - Arg::Rca::set(arg, rca); - } - }; - - struct Send_if_cond : Command<8, RESPONSE_48_BIT> - { - struct Arg : Sd_card::Arg - { - struct Check_pattern : Bitfield<0, 8> { }; - struct Supply_voltage : Bitfield<8, 4> { }; - }; - - Send_if_cond() - { - Arg::Check_pattern::set(arg, 0xaa); - Arg::Supply_voltage::set(arg, 1); - } - }; - - struct Send_csd : Command<9, RESPONSE_136_BIT> - { - struct Arg : Sd_card::Arg - { - struct Rca : Bitfield<16, 16> { }; - }; - - Send_csd(unsigned rca) - { - Arg::Rca::set(arg, rca); - } - }; - - struct Mmc_send_ext_csd : Command<8, RESPONSE_48_BIT_WITH_BUSY, TRANSFER_READ> - { }; - - struct Set_block_count : Command<23, RESPONSE_48_BIT> - { - Set_block_count(size_t count) - { - arg = count; - }; - }; - - struct Set_blocklen : Command<16, RESPONSE_48_BIT> - { - Set_blocklen(size_t blocklen) - { - arg = blocklen; - }; - }; - - struct Read_multiple_block : Command<18, RESPONSE_48_BIT, TRANSFER_READ> - { - Read_multiple_block(unsigned long addr) - { - arg = addr; - } - }; - - struct Write_multiple_block : Command<25, RESPONSE_48_BIT, TRANSFER_WRITE> - { - Write_multiple_block(unsigned long addr) - { - arg = addr; - } - }; - - struct Set_bus_width : Prefixed_command<6, RESPONSE_48_BIT> - { - struct Arg : Sd_card::Arg - { - struct Bus_width : Bitfield<0, 2> - { - enum Width { ONE_BIT = 0, FOUR_BITS = 2 }; - }; - }; - - Set_bus_width(Arg::Bus_width::Width width) - { - Arg::Bus_width::set(arg, width); - } - }; - - struct Mmc_switch : Command<6, RESPONSE_48_BIT> - { - enum { SWITCH_MODE_WRITE_BYTE = 0x3 }; - - struct Arg : Sd_card::Arg - { - struct Value : Bitfield<8, 8> { }; - struct Index : Bitfield<16, 8> { }; - struct Mode : Bitfield<24, 8> { }; - }; - - Mmc_switch(unsigned index, unsigned val) - { - Arg::Mode::set(arg, SWITCH_MODE_WRITE_BYTE); - Arg::Index::set(arg, index); - Arg::Value::set(arg, val); - } - }; - - struct Sd_send_op_cond : Prefixed_command<41, RESPONSE_48_BIT> - { - struct Arg : Sd_card::Arg - { - /** - * Operating condition register - */ - struct Ocr : Bitfield<0, 24> { }; - - /** - * Host capacity support - */ - struct Hcs : Bitfield<30, 1> { }; - }; - - Sd_send_op_cond(unsigned ocr, bool hcs) - { - Arg::Ocr::set(arg, ocr); - Arg::Hcs::set(arg, hcs); - } - }; - - struct Mmc_send_op_cond : Command<1, RESPONSE_48_BIT> - { - struct Arg : Sd_card::Arg - { - /** - * Operating condition register - */ - struct Ocr : Bitfield<0, 24> { }; - - /** - * Host capacity support - */ - struct Hcs : Bitfield<30, 1> { }; - }; - - Mmc_send_op_cond(unsigned ocr, bool hcs) - { - Arg::Ocr::set(arg, ocr); - Arg::Hcs::set(arg, hcs); - } - }; - - struct Stop_transmission : Command<12, RESPONSE_48_BIT> { }; - - struct Acmd_prefix : Command<55, RESPONSE_48_BIT> - { - struct Arg : Sd_card::Arg - { - struct Rca : Bitfield<16, 16> { }; - }; - - Acmd_prefix(unsigned rca) - { - Arg::Rca::set(arg, rca); - } - }; - - class Card_info - { - private: - - unsigned _rca; - size_t _capacity_mb; - const Csd3::Version::Type _version; - - public: - - Card_info(unsigned rca, size_t capacity_mb, const Csd3::Version::Type version) - : _rca(rca), _capacity_mb(capacity_mb), _version(version) - { } - - /** - * Return capacity in megabytes - */ - size_t capacity_mb() const { return _capacity_mb; } - - /** - * Return relative card address - */ - unsigned rca() const { return _rca; } - - /** - * Returns the version of the card - */ - Csd3::Version::Type version() const { return _version; } - }; - - - /** - * SD card host controller - */ - class Host_controller : Genode::Interface - { - public: - - /** - * Exception type - */ - struct Detection_failed { }; - - protected: - - virtual bool _issue_command(Command_base const &command) = 0; - - virtual Cid _read_cid() = 0; - - virtual Csd _read_csd() = 0; - - virtual unsigned _read_rca() = 0; - - virtual size_t _read_ext_csd() { return 0; } - - public: - - virtual Card_info card_info() const = 0; - - bool issue_command(Command_base const &command) - { - return _issue_command(command); - } - - /** - * Issue application-specific command - * - * This overload is selected if the supplied command type has - * 'Prefixed_command' as its base class. In this case, we need to - * issue a CMD55 as command prefix followed by the actual command. - * - * \param prefix_rca argument to CMD55 prefix command - */ - template - bool issue_command(Prefixed_command const &command, - unsigned prefix_rca = 0) - { - /* send CMD55 prefix */ - if (!_issue_command(Acmd_prefix(prefix_rca))) { - error("prefix command timed out"); - return false; - } - - /* send actual command */ - return _issue_command(command.base()); - } - - private: - - /** - * Extract capacity information from CSD register - * - * \throw Detection_failed - * \return capacity in 512-kByte blocks - */ - size_t _sd_card_device_size(Csd const csd) - { - /* - * The capacity is reported via the CSD register. There are - * two versions of this register. Standard-capacity cards - * use version 1 whereas high-capacity cards use version 2. - */ - - if (Csd3::Version::get(csd.csd3) == Csd3::Version::STANDARD_CAPACITY) { - /* - * Calculation of the capacity according to the - * "Physical Layer Simplified Specification Version 4.10", - * Section 5.3.2. - */ - size_t const read_bl_len = Csd2::V1_read_bl_len::get(csd.csd2); - size_t const c_size = (Csd2::V1_c_size_hi::get(csd.csd2) << 2) - | Csd1::V1_c_size_lo::get(csd.csd1); - - size_t const c_size_mult = Csd1::V1_c_size_mult::get(csd.csd1); - size_t const mult = 1 << (c_size_mult + 2); - size_t const block_len = 1 << read_bl_len; - size_t const capacity = (c_size + 1)*mult*block_len; - size_t const capacity512KiB = capacity / (512 * 1024); - - return capacity512KiB; - } - - if (Csd3::Version::get(csd.csd3) == Csd3::Version::HIGH_CAPACITY) - return ((Csd2::V2_device_size_hi::get(csd.csd2) << 16) - | Csd1::V2_device_size_lo::get(csd.csd1)) + 1; - - error("Could not detect SD-card capacity"); - throw Detection_failed(); - } - - protected: - - /** - * Perform SD card detection sequence - * - * \throw Detection_failed - */ - Card_info _detect() - { - if (!issue_command(All_send_cid())) { - warning("All_send_cid command failed"); - throw Detection_failed(); - } - - Cid const cid = _read_cid(); - log("CID: ", cid); - - if (!issue_command(Send_relative_addr())) { - error("Send_relative_addr timed out"); - throw Detection_failed(); - } - - unsigned const rca = _read_rca(); - log("RCA: ", Hex(rca)); - - if (!issue_command(Send_csd(rca))) { - error("Send_csd failed"); - throw Detection_failed(); - } - - Csd const csd = _read_csd(); - - if (!issue_command(Select_card(rca))) { - error("Select_card failed"); - throw Detection_failed(); - } - - return Card_info(rca, _sd_card_device_size(csd) / 2, - static_cast(Csd3::Version::get(csd.csd3))); - } - - Card_info _detect_mmc() - { - if (!issue_command(All_send_cid())) { - warning("All_send_cid command failed"); - throw Detection_failed(); - } - - unsigned const rca = 1; - - if (!issue_command(Send_relative_addr(rca))) { - error("Send_relative_addr timed out"); - throw Detection_failed(); - } - - if (!issue_command(Send_csd(rca))) { - error("Send_csd failed"); - throw Detection_failed(); - } - - Csd const csd = _read_csd(); - - if (Csd3::Version::get(csd.csd3) != Csd3::Version::EXT_CSD) { - error("Csd version is not extented CSD"); - throw Detection_failed(); - } - - if (Csd3::Mmc_spec_vers::get(csd.csd3) < 4) { - error("Csd specific version is less than 4"); - throw Detection_failed(); - } - - if (!issue_command(Select_card(rca))) { - error("Select_card failed"); - throw Detection_failed(); - } - - size_t device_size; - if(!(device_size = _read_ext_csd())) { - error("Could not read extented CSD"); - throw Detection_failed(); - } - - return Card_info(rca, device_size, - static_cast(Csd3::Version::get(csd.csd3))); - } - }; -} - -#endif /* _SD_CARD_H_ */ diff --git a/repos/os/src/driver/sd_card/target.inc b/repos/os/src/driver/sd_card/target.inc deleted file mode 100644 index a073d3d7e3..0000000000 --- a/repos/os/src/driver/sd_card/target.inc +++ /dev/null @@ -1,6 +0,0 @@ -SRC_CC += main.cc driver.cc -LIBS += base -INC_DIR += $(PRG_DIR) $(REP_DIR)/src/driver/sd_card - -vpath %.cc $(REP_DIR)/src/driver/sd_card -vpath %.cc $(PRG_DIR) diff --git a/tool/autopilot.list b/tool/autopilot.list index 0a1b685076..37b4288182 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -64,7 +64,6 @@ nova platform rtc rump_ext2 -sd_card_bench sd_card_zynq seoul-auto smartcard