From 35bb156972676d1d05496004f60243a0681befb2 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 13 Dec 2013 11:54:50 +0100 Subject: [PATCH] block: extend block session test framework --- dde_linux/run/usb_storage.run | 8 +- os/run/ahci.run | 47 +-- os/run/blk.run | 54 +++ os/run/sd_card.run | 6 +- os/src/test/blk/cli/main.cc | 399 +++++++++++++++++++++++ os/src/test/{block => blk/cli}/target.mk | 2 +- os/src/test/blk/srv/main.cc | 149 +++++++++ os/src/test/blk/srv/target.mk | 3 + os/src/test/block/main.cc | 183 ----------- ports-foc/run/l4linux_dynamic.run | 8 +- 10 files changed, 621 insertions(+), 238 deletions(-) create mode 100644 os/run/blk.run create mode 100644 os/src/test/blk/cli/main.cc rename os/src/test/{block => blk/cli}/target.mk (58%) create mode 100644 os/src/test/blk/srv/main.cc create mode 100644 os/src/test/blk/srv/target.mk delete mode 100644 os/src/test/block/main.cc diff --git a/dde_linux/run/usb_storage.run b/dde_linux/run/usb_storage.run index 51b6c7493..24f75d626 100644 --- a/dde_linux/run/usb_storage.run +++ b/dde_linux/run/usb_storage.run @@ -12,7 +12,7 @@ set build_components { core init drivers/timer drivers/usb - test/block + test/blk/cli } lappend_if [have_spec acpi] build_components drivers/acpi @@ -93,7 +93,7 @@ append config { - + } @@ -105,7 +105,7 @@ install_config $config # generic modules set boot_modules { - core init timer usb_drv test-block + core init timer usb_drv test-blk-cli } lappend_if [have_spec acpi] boot_modules acpi_drv @@ -142,7 +142,7 @@ append qemu_args { \ -device usb-storage,bus=ehci.0,drive=disk \ -boot order=d } -run_genode_until {.*child exited with exit value 0.*} 40 +run_genode_until {.*child exited with exit value 0.*} 100 puts "\ntest succeeded\n" diff --git a/os/run/ahci.run b/os/run/ahci.run index faafda72f..1f27dcf09 100644 --- a/os/run/ahci.run +++ b/os/run/ahci.run @@ -7,7 +7,7 @@ if {![have_spec x86_32] && ![have_spec exynos5]} { # Build # -set build_components { core init drivers/timer drivers/ahci test/block } +set build_components { core init drivers/timer drivers/ahci test/blk/cli } lappend_if [have_spec x86_32] build_components drivers/pci lappend_if [have_spec acpi] build_components drivers/acpi @@ -93,7 +93,7 @@ append config { - + @@ -108,7 +108,7 @@ install_config $config # Boot modules # -set boot_modules { core init timer ahci test-block } +set boot_modules { core init timer ahci test-blk-cli } append_if [have_spec x86_32] boot_modules { pci_drv acpi_drv } append_if [have_spec nova] boot_modules pci_device_pd @@ -137,43 +137,4 @@ if { [file exists $disk_image] == 0 } then { # Test # -run_genode_until "child exited with exit value 0.*\n" 10 - -# pay only attention to the output of test-block -grep_output {^\[init -> test-block.*Comparing} - -compare_output_to { - [init -> test-block] Comparing block 0000000000: success - [init -> test-block] Comparing block 0000000640: success - [init -> test-block] Comparing block 0000001280: success - [init -> test-block] Comparing block 0000001920: success - [init -> test-block] Comparing block 0000002560: success - [init -> test-block] Comparing block 0000003200: success - [init -> test-block] Comparing block 0000003840: success - [init -> test-block] Comparing block 0000004480: success - [init -> test-block] Comparing block 0000005120: success - [init -> test-block] Comparing block 0000005760: success - [init -> test-block] Comparing block 0000006400: success - [init -> test-block] Comparing block 0000007040: success - [init -> test-block] Comparing block 0000007680: success - [init -> test-block] Comparing block 0000008320: success - [init -> test-block] Comparing block 0000008960: success - [init -> test-block] Comparing block 0000009600: success - [init -> test-block] Comparing block 0000010240: success - [init -> test-block] Comparing block 0000010880: success - [init -> test-block] Comparing block 0000011520: success - [init -> test-block] Comparing block 0000012160: success - [init -> test-block] Comparing block 0000012800: success - [init -> test-block] Comparing block 0000013440: success - [init -> test-block] Comparing block 0000014080: success - [init -> test-block] Comparing block 0000014720: success - [init -> test-block] Comparing block 0000015360: success - [init -> test-block] Comparing block 0000016000: success - [init -> test-block] Comparing block 0000016640: success - [init -> test-block] Comparing block 0000017280: success - [init -> test-block] Comparing block 0000017920: success - [init -> test-block] Comparing block 0000018560: success - [init -> test-block] Comparing block 0000019200: success - [init -> test-block] Comparing block 0000019840: success -} - +run_genode_until "Tests finished successfully.*\n" 50 diff --git a/os/run/blk.run b/os/run/blk.run new file mode 100644 index 000000000..d183d2e99 --- /dev/null +++ b/os/run/blk.run @@ -0,0 +1,54 @@ +# +# \brief Test of Block session interface +# \author Stefan Kalkowski +# \date 2013-12-10 +# + +# +# Build +# +build { core init drivers/timer test/blk lib/trace/policy/rpc_name } +create_boot_directory + +# +# Generate config +# +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +# +# Boot modules +# +build_boot_image { core init timer test-blk-srv test-blk-cli rpc_name } + +append qemu_args " -nographic -m 64 " +run_genode_until "Tests finished successfully.*\n" 100 \ No newline at end of file diff --git a/os/run/sd_card.run b/os/run/sd_card.run index c07591ba3..21f5feae5 100644 --- a/os/run/sd_card.run +++ b/os/run/sd_card.run @@ -7,7 +7,7 @@ set build_components { core init drivers/timer drivers/sd_card - test/block + test/blk/cli } lappend_if [have_spec platform_arndale] build_components drivers/platform @@ -52,7 +52,7 @@ append config { - + } @@ -69,7 +69,7 @@ set boot_modules { core init timer sd_card_drv - test-block + test-blk-cli } lappend_if [have_spec platform_arndale] boot_modules platform_drv diff --git a/os/src/test/blk/cli/main.cc b/os/src/test/blk/cli/main.cc new file mode 100644 index 000000000..1a1882178 --- /dev/null +++ b/os/src/test/blk/cli/main.cc @@ -0,0 +1,399 @@ +/** + * \brief Block session tests - client side. + * \author Stefan Kalkowski + * \date 2013-12-10 + */ + +#include +#include +#include +#include + +static Genode::size_t blk_sz; /* block size of the device */ +static Block::sector_t blk_cnt; /* number of blocks of device */ +static Block::Session::Operations blk_ops; /* supported operations */ + + +/** + * Virtual base class of all test scenarios, provides basic signal handling + */ +class Test +{ + public: + + struct Exception : Genode::Exception + { + virtual void print_error() = 0; + }; + + class Block_exception : public Exception + { + protected: + + Block::sector_t _nr; + Genode::size_t _cnt; + bool _write; + + public: + + Block_exception(Block::sector_t nr, Genode::size_t cnt, + bool write) + : _nr(nr), _cnt(cnt), _write(write) {} + + virtual void print_error() { + PINF("couldn't %s block %lld - %lld", + _write ? "write" : "read", _nr, _nr+_cnt); } + }; + + struct Submit_queue_full : Exception { + void print_error() { PINF("The submit queue is full!"); } }; + + struct Timeout : Exception { + void print_error() { PINF("Test timed out!"); } }; + + virtual void perform() = 0; + virtual void ack_avail() = 0; + + protected: + + Genode::Allocator_avl _alloc; + Block::Connection _session; + Genode::Signal_receiver _receiver; + Genode::Signal_dispatcher _disp_ack; + Genode::Signal_dispatcher _disp_submit; + Genode::Signal_dispatcher _disp_timeout; + Timer::Connection _timer; + bool _handle; + + Genode::size_t _shared_buffer_size(Genode::size_t bulk) + { + return bulk + + sizeof(Block::Session::Tx_policy::Ack_queue) + + sizeof(Block::Session::Tx_policy::Submit_queue); + } + + void _ack_avail(unsigned) { ack_avail(); } + void _ready_to_submit(unsigned) { _handle = false; } + void _timeout(unsigned) { throw Timeout(); } + + Test(Genode::size_t bulk_buffer_size, + unsigned timeout_ms) + : _alloc(Genode::env()->heap()), + _session(&_alloc, _shared_buffer_size(bulk_buffer_size)), + _disp_ack(_receiver, *this, &Test::_ack_avail), + _disp_submit(_receiver, *this, &Test::_ready_to_submit), + _disp_timeout(_receiver, *this, &Test::_timeout) + { + _session.tx_channel()->sigh_ack_avail(_disp_ack); + _session.tx_channel()->sigh_ready_to_submit(_disp_submit); + + if (timeout_ms) { + _timer.sigh(_disp_timeout); + _timer.trigger_once(1000*timeout_ms); + } + } + + void _handle_signal() + { + _handle = true; + + while (_handle) { + Genode::Signal s = _receiver.wait_for_signal(); + static_cast + (s.context())->dispatch(s.num()); + } + } +}; + + +template +struct Read_test : Test +{ + bool done; + + Read_test(unsigned timeo_ms) + : Test(BULK_BLK_NR*blk_sz, timeo_ms), done(false) { } + + void perform() + { + PINF("reading block 0 - %llu, %u per request", + blk_cnt - 1, NR_PER_REQ); + + for (Block::sector_t nr = 0, cnt = NR_PER_REQ; nr < blk_cnt; + nr += cnt) { + + while (!_session.tx()->ready_to_submit()) + _handle_signal(); + + cnt = Genode::min(NR_PER_REQ, blk_cnt-nr); + + try { + Block::Packet_descriptor p( + _session.dma_alloc_packet(cnt*blk_sz), + Block::Packet_descriptor::READ, nr, cnt); + _session.tx()->submit_packet(p); + } catch(Block::Session::Tx::Source::Packet_alloc_failed) { + cnt = 0; /* retry the current block number */ + _handle_signal(); + } + } + + while (!done) + _handle_signal(); + } + + void ack_avail() + { + _handle = false; + + while (_session.tx()->ack_avail()) { + Block::Packet_descriptor p = _session.tx()->get_acked_packet(); + + if (!p.succeeded()) + throw Block_exception(p.block_number(), p.block_count(), + false); + + if ((p.block_number() + p.block_count()) == blk_cnt) + done = true; + + _session.tx()->release_packet(p); + } + } +}; + + +template +struct Write_test : Test +{ + struct Invalid_dimensions : Exception { + void print_error() { PINF("Invalid bulk buffer, or batch size!"); } }; + + struct Integrity_exception : Block_exception + { + Integrity_exception(Block::sector_t nr, Genode::size_t cnt) + : Block_exception(nr, cnt, false) {} + + void print_error() { + PINF("Integrity check failed: block %lld - %lld", _nr, _nr+_cnt); } + }; + + typedef Ring_buffer Req_buffer; + + Req_buffer read_packets; + Req_buffer write_packets; + + Write_test(unsigned timeo_ms) + : Test(BULK_BLK_NR*blk_sz, timeo_ms) + { + if (BULK_BLK_NR < BATCH*NR_PER_REQ || + BATCH > Block::Session::TX_QUEUE_SIZE || + BULK_BLK_NR % BATCH != 0) + throw Invalid_dimensions(); + } + + bool compare(Block::Packet_descriptor &r, Block::Packet_descriptor &w) + { + signed char *dst = (signed char*)_session.tx()->packet_content(w), + *src = (signed char*)_session.tx()->packet_content(r); + for (Genode::size_t i = 0; i < blk_sz; i++) + if (dst[i] != src[i]) + return false; + return true; + } + + void compare() + { + while (!read_packets.empty()) { + Block::Packet_descriptor r = read_packets.get(); + while (true) { + Block::Packet_descriptor w = write_packets.get(); + if (r.block_number() == w.block_number()) { + if (!compare(r,w)) + throw Integrity_exception(r.block_number(), + r.block_count()); + break; + } + write_packets.add(w); + } + } + } + + void write(signed char val) + { + while (!read_packets.empty()) { + Block::Packet_descriptor r = read_packets.get(); + Block::Packet_descriptor w(_session.dma_alloc_packet(r.block_count() + *blk_sz), + Block::Packet_descriptor::WRITE, + r.block_number(), r.block_count()); + signed char *dst = (signed char*)_session.tx()->packet_content(w), + *src = (signed char*)_session.tx()->packet_content(r); + for (Genode::size_t i = 0; i < blk_sz; i++) + dst[i] = src[i] + val; + _session.tx()->submit_packet(w); + } + while (write_packets.avail_capacity()) + _handle_signal(); + } + + void read(Block::sector_t start, Block::sector_t end) + { + using namespace Block; + + for (sector_t nr = start, cnt = NR_PER_REQ; nr < end; + cnt = Genode::min(NR_PER_REQ, end-nr), + nr += cnt) { + Block::Packet_descriptor p(_session.dma_alloc_packet(cnt*blk_sz), + Block::Packet_descriptor::READ, nr, cnt); + _session.tx()->submit_packet(p); + } + while (read_packets.avail_capacity()) + _handle_signal(); + } + + void batch(Block::sector_t start, Block::sector_t end, signed char val) + { + read(start, end); + write(val); + read(start, end); + compare(); + } + + void perform() + { + if (!blk_ops.supported(Block::Packet_descriptor::WRITE)) + return; + + PINF("read/write/compare block 0 - %llu, %u per request", + blk_cnt - 1, NR_PER_REQ); + + for (Block::sector_t nr = 0, cnt = BATCH*NR_PER_REQ; nr < blk_cnt; + cnt = Genode::min(BATCH*NR_PER_REQ, blk_cnt-nr), + nr += cnt) { + batch(nr, nr + cnt, 1); + batch(nr, nr + cnt, -1); + } + } + + void ack_avail() + { + _handle = false; + + while (_session.tx()->ack_avail()) { + Block::Packet_descriptor p = _session.tx()->get_acked_packet(); + bool write = p.operation() == Block::Packet_descriptor::WRITE; + if (!p.succeeded()) + throw Block_exception(p.block_number(), p.block_count(), write); + if (write) + write_packets.add(p); + else + read_packets.add(p); + _session.tx()->release_packet(p); + } + } +}; + + +struct Violation_test : Test +{ + struct Write_on_read_only : Exception { + void print_error() { PINF("write on read-only device succeeded!"); } }; + + struct Range_check_failed : Block_exception + { + Range_check_failed(Block::sector_t nr, Genode::size_t cnt) + : Block_exception(nr, cnt, false) {} + + void print_error() { + PINF("Range check failed: access to block %lld - %lld succeeded", + _nr, _nr+_cnt); } + }; + + int p_in_fly; + + Violation_test(unsigned timeo) : Test(20*blk_sz, timeo), p_in_fly(0) {} + + void req(Block::sector_t nr, Genode::size_t cnt, bool write) + { + Block::Packet_descriptor p(_session.dma_alloc_packet(blk_sz), + write ? Block::Packet_descriptor::WRITE + : Block::Packet_descriptor::READ, + nr, cnt); + _session.tx()->submit_packet(p); + p_in_fly++; + } + + void perform() + { + if (!blk_ops.supported(Block::Packet_descriptor::WRITE)) + req(0, 1, true); + + req(blk_cnt, 1, false); + req(blk_cnt-1, 2, false); + + while (p_in_fly > 0) + _handle_signal(); + } + + void ack_avail() + { + _handle = false; + + while (_session.tx()->ack_avail()) { + Block::Packet_descriptor p = _session.tx()->get_acked_packet(); + if (p.succeeded()) { + if (p.operation() == Block::Packet_descriptor::WRITE) + throw Write_on_read_only(); + throw Range_check_failed(p.block_number(), p.block_count()); + } + _session.tx()->release_packet(p); + p_in_fly--; + } + } +}; + + +template +void perform(unsigned timeo_ms = 0) +{ + TEST t(timeo_ms); + t.perform(); +} + + +int main() +{ + try { + /** + * First we ask for the block size of the driver to dimension + * the queue size for our tests. Moreover, we implicitely test, + * whether closing and opening again works for the driver + */ + { + Genode::Allocator_avl alloc(Genode::env()->heap()); + Block::Connection blk(&alloc); + blk.info(&blk_cnt, &blk_sz, &blk_ops); + } + + PINF("block device with block size %zd sector count %lld", + blk_sz, blk_cnt); + + perform >(); + perform >(); + perform >(); + perform >(); + perform(1000); + + PINF("Tests finished successfully!"); + } catch(Genode::Parent::Service_denied) { + PERR("Opening block session was denied!"); + return -1; + } catch(Test::Exception &e) { + PERR("Test failed!"); + e.print_error(); + return -2; + } + return 0; +} diff --git a/os/src/test/block/target.mk b/os/src/test/blk/cli/target.mk similarity index 58% rename from os/src/test/block/target.mk rename to os/src/test/blk/cli/target.mk index 09b8fbb69..9e8ae2c31 100644 --- a/os/src/test/block/target.mk +++ b/os/src/test/blk/cli/target.mk @@ -1,3 +1,3 @@ -TARGET = test-block +TARGET = test-blk-cli SRC_CC = main.cc LIBS = base diff --git a/os/src/test/blk/srv/main.cc b/os/src/test/blk/srv/main.cc new file mode 100644 index 000000000..d5f11b2ed --- /dev/null +++ b/os/src/test/blk/srv/main.cc @@ -0,0 +1,149 @@ +/* + * \brief Test block session interface - server side + * \author Stefan Kalkowski + * \date 2013-12-09 + */ + +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + + +class Driver : public Block::Driver +{ + private: + + enum { MAX_REQUESTS = 5 }; + + typedef Ring_buffer Req_buffer; + + Genode::size_t _number; + Genode::size_t _size; + Req_buffer _packets; + Genode::Signal_dispatcher _ack; + Genode::Ram_dataspace_capability _blk_ds; + unsigned char *_blk_buf; + + void _handle_ack(unsigned) + { + while (!_packets.empty()) { + Block::Packet_descriptor p = _packets.get(); + session->ack_packet(p); + } + } + + public: + + Driver(Genode::size_t number, Genode::size_t size, + Genode::Signal_receiver &receiver) + : _number(number), _size(size), + _ack(receiver, *this, &Driver::_handle_ack), + _blk_ds(Genode::env()->ram_session()->alloc(number*size)), + _blk_buf(Genode::env()->rm_session()->attach(_blk_ds)) {} + + Genode::Signal_context_capability handler() { return _ack; } + + + /******************************* + ** Block::Driver interface ** + *******************************/ + + Genode::size_t block_size() { return _size; } + Block::sector_t block_count() { return _number; } + + Block::Session::Operations ops() + { + Block::Session::Operations ops; + ops.set_operation(Block::Packet_descriptor::READ); + ops.set_operation(Block::Packet_descriptor::WRITE); + return ops; + } + + void read(Block::sector_t block_number, + Genode::size_t block_count, + char *buffer, + Block::Packet_descriptor &packet) + { + if (!_packets.avail_capacity()) + throw Block::Driver::Request_congestion(); + + Genode::memcpy((void*)buffer, &_blk_buf[block_number*_size], + block_count * _size); + _packets.add(packet); + } + + void write(Block::sector_t block_number, + Genode::size_t block_count, + const char *buffer, + Block::Packet_descriptor &packet) + { + if (!_packets.avail_capacity()) + throw Block::Driver::Request_congestion(); + Genode::memcpy(&_blk_buf[block_number*_size], + (void*)buffer, block_count * _size); + _packets.add(packet); + } +}; + + +struct Factory : Block::Driver_factory +{ + Genode::Signal_receiver &receiver; + ::Driver *driver; + + Factory(Genode::Signal_receiver &r) : receiver(r) + { + Genode::size_t blk_nr = 1024; + Genode::size_t blk_sz = 512; + + try { + Genode::config()->xml_node().attribute("sectors").value(&blk_nr); + Genode::config()->xml_node().attribute("block_size").value(&blk_sz); + } + catch (...) { } + + driver = new (Genode::env()->heap()) Driver(blk_nr, blk_sz, receiver); + } + + Block::Driver *create() { return driver; } + + void destroy(Block::Driver *driver) { } +}; + + +int main() +{ + using namespace Genode; + + enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) }; + static Cap_connection cap; + static Rpc_entrypoint ep(&cap, STACK_SIZE, "test_blk_ep"); + + static Signal_receiver receiver; + static Factory driver_factory(receiver); + static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver); + + env()->parent()->announce(ep.manage(&block_root)); + + static Timer::Connection timer; + timer.sigh(driver_factory.driver->handler()); + timer.trigger_periodic(10000); + while (true) { + Signal s = receiver.wait_for_signal(); + static_cast(s.context())->dispatch(s.num()); + } + + return 0; +} diff --git a/os/src/test/blk/srv/target.mk b/os/src/test/blk/srv/target.mk new file mode 100644 index 000000000..d4b8c6624 --- /dev/null +++ b/os/src/test/blk/srv/target.mk @@ -0,0 +1,3 @@ +TARGET = test-blk-srv +SRC_CC = main.cc +LIBS = base config diff --git a/os/src/test/block/main.cc b/os/src/test/block/main.cc deleted file mode 100644 index 14691c8de..000000000 --- a/os/src/test/block/main.cc +++ /dev/null @@ -1,183 +0,0 @@ -/* - * \brief Block driver interface test - * \author Sebastian Sumpf - * \date 2011-08-11 - * - * Test block device, read blocks add one to the data, write block back, read - * block again and compare outputs - */ - -/* - * Copyright (C) 2011-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. - */ - -#include -#include -#include -#include -#include -#include - - -static const bool read_only = false; - -class Worker : public Genode::Thread<8192> -{ - private: - - Block::Connection _blk_con; - Genode::size_t _blk_size; - - public: - - /** - * Constructor - */ - Worker(Genode::Allocator_avl *block_alloc) - : Thread("worker"), _blk_con(block_alloc) { } - - void dump(Block::Packet_descriptor &p1, Block::Packet_descriptor &p2) - { - Block::Session::Tx::Source *source = _blk_con.tx(); - unsigned *d1 = (unsigned *)source->packet_content(p1); - unsigned *d2 = (unsigned *)source->packet_content(p2); - for (int i = 0; i < 128; i += 8) { - Genode::printf("1 0x%02x: %08x %08x %08x %08x %08x %08x %08x %08x\n", i, - d1[i], d1[i+1], d1[i+2], d1[i+3], d1[i+4], d1[i+5], d1[i+6], d1[i+7]); - Genode::printf("2 0x%02x: %08x %08x %08x %08x %08x %08x %08x %08x\n\n", i, - d2[i], d2[i+1], d2[i+2], d2[i+3], d2[i+4], d2[i+5], d2[i+6], d2[i+7]); - } - - } - - void compare(Genode::size_t block, Block::Packet_descriptor &p1, Block::Packet_descriptor &p2) - { - using namespace Genode; - Block::Session::Tx::Source *source = _blk_con.tx(); - char *d1 = source->packet_content(p1); - char *d2 = source->packet_content(p2); - - bool equal = true; - for (size_t i = 0; i < _blk_size / sizeof(unsigned); i++) - if (d1[i] != d2[i]) { - equal = false; - - if (!read_only) - PERR("%zu: %x != %x", i, d1[i], d2[i]); - } - - printf("Comparing block %010zu: ", block); - if (equal) - printf("success\n"); - else { - printf("failed\n"); - dump(p1, p2); - } - } - - void modify(Block::Packet_descriptor &src, Block::Packet_descriptor &dst, int val) - { - Block::Session::Tx::Source *source = _blk_con.tx(); - for (unsigned j = 0; j < _blk_size; j++) - source->packet_content(dst)[j] = source->packet_content(src)[j] + val; - } - - void submit(Block::Packet_descriptor &src, - Block::Packet_descriptor &dst, - int val, Genode::size_t block, bool cmp) - { - Block::Session::Tx::Source *source = _blk_con.tx(); - - source->submit_packet(src); - src = source->get_acked_packet(); - - /* check for success of operation */ - if (!src.succeeded()) { - PWRN("Could not read block %zu", block); - return; - } - - if (cmp) - compare(block, src, dst); - - modify(src, dst, val); - - if (read_only) - return; - - source->submit_packet(dst); - dst = source->get_acked_packet(); - - /* check for success of operation */ - if (!dst.succeeded()) - PWRN("Could not write block %zu", block); - } - - /** - * Thread's entry function. - */ - void entry() - { - using namespace Genode; - - Block::Session::Tx::Source *source = _blk_con.tx(); - size_t blk_cnt = 0; - Block::Session::Operations ops; - _blk_con.info(&blk_cnt, &_blk_size, &ops); - - /* check for read- and write-capability */ - if (!ops.supported(Block::Packet_descriptor::READ)) { - PERR("Block device not readable!"); - return; - } - if (!ops.supported(Block::Packet_descriptor::WRITE)) { - PERR("Block device not writeable!"); - return; - } - - printf("We have %zu blocks with a size of %zu bytes (%zu MB)\n", - blk_cnt, _blk_size, blk_cnt / (2 * 1024)); - - /* now, repeatedly invert each single block of the device */ - size_t step = blk_cnt / 32; - for (size_t i = 0; i < blk_cnt; i += step) { - try { - /* allocate packet-descriptor for reading */ - Block::Packet_descriptor p(source->alloc_packet(_blk_size), - Block::Packet_descriptor::READ, i); - - /* allocate a packet-descriptor for writing */ - Block::Packet_descriptor q(source->alloc_packet(_blk_size), - Block::Packet_descriptor::WRITE, i); - - submit(p, q, 1, i, false); - submit(p, q, -1, i, true); - - /* release packets */ - source->release_packet(q); - source->release_packet(p); - } catch (Block::Session::Tx::Source::Packet_alloc_failed) { - PWRN("Mmh, strange we run out of packets"); - source->release_packet(source->get_acked_packet()); - } - } - - env()->parent()->close(_blk_con.cap()); - env()->parent()->exit(0); - } -}; - - -int main(int argc, char **argv) -{ - Genode::printf("--- AHCI block driver test ---\n"); - - Genode::Allocator_avl block_alloc(Genode::env()->heap()); - Worker th(&block_alloc); - th.start(); - Genode::sleep_forever(); - return 0; -} diff --git a/ports-foc/run/l4linux_dynamic.run b/ports-foc/run/l4linux_dynamic.run index 8844e233c..aad524cb4 100644 --- a/ports-foc/run/l4linux_dynamic.run +++ b/ports-foc/run/l4linux_dynamic.run @@ -32,7 +32,7 @@ set build_components { server/terminal_log server/terminal_mux test/affinity - test/block + test/blk/cli test/gdb_monitor test/input test/lwip/http_srv @@ -231,11 +231,11 @@ set config { - + - + @@ -600,7 +600,7 @@ set boot_modules { terminal_log terminal_mux test-affinity - test-block + test-blk-cli timer usb_drv vim.tar