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
This commit is contained in:
Andreas Färber 2010-08-30 21:13:10 +00:00
parent eb01f516a3
commit 56f837e265
3 changed files with 32 additions and 2 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* Copyright 2010, Andreas Färber <andreas.faerber@web.de>
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -14,6 +15,9 @@
#include <platform/openfirmware/openfirmware.h>
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;
}

View File

@ -12,6 +12,8 @@
extern "C" {
#endif
extern int gRTC;
status_t init_real_time_clock(void);
#ifdef __cplusplus

View File

@ -1,5 +1,6 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* Copyright 2010, Andreas Färber <andreas.faerber@web.de>
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -8,10 +9,27 @@
#include <platform/openfirmware/openfirmware.h>
#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;
}