Implemented the PPC specific RTC support. We search for an "rtc"
device in the Open Firmware implementation of boot loader and pass its path to the kernel, where it's opened and used for getting/setting the real time. The expensive atomic_*64() on PPC 32-bit make things a bit more complicated. Moreover, missing 64 bit multiplication and division instructions won't really allow system_time() to be anywhere near as fast as on x86. :-/ git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15837 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -8,7 +8,8 @@ MergeObject os_arch_$(TARGET_ARCH).o :
|
||||
compatibility.c # only here until the places where those functions are used
|
||||
# are fixed
|
||||
# systeminfo.c
|
||||
system_time.S
|
||||
system_time.c
|
||||
system_time_asm.S
|
||||
thread.c
|
||||
time.c
|
||||
tls.c
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <[email protected]>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <arch_cpu.h>
|
||||
#include <libroot_private.h>
|
||||
#include <real_time_data.h>
|
||||
|
||||
|
||||
static vint64 *sConversionFactor;
|
||||
|
||||
void
|
||||
__ppc_setup_system_time(vint64 *cvFactor)
|
||||
{
|
||||
sConversionFactor = cvFactor;
|
||||
}
|
||||
|
||||
|
||||
// Note: We don't implement system_time() in assembly since the 64 bit
|
||||
// divisions/multiplications are a bit tough to implement for a 32 bit
|
||||
// PPC.
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
uint64 timeBase = __ppc_get_time_base();
|
||||
// TODO: The multiplication doesn't look that nice. The value can easily
|
||||
// overflow when timeBase gets big enough. The limit for timebase is
|
||||
// about 2^(64 - 20). This might sound a lot, but the conversion factor
|
||||
// might be quite big. Assuming a worst case factor of 2^32,
|
||||
// this would leave us with only about 2^12 = 4096 seconds we can
|
||||
// represent. The actual factor for my Mac mini is about 40 * 10^6, i.e.
|
||||
// the overflow limit is ca. 100 times greater, but that isn't more than
|
||||
// five days either.
|
||||
return (timeBase * 1000000ULL) / *sConversionFactor;
|
||||
}
|
||||
@@ -10,14 +10,33 @@
|
||||
#include <real_time_data.h>
|
||||
|
||||
|
||||
static struct arch_real_time_data *sRealTimeData;
|
||||
|
||||
void
|
||||
__arch_init_time(struct real_time_data *data, bool setDefaults)
|
||||
{
|
||||
sRealTimeData = &data->arch_data;
|
||||
|
||||
if (setDefaults) {
|
||||
data->arch_data.data[0].system_time_offset = 0;
|
||||
data->arch_data.system_time_conversion_factor = 1000000000LL;
|
||||
data->arch_data.version = 0;
|
||||
sRealTimeData->data[0].system_time_offset = 0;
|
||||
sRealTimeData->system_time_conversion_factor = 1000000000LL;
|
||||
sRealTimeData->version = 0;
|
||||
}
|
||||
|
||||
__ppc_setup_system_time(&data->arch_data.system_time_conversion_factor);
|
||||
__ppc_setup_system_time(&sRealTimeData->system_time_conversion_factor);
|
||||
}
|
||||
|
||||
|
||||
bigtime_t
|
||||
__arch_get_system_time_offset(struct real_time_data *data)
|
||||
{
|
||||
int32 version;
|
||||
bigtime_t offset;
|
||||
do {
|
||||
version = sRealTimeData->version;
|
||||
offset = sRealTimeData->data[version % 2].system_time_offset;
|
||||
} while (version != sRealTimeData->version);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ MergeObject os_arch_$(TARGET_ARCH).o :
|
||||
compatibility.c
|
||||
get_stack_frame.S
|
||||
system_info.c
|
||||
system_time.S
|
||||
system_time_asm.S
|
||||
thread.c
|
||||
time.c
|
||||
tls.c
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
Just a dummy to avoid a special case in the build system. system_time()
|
||||
is implemented in system_time_asm.S.
|
||||
*/
|
||||
Reference in New Issue
Block a user