From 56f837e265f8569acf2a1e26bb0b1c00f46b06ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 30 Aug 2010 21:13:10 +0000 Subject: [PATCH] boot_loader_openfirmware: Fix system_time() system_time() was based on of_milliseconds(), which returns the number of milliseconds since power-on. This would produce very similar or identical results for subsequent boots due to limited clock resolution; therefore it was unsuited as PRNG seed, e.g., for TCP ports. Try to inquire the RTC device node with get-time to return an improved time value, if possible. Closes ticket #6061. Changes from proposed patch: * Obtain the RTC handle once and reuse it for each inquiry. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38465 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../platform/openfirmware/real_time_clock.cpp | 10 +++++++++ .../platform/openfirmware/real_time_clock.h | 2 ++ .../boot/platform/openfirmware/support.cpp | 22 +++++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/system/boot/platform/openfirmware/real_time_clock.cpp b/src/system/boot/platform/openfirmware/real_time_clock.cpp index a87f851713..2fb0aab5df 100644 --- a/src/system/boot/platform/openfirmware/real_time_clock.cpp +++ b/src/system/boot/platform/openfirmware/real_time_clock.cpp @@ -1,5 +1,6 @@ /* * Copyright 2006, Ingo Weinhold . + * Copyright 2010, Andreas Färber * All rights reserved. Distributed under the terms of the MIT License. */ @@ -14,6 +15,9 @@ #include +int gRTC = OF_FAILED; + + status_t init_real_time_clock(void) { @@ -26,6 +30,12 @@ init_real_time_clock(void) return B_ERROR; } + gRTC = of_open(gKernelArgs.platform_args.rtc_path); + if (gRTC == OF_FAILED) { + printf("%s(): Could not open RTC device!\n", __func__); + return B_ERROR; + } + return B_OK; } diff --git a/src/system/boot/platform/openfirmware/real_time_clock.h b/src/system/boot/platform/openfirmware/real_time_clock.h index 2714197f1c..4c7e203ea6 100644 --- a/src/system/boot/platform/openfirmware/real_time_clock.h +++ b/src/system/boot/platform/openfirmware/real_time_clock.h @@ -12,6 +12,8 @@ extern "C" { #endif +extern int gRTC; + status_t init_real_time_clock(void); #ifdef __cplusplus diff --git a/src/system/boot/platform/openfirmware/support.cpp b/src/system/boot/platform/openfirmware/support.cpp index 2333b8eb24..806f3a869c 100644 --- a/src/system/boot/platform/openfirmware/support.cpp +++ b/src/system/boot/platform/openfirmware/support.cpp @@ -1,5 +1,6 @@ /* * Copyright 2005, Ingo Weinhold . + * Copyright 2010, Andreas Färber * All rights reserved. Distributed under the terms of the MIT License. */ @@ -8,10 +9,27 @@ #include +#include "real_time_clock.h" + bigtime_t system_time(void) { - int result = of_milliseconds(); - return (result == OF_FAILED ? 0 : bigtime_t(result) * 1000); + int milliseconds = of_milliseconds(); + if (milliseconds == OF_FAILED) + milliseconds = 0; + bigtime_t result = milliseconds; + int second, minute, hour, day, month, year; + if (gRTC != OF_FAILED) { + if (of_call_method(gRTC, "get-time", 0, 6, &year, &month, &day, + &hour, &minute, &second) != OF_FAILED) { + result %= 1000; + int days = day; + // TODO: Apply algorithm from kernel + // to assure monotonically increasing date. + result += (((days * 24 + hour) * 60ULL + minute) * 60ULL + second) + * 1000ULL; + } + } + return result * 1000; }