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"); }
}