From 0a835e4ce9def409e630d4bfd1ce0f9e90bf8d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Tue, 27 Jan 2015 13:56:16 +0100 Subject: [PATCH] os: structured timestamp in Rtc session Instead of returning an uint64_t value, return a structured time stamp. This change is only visible to components using Rtc_session directly. Fixes #1381. --- repos/os/include/rtc_session/client.h | 4 +-- repos/os/include/rtc_session/rtc_session.h | 22 ++++++++---- repos/os/include/vfs/rtc_file_system.h | 42 +++++++++++++++------- repos/os/run/rtc.run | 2 -- repos/os/src/drivers/rtc/x86/linux.cc | 19 +++++++--- repos/os/src/drivers/rtc/x86/main.cc | 4 +-- repos/os/src/drivers/rtc/x86/rtc.cc | 40 ++------------------- repos/os/src/drivers/rtc/x86/rtc.h | 4 +-- repos/os/src/test/rtc/main.cc | 8 ++--- repos/ports/run/noux_bash.run | 11 +++++- repos/ports/src/app/seoul/main.cc | 11 ++++-- repos/ports/src/noux/main.cc | 3 ++ 12 files changed, 94 insertions(+), 76 deletions(-) diff --git a/repos/os/include/rtc_session/client.h b/repos/os/include/rtc_session/client.h index 57a6861df..477855380 100644 --- a/repos/os/include/rtc_session/client.h +++ b/repos/os/include/rtc_session/client.h @@ -6,7 +6,7 @@ /* * Copyright (C) 2012 Intel Corporation - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2013-14 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. @@ -25,7 +25,7 @@ namespace Rtc { Session_client(Genode::Capability cap) : Genode::Rpc_client(cap) {} - Genode::uint64_t current_time() + Timestamp current_time() { return call(); } diff --git a/repos/os/include/rtc_session/rtc_session.h b/repos/os/include/rtc_session/rtc_session.h index a6a0b61c6..fb3886412 100644 --- a/repos/os/include/rtc_session/rtc_session.h +++ b/repos/os/include/rtc_session/rtc_session.h @@ -1,12 +1,13 @@ /* * \brief Rtc session interface * \author Markus Partheymueller + * \author Josef Soentgen * \date 2012-11-15 */ /* * Copyright (C) 2012 Intel Corporation - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2013-2014 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. @@ -21,16 +22,25 @@ namespace Rtc { + struct Timestamp + { + unsigned microsecond; + unsigned second; + unsigned minute; + unsigned hour; + unsigned day; + unsigned month; + unsigned year; + }; + + struct Session : Genode::Session { static const char *service_name() { return "Rtc"; } - /** - * Get microseconds elapsed since 1.1.1970 UTC. - */ - virtual Genode::uint64_t current_time() = 0; + virtual Timestamp current_time() = 0; - GENODE_RPC(Rpc_current_time, Genode::uint64_t, current_time); + GENODE_RPC(Rpc_current_time, Timestamp, current_time); GENODE_RPC_INTERFACE(Rpc_current_time); }; } diff --git a/repos/os/include/vfs/rtc_file_system.h b/repos/os/include/vfs/rtc_file_system.h index d7c18dc8b..777f867cf 100644 --- a/repos/os/include/vfs/rtc_file_system.h +++ b/repos/os/include/vfs/rtc_file_system.h @@ -18,8 +18,6 @@ #include #include -/* libc includes */ -#include namespace Vfs { class Rtc_file_system; } @@ -40,6 +38,19 @@ class Vfs::Rtc_file_system : public Single_file_system static char const *name() { return "rtc"; } + /********************************* + ** Directory-service interface ** + *********************************/ + + Stat_result stat(char const *path, Stat &out) override + { + Stat_result result = Single_file_system::stat(path, out); + out.mode |= 0444; + + return result; + } + + /******************************** ** File I/O service interface ** ********************************/ @@ -51,7 +62,7 @@ class Vfs::Rtc_file_system : public Single_file_system } /** - * Read the current time from the RTC + * Read the current time from the Rtc session * * On each read the current time is queried and afterwards formated * as '%Y-%m-%d %H:%M\n'. @@ -59,19 +70,26 @@ class Vfs::Rtc_file_system : public Single_file_system Read_result read(Vfs_handle *vfs_handle, char *dst, file_size count, file_size &out_count) override { - time_t t = _rtc.current_time() / 1000000ULL; + enum { TIMESTAMP_LEN = 17 }; - struct tm *tm = localtime(&t); + file_size seek = vfs_handle->seek(); - char buf[16 + 1 + 1]; - Genode::snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d\n", - 1900 + tm->tm_year, /* years since 1900 */ - 1 + tm->tm_mon, /* months since January [0-11] */ - tm->tm_mday, tm->tm_hour, tm->tm_min); + if (seek >= TIMESTAMP_LEN) { + out_count = 0; + return READ_OK; + } - file_size len = count > sizeof(buf) ? sizeof(buf) : count; - Genode::memcpy(dst, buf, len); + Rtc::Timestamp ts = _rtc.current_time(); + char buf[TIMESTAMP_LEN+1]; + char *b = buf; + unsigned n = Genode::snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u\n", + ts.year, ts.month, ts.day, ts.hour, ts.minute); + n -= seek; + b += seek; + + file_size len = count > n ? n : count; + Genode::memcpy(dst, b, len); out_count = len; return READ_OK; diff --git a/repos/os/run/rtc.run b/repos/os/run/rtc.run index a03bacbcf..2844e41dc 100644 --- a/repos/os/run/rtc.run +++ b/repos/os/run/rtc.run @@ -40,5 +40,3 @@ build_boot_image { core init timer rtc_drv test-rtc } append qemu_args " -nographic -m 128 " run_genode_until ".*--- RTC test finished ---.*\n" 20 - -puts "Test succeeded" diff --git a/repos/os/src/drivers/rtc/x86/linux.cc b/repos/os/src/drivers/rtc/x86/linux.cc index 512943bc3..d42629815 100644 --- a/repos/os/src/drivers/rtc/x86/linux.cc +++ b/repos/os/src/drivers/rtc/x86/linux.cc @@ -12,16 +12,25 @@ */ /* Linux includes */ -#include +#include #include "rtc.h" -Genode::uint64_t Rtc::get_time(void) +Rtc::Timestamp Rtc::get_time(void) { - struct timeval now { }; + Timestamp ts { 0 }; - gettimeofday(&now, nullptr); + time_t t = time(NULL); + struct tm *utc = gmtime(&t); + if (utc) { + ts.second = utc->tm_sec; + ts.minute = utc->tm_min; + ts.hour = utc->tm_hour; + ts.day = utc->tm_mday; + ts.month = utc->tm_mon + 1; + ts.year = utc->tm_year + 1900; + } - return now.tv_sec * 1000000ULL + now.tv_usec; + return ts; } diff --git a/repos/os/src/drivers/rtc/x86/main.cc b/repos/os/src/drivers/rtc/x86/main.cc index 764150f11..1793187f8 100644 --- a/repos/os/src/drivers/rtc/x86/main.cc +++ b/repos/os/src/drivers/rtc/x86/main.cc @@ -31,9 +31,9 @@ namespace Rtc { struct Rtc::Session_component : public Genode::Rpc_object { - uint64_t current_time() override + Timestamp current_time() override { - uint64_t ret = Rtc::get_time(); + Timestamp ret = Rtc::get_time(); return ret; } diff --git a/repos/os/src/drivers/rtc/x86/rtc.cc b/repos/os/src/drivers/rtc/x86/rtc.cc index 2d3589b17..f7e893c3f 100644 --- a/repos/os/src/drivers/rtc/x86/rtc.cc +++ b/repos/os/src/drivers/rtc/x86/rtc.cc @@ -28,42 +28,6 @@ using namespace Genode; -/** - * Time helper - */ -static bool is_leap_year(int year) -{ - if (((year & 3) || !((year % 100) != 0)) && (year % 400 != 0)) return false; - return true; -} - -/** - * Return UNIX time from given date and time. - */ -static uint64_t mktime(int day, int mon, int year, int hour, int minutes, int seconds) -{ - bool jan_mar = mon < 3; - uint64_t ret = 0; - ret += (367*(10+mon))/12; - ret += jan_mar*2; - ret -= 719866; - ret += day; - ret += jan_mar * is_leap_year(year); - ret += 365*year; - ret += year/4; - ret -= year/100; - ret += year/400; - ret *= 24; - ret += hour; - ret *= 60; - ret += minutes; - ret *= 60; - ret += seconds; - - return ret; -} - - enum RTC { RTC_SECONDS = 0, @@ -136,7 +100,7 @@ static inline unsigned cmos_read(unsigned char addr) #define BIN_TO_BCD(val) ((val) = (((val)/10) << 4) + (val) % 10) -uint64_t Rtc::get_time(void) +Rtc::Timestamp Rtc::get_time(void) { unsigned year, mon, day, hour, min, sec; int i; @@ -174,5 +138,5 @@ uint64_t Rtc::get_time(void) if ((year += 1900) < 1970) year += 100; - return mktime(day, mon, year, hour, min, sec) * 1000000ULL; + return Timestamp { 0, sec, min, hour, day, mon, year }; } diff --git a/repos/os/src/drivers/rtc/x86/rtc.h b/repos/os/src/drivers/rtc/x86/rtc.h index ee3c0b06a..2b82b535e 100644 --- a/repos/os/src/drivers/rtc/x86/rtc.h +++ b/repos/os/src/drivers/rtc/x86/rtc.h @@ -15,11 +15,11 @@ #define _RTC_H_ #include +#include namespace Rtc { - /* Get real time in microseconds since 1970 */ - Genode::uint64_t get_time(); + Timestamp get_time(); } #endif /* _RTC_H_ */ diff --git a/repos/os/src/test/rtc/main.cc b/repos/os/src/test/rtc/main.cc index a4cde1886..6ab3c6c3e 100644 --- a/repos/os/src/test/rtc/main.cc +++ b/repos/os/src/test/rtc/main.cc @@ -26,11 +26,11 @@ int main(int argc, char **argv) static Timer::Connection timer; for (unsigned i = 0; i < 4; ++i) { - Genode::uint64_t now = rtc.current_time(); + Rtc::Timestamp now = rtc.current_time(); - Genode::printf("RTC: %llu.%06llu seconds since 1970\n", - now / 1000000ULL, - now % 1000000ULL); + Genode::printf("RTC: %u-%02u-%02u %02u:%02u:%02u\n", + now.year, now.month, now.day, + now.hour, now.minute, now.second); timer.msleep(1000); } diff --git a/repos/ports/run/noux_bash.run b/repos/ports/run/noux_bash.run index ffadb685d..06a3ecdd2 100644 --- a/repos/ports/run/noux_bash.run +++ b/repos/ports/run/noux_bash.run @@ -14,6 +14,8 @@ set build_components { drivers/framebuffer drivers/pci drivers/input server/terminal server/ram_fs test/libports/ncurses + + drivers/rtc } lappend_if [use_usb_input] build_components drivers/usb @@ -68,7 +70,11 @@ append config { - } + + + + + } append_if [have_spec sdl] config { @@ -162,6 +168,8 @@ append config { + + @@ -183,6 +191,7 @@ set boot_modules { core init timer ld.lib.so noux terminal ram_fs libc.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so bash.tar coreutils.tar vim.tar + rtc_drv } # platform-specific modules diff --git a/repos/ports/src/app/seoul/main.cc b/repos/ports/src/app/seoul/main.cc index 629ce4ae9..7ec1216ab 100644 --- a/repos/ports/src/app/seoul/main.cc +++ b/repos/ports/src/app/seoul/main.cc @@ -61,6 +61,9 @@ #include #include +/* utilities includes */ +#include + /* local includes */ #include "synced_motherboard.h" #include "device_model_registry.h" @@ -1133,8 +1136,12 @@ class Machine : public StaticReceiver return true; } } - /* current_time() returns microseconds */ - msg.wallclocktime = _rtc->current_time() / 1000000U * MessageTime::FREQUENCY; + + Rtc::Timestamp rtc_ts = _rtc->current_time(); + tm_simple tms(rtc_ts.year, rtc_ts.month, rtc_ts.day, rtc_ts.hour, + rtc_ts.minute, rtc_ts.second); + + msg.wallclocktime = mktime(&tms) * MessageTime::FREQUENCY; Logging::printf("Got time %llx\n", msg.wallclocktime); msg.timestamp = _unsynchronized_motherboard.clock()->clock(MessageTime::FREQUENCY); diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc index 4822beee9..06f5108a9 100644 --- a/repos/ports/src/noux/main.cc +++ b/repos/ports/src/noux/main.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -1113,6 +1114,8 @@ int main(int argc, char **argv) fs_factory.add_fs_type(); fs_factory.add_fs_type(); fs_factory.add_fs_type(); + fs_factory.add_fs_type(); + fs_factory.add_fs_type(); fs_factory.add_fs_type(); fs_factory.add_fs_type();