diff --git a/dde_linux/run/usb_storage.run b/dde_linux/run/usb_storage.run
index 51b6c74939..24f75d6262 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 faafda72f2..1f27dcf09f 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 0000000000..d183d2e99f
--- /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 c07591ba3f..21f5feae5a 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 0000000000..1a18821785
--- /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 09b8fbb69d..9e8ae2c31e 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 0000000000..d5f11b2edd
--- /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 0000000000..d4b8c6624c
--- /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 14691c8def..0000000000
--- 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 8844e233c3..aad524cb49 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