rtc_drv: add dummy driver

* Add dummy driver implementation and depot package
* Extend configuration to allow setting an initial RTC value

Fix #4033
This commit is contained in:
Stefan Kalkowski 2021-02-26 11:29:59 +01:00 committed by Norman Feske
parent d4b58b689c
commit 10b56afff0
8 changed files with 122 additions and 55 deletions

View File

@ -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)

View File

@ -0,0 +1 @@
2021-02-26-a 83b73850330c570cb358e2c45147e831735c78c5

View File

@ -0,0 +1,3 @@
base
os
rtc_session

View File

@ -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 {
<policy label_suffix="set_rtc" report="test-rtc -> set_rtc"/>
</config>
</start>}
append_if [have_spec linux] config {
append_if [have_board linux] config {
<start name="linux_rtc_drv" priority="-1" ld="no">}
append_if [expr ![have_spec linux]] config {
append_if [have_board pc] config {
<start name="rtc_drv" priority="-1">}
append_if [expr ![have_board pc] && ![have_board linux]] config {
<start name="dummy_rtc_drv" priority="-1">}
append config {
<resource name="RAM" quantum="1M"/>
<provides><service name="Rtc"/></provides>}

View File

@ -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.

View File

@ -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.h>
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;
}

View File

@ -0,0 +1,4 @@
TARGET = dummy_rtc_drv
LIBS = base
include $(REP_DIR)/src/drivers/rtc/target.inc

View File

@ -111,6 +111,9 @@ struct Rtc::Main
Constructible<Attached_rom_dataspace> _update_rom { };
struct Invalid_timestamp_xml : Exception {};
Timestamp _parse_xml(Xml_node);
void _handle_update();
Signal_handler<Main> _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"); }
}