From 10b56afff00055c4a74cfbb5e4912e945eef380d Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 26 Feb 2021 11:29:59 +0100 Subject: [PATCH] rtc_drv: add dummy driver * Add dummy driver implementation and depot package * Extend configuration to allow setting an initial RTC value Fix #4033 --- repos/os/recipes/src/dummy_rtc_drv/content.mk | 10 ++ repos/os/recipes/src/dummy_rtc_drv/hash | 1 + repos/os/recipes/src/dummy_rtc_drv/used_apis | 3 + repos/os/run/rtc.run | 17 ++- repos/os/src/drivers/rtc/README | 3 + repos/os/src/drivers/rtc/dummy/rtc.cc | 30 +++++ repos/os/src/drivers/rtc/dummy/target.mk | 4 + repos/os/src/drivers/rtc/main.cc | 109 ++++++++++-------- 8 files changed, 122 insertions(+), 55 deletions(-) create mode 100644 repos/os/recipes/src/dummy_rtc_drv/content.mk create mode 100644 repos/os/recipes/src/dummy_rtc_drv/hash create mode 100644 repos/os/recipes/src/dummy_rtc_drv/used_apis create mode 100644 repos/os/src/drivers/rtc/dummy/rtc.cc create mode 100644 repos/os/src/drivers/rtc/dummy/target.mk diff --git a/repos/os/recipes/src/dummy_rtc_drv/content.mk b/repos/os/recipes/src/dummy_rtc_drv/content.mk new file mode 100644 index 0000000000..bb9eff50b5 --- /dev/null +++ b/repos/os/recipes/src/dummy_rtc_drv/content.mk @@ -0,0 +1,10 @@ +SRC_DIR = src/drivers/rtc/dummy +include $(GENODE_DIR)/repos/base/recipes/src/content.inc + +CONTENT = src/drivers/rtc/README src/drivers/rtc/rtc.h src/drivers/rtc/main.cc \ + src/drivers/rtc/target.inc + +content: $(CONTENT) + +$(CONTENT): + $(mirror_from_rep_dir) diff --git a/repos/os/recipes/src/dummy_rtc_drv/hash b/repos/os/recipes/src/dummy_rtc_drv/hash new file mode 100644 index 0000000000..051e2bdbb6 --- /dev/null +++ b/repos/os/recipes/src/dummy_rtc_drv/hash @@ -0,0 +1 @@ +2021-02-26-a 83b73850330c570cb358e2c45147e831735c78c5 diff --git a/repos/os/recipes/src/dummy_rtc_drv/used_apis b/repos/os/recipes/src/dummy_rtc_drv/used_apis new file mode 100644 index 0000000000..9333ff50a7 --- /dev/null +++ b/repos/os/recipes/src/dummy_rtc_drv/used_apis @@ -0,0 +1,3 @@ +base +os +rtc_session diff --git a/repos/os/run/rtc.run b/repos/os/run/rtc.run index 203613b50a..c693e4b32a 100644 --- a/repos/os/run/rtc.run +++ b/repos/os/run/rtc.run @@ -1,17 +1,20 @@ # RTC test -assert_spec x86 - create_boot_directory set depot_pkgs "[depot_user]/src/[base_src] [depot_user]/src/init [depot_user]/src/report_rom" -if [have_spec linux] { +if [have_board linux] { lappend depot_pkgs [depot_user]/src/linux_rtc_drv } else { - lappend depot_pkgs [depot_user]/src/rtc_drv + if [have_board pc] { + lappend depot_pkgs [depot_user]/src/rtc_drv + } else { + lappend depot_pkgs [depot_user]/src/dummy_rtc_drv + } } +puts $depot_pkgs import_from_depot $depot_pkgs # RTC setting tested on Qemu only @@ -45,10 +48,12 @@ append_if $test_update config { } -append_if [have_spec linux] config { +append_if [have_board linux] config { } -append_if [expr ![have_spec linux]] config { +append_if [have_board pc] config { } +append_if [expr ![have_board pc] && ![have_board linux]] config { + } append config { } diff --git a/repos/os/src/drivers/rtc/README b/repos/os/src/drivers/rtc/README index d9f26bd5a7..ab15fda82d 100644 --- a/repos/os/src/drivers/rtc/README +++ b/repos/os/src/drivers/rtc/README @@ -13,5 +13,8 @@ the following attributes: * 'minute' (0 - 59) * 'second' (0 - 59) +The same attributes can be set in the configuration node of the driver +to initially set the RTC to the givven value. + The component will always use 24H mode and relies on the BIOS/firmware to do the right thing regarding the year. diff --git a/repos/os/src/drivers/rtc/dummy/rtc.cc b/repos/os/src/drivers/rtc/dummy/rtc.cc new file mode 100644 index 0000000000..5b045ec69e --- /dev/null +++ b/repos/os/src/drivers/rtc/dummy/rtc.cc @@ -0,0 +1,30 @@ +/* + * \brief RTC dummy driver + * \author Stefan Kalkowski + * \date 2021-02-25 + */ + +/* + * Copyright (C) 2021 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. + */ + +#include + +Rtc::Timestamp & current_ts() +{ + static Rtc::Timestamp cur {}; + return cur; +} + + +Rtc::Timestamp Rtc::get_time(Env &) { return current_ts(); } + + +void Rtc::set_time(Env &, Timestamp ts) +{ + Timestamp & cur = current_ts(); + cur = ts; +} diff --git a/repos/os/src/drivers/rtc/dummy/target.mk b/repos/os/src/drivers/rtc/dummy/target.mk new file mode 100644 index 0000000000..e7cd80edfc --- /dev/null +++ b/repos/os/src/drivers/rtc/dummy/target.mk @@ -0,0 +1,4 @@ +TARGET = dummy_rtc_drv +LIBS = base + +include $(REP_DIR)/src/drivers/rtc/target.inc diff --git a/repos/os/src/drivers/rtc/main.cc b/repos/os/src/drivers/rtc/main.cc index 82f3e2b6ab..3ec7897722 100644 --- a/repos/os/src/drivers/rtc/main.cc +++ b/repos/os/src/drivers/rtc/main.cc @@ -111,6 +111,9 @@ struct Rtc::Main Constructible _update_rom { }; + struct Invalid_timestamp_xml : Exception {}; + + Timestamp _parse_xml(Xml_node); void _handle_update(); Signal_handler
_update_sigh { @@ -123,11 +126,63 @@ struct Rtc::Main _update_rom->sigh(_update_sigh); } + try { + Rtc::set_time(env, _parse_xml(_config_rom.xml())); + } catch (Invalid_timestamp_xml &) {} + env.parent().announce(env.ep().manage(root)); } }; +Rtc::Timestamp Rtc::Main::_parse_xml(Xml_node node) +{ + bool const complete = node.has_attribute("year") + && node.has_attribute("month") + && node.has_attribute("day") + && node.has_attribute("hour") + && node.has_attribute("minute") + && node.has_attribute("second"); + + if (!complete) { throw Invalid_timestamp_xml(); } + + Timestamp ts { }; + + ts.second = node.attribute_value("second", 0u); + if (ts.second > 59) { + Genode::error("set_rtc: second invalid"); + throw Invalid_timestamp_xml(); + } + + ts.minute = node.attribute_value("minute", 0u); + if (ts.minute > 59) { + Genode::error("set_rtc: minute invalid"); + throw Invalid_timestamp_xml(); + } + + ts.hour = node.attribute_value("hour", 0u); + if (ts.hour > 23) { + Genode::error("set_rtc: hour invalid"); + throw Invalid_timestamp_xml(); + } + + ts.day = node.attribute_value("day", 1u); + if (ts.day > 31 || ts.day == 0) { + Genode::error("set_rtc: day invalid"); + throw Invalid_timestamp_xml(); + } + + ts.month = node.attribute_value("month", 1u); + if (ts.month > 12 || ts.month == 0) { + Genode::error("set_rtc: month invalid"); + throw Invalid_timestamp_xml(); + } + + ts.year = node.attribute_value("year", 2019u); + return ts; +} + + void Rtc::Main::_handle_update() { _update_rom->update(); @@ -136,55 +191,11 @@ void Rtc::Main::_handle_update() Genode::Xml_node node = _update_rom->xml(); - bool const complete = node.has_attribute("year") - && node.has_attribute("month") - && node.has_attribute("day") - && node.has_attribute("hour") - && node.has_attribute("minute") - && node.has_attribute("second"); - - if (!complete) { - Genode::warning("set_rtc: ignoring incomplete RTC update"); - return; - } - - Timestamp ts { }; - - ts.second = node.attribute_value("second", 0u); - if (ts.second > 59) { - Genode::error("set_rtc: second invalid"); - return; - } - - ts.minute = node.attribute_value("minute", 0u); - if (ts.minute > 59) { - Genode::error("set_rtc: minute invalid"); - return; - } - - ts.hour = node.attribute_value("hour", 0u); - if (ts.hour > 23) { - Genode::error("set_rtc: hour invalid"); - return; - } - - ts.day = node.attribute_value("day", 1u); - if (ts.day > 31 || ts.day == 0) { - Genode::error("set_rtc: day invalid"); - return; - } - - ts.month = node.attribute_value("month", 1u); - if (ts.month > 12 || ts.month == 0) { - Genode::error("set_rtc: month invalid"); - return; - } - - ts.year = node.attribute_value("year", 2019u); - - Rtc::set_time(env, ts); - - root.notify_clients(); + try { + Rtc::set_time(env, _parse_xml(node)); + root.notify_clients(); + } catch (Invalid_timestamp_xml &) { + Genode::warning("set_rtc: ignoring incomplete RTC update"); } }