diff --git a/os/src/drivers/sd_card/omap4/bench/main.cc b/os/src/drivers/sd_card/omap4/bench/main.cc index fafbbdec78..9731394228 100644 --- a/os/src/drivers/sd_card/omap4/bench/main.cc +++ b/os/src/drivers/sd_card/omap4/bench/main.cc @@ -14,20 +14,31 @@ #include +struct Operation +{ + virtual void operator () (Block::Driver &driver, + Genode::addr_t block_number, + Genode::size_t block_count, + Genode::addr_t buffer_phys, + char *buffer_virt) = 0; +}; + + /* * \param total_size total number of bytes to read * \param request_size number of bytes per request */ -static void test_read(Block::Driver &driver, - Timer::Session &timer, - char *buffer_virt, - Genode::addr_t buffer_phys, - Genode::size_t buffer_size, - Genode::size_t request_size) +static void run_benchmark(Block::Driver &driver, + Timer::Session &timer, + char *buffer_virt, + Genode::addr_t buffer_phys, + Genode::size_t buffer_size, + Genode::size_t request_size, + Operation &operation) { using namespace Genode; - PLOG("read: request_size=%zd bytes", request_size); + PLOG("request_size=%zd bytes", request_size); size_t const time_before_ms = timer.elapsed_ms(); @@ -38,13 +49,9 @@ static void test_read(Block::Driver &driver, size_t const block_count = request_size / driver.block_size(); addr_t const block_number = i*block_count; - if (driver.dma_enabled()) { - driver.read_dma(block_number, block_count, - buffer_phys + i*request_size); - } else { - driver.read(block_number, block_count, - buffer_virt + i*request_size); - } + operation(driver, block_number, block_count, + buffer_phys + i*request_size, + buffer_virt + i*request_size); } size_t const time_after_ms = timer.elapsed_ms(); @@ -69,29 +76,72 @@ int main(int argc, char **argv) printf("--- OMAP4 SD card benchmark ---\n"); - bool const use_dma = true; + bool const use_dma = false; static Block::Omap4_driver driver(use_dma); static Timer::Connection timer; long const request_sizes[] = { - 512, 1024, 2048, 4096, 8192, 16384, 32768, 0 }; + 512, 1024, 2048, 4096, 8192, 16384, 32768, 64*1024, 128*1024, 0 }; /* total size of communication buffer */ size_t const buffer_size = 10*1024*1024; - /* allocate read buffer */ + /* allocate read/write buffer */ static Attached_ram_dataspace buffer(env()->ram_session(), buffer_size, false); - char * const buffer_virt = buffer.local_addr(); addr_t const buffer_phys = Dataspace_client(buffer.cap()).phys_addr(); - for (unsigned i = 0; request_sizes[i]; i++) - test_read(driver, timer, buffer_virt, buffer_phys, buffer_size, - request_sizes[i]); + /* + * Benchmark reading from SD card + */ - printf("--- OMAP4 SD card benchmark finished ---\n"); + printf("\n-- reading from SD card --\n"); + + struct Read : Operation + { + void operator () (Block::Driver &driver, + addr_t number, size_t count, addr_t phys, char *virt) + { + if (driver.dma_enabled()) + driver.read_dma(number, count, phys); + else + driver.read(number, count, virt); + } + } read_operation; + + for (unsigned i = 0; request_sizes[i]; i++) + run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, + request_sizes[i], read_operation); + + /* + * Benchmark writing to SD card + * + * We write back the content of the buffer, which we just filled during the + * read benchmark. If both read and write succeed, the SD card will retain + * its original content. + */ + + printf("\n-- writing to SD card --\n"); + + struct Write : Operation + { + void operator () (Block::Driver &driver, + addr_t number, size_t count, addr_t phys, char *virt) + { + if (driver.dma_enabled()) + driver.write_dma(number, count, phys); + else + driver.write(number, count, virt); + } + } write_operation; + + for (unsigned i = 0; request_sizes[i]; i++) + run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, + request_sizes[i], write_operation); + + printf("\n--- OMAP4 SD card benchmark finished ---\n"); sleep_forever(); return 0; }