diff --git a/headers/private/kernel/arch/real_time_clock.h b/headers/private/kernel/arch/real_time_clock.h index 50c179917b..0a226303e3 100644 --- a/headers/private/kernel/arch/real_time_clock.h +++ b/headers/private/kernel/arch/real_time_clock.h @@ -25,6 +25,12 @@ void arch_rtc_set_hw_time(uint32 seconds); uint32 arch_rtc_get_hw_time(void); // Returns number of seconds since 1/1/1970 as stored in HW +void arch_rtc_set_system_time_offset(struct real_time_data *data, + bigtime_t offset); + // Set the system time offset in data. +bigtime_t arch_rtc_get_system_time_offset(struct real_time_data *data); + // Return the system time offset as stored in data. + #ifdef __cplusplus } #endif diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index ec7e48a69d..b1186f87f6 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -97,7 +97,7 @@ extern "C" { struct arch_thread; -void setup_system_time(uint32 cv_factor); +void __x86_setup_system_time(uint32 cv_factor); void i386_context_switch(struct arch_thread *old_state, struct arch_thread *new_state, addr_t new_pgdir); void i386_enter_uspace(addr_t entry, void *args1, void *args2, addr_t ustack_top); void i386_set_tss_and_kstack(addr_t kstack); diff --git a/headers/private/kernel/arch/x86/arch_real_time_data.h b/headers/private/kernel/arch/x86/arch_real_time_data.h new file mode 100644 index 0000000000..9651676969 --- /dev/null +++ b/headers/private/kernel/arch/x86/arch_real_time_data.h @@ -0,0 +1,17 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_REAL_TIME_DATA_H +#define _KERNEL_ARCH_REAL_TIME_DATA_H + +#include +#include + + +struct arch_real_time_data { + bigtime_t system_time_offset; + uint32 system_time_conversion_factor; +}; + +#endif /* _KERNEL_ARCH_REAL_TIME_DATA_H */ diff --git a/headers/private/kernel/real_time_data.h b/headers/private/kernel/real_time_data.h index 5ac2631493..9977a2dc75 100644 --- a/headers/private/kernel/real_time_data.h +++ b/headers/private/kernel/real_time_data.h @@ -8,13 +8,11 @@ #include #include +#include -// ToDo: most of this is probably arch dependent. When the PPC port comes -// to this, it should be properly separated and moved into the arch tree. struct real_time_data { - bigtime_t system_time_offset; - uint32 system_time_conversion_factor; + struct arch_real_time_data arch_data; }; #endif /* _KERNEL_REAL_TIME_DATA_H */ diff --git a/headers/private/libroot/libroot_private.h b/headers/private/libroot/libroot_private.h index 9fe425a794..4bfbb77ca0 100644 --- a/headers/private/libroot/libroot_private.h +++ b/headers/private/libroot/libroot_private.h @@ -21,7 +21,8 @@ void __init_env(const struct uspace_program_args *args); void __init_heap(void); void __init_time(void); -void __arch_init_time(struct real_time_data *data); +void __arch_init_time(struct real_time_data *data, bool setDefaults); +bigtime_t __arch_get_system_time_offset(struct real_time_data *data); extern char _single_threaded; diff --git a/src/system/kernel/arch/x86/arch_cpu.c b/src/system/kernel/arch/x86/arch_cpu.c index 5436c50e0f..70a1e4f814 100644 --- a/src/system/kernel/arch/x86/arch_cpu.c +++ b/src/system/kernel/arch/x86/arch_cpu.c @@ -212,7 +212,7 @@ arch_cpu_preboot_init(kernel_args *args) status_t arch_cpu_init(kernel_args *args) { - setup_system_time(args->arch_args.system_time_cv_factor); + __x86_setup_system_time(args->arch_args.system_time_cv_factor); return B_OK; } diff --git a/src/system/kernel/arch/x86/arch_real_time_clock.c b/src/system/kernel/arch/x86/arch_real_time_clock.c index f49acb80e0..c4ca8bad40 100644 --- a/src/system/kernel/arch/x86/arch_real_time_clock.c +++ b/src/system/kernel/arch/x86/arch_real_time_clock.c @@ -178,7 +178,8 @@ secs_to_cmos(uint32 seconds, cmos_time *cmos) status_t arch_rtc_init(struct kernel_args *args, struct real_time_data *data) { - data->system_time_conversion_factor = args->arch_args.system_time_cv_factor; + data->arch_data.system_time_conversion_factor + = args->arch_args.system_time_cv_factor; return B_OK; } @@ -214,3 +215,17 @@ arch_rtc_set_hw_time(uint32 seconds) secs_to_cmos(seconds, &cmos); write_cmos_clock(&cmos); } + + +void +arch_rtc_set_system_time_offset(struct real_time_data *data, bigtime_t offset) +{ + atomic_set64(&data->arch_data.system_time_offset, offset); +} + + +bigtime_t +arch_rtc_get_system_time_offset(struct real_time_data *data) +{ + return atomic_get64(&data->arch_data.system_time_offset); +} diff --git a/src/system/kernel/real_time_clock.c b/src/system/kernel/real_time_clock.c index 8093d886d7..471c9a9b7e 100644 --- a/src/system/kernel/real_time_clock.c +++ b/src/system/kernel/real_time_clock.c @@ -36,7 +36,7 @@ rtc_system_to_hw(void) { uint32 seconds; - seconds = (sRealTimeData->system_time_offset + system_time() + seconds = (arch_rtc_get_system_time_offset(sRealTimeData) + system_time() - (sIsGMT ? 0 : sTimezoneOffset)) / 1000000; arch_rtc_set_hw_time(seconds); @@ -58,7 +58,7 @@ rtc_hw_to_system(void) bigtime_t rtc_boot_time(void) { - return sRealTimeData->system_time_offset; + return arch_rtc_get_system_time_offset(sRealTimeData); } @@ -68,10 +68,12 @@ rtc_debug(int argc, char **argv) if (argc < 2) { // If no arguments were given, output all useful data. uint32 currentTime; + bigtime_t systemTimeOffset + = arch_rtc_get_system_time_offset(sRealTimeData); - currentTime = (sRealTimeData->system_time_offset + system_time()) / 1000000; + currentTime = (systemTimeOffset + system_time()) / 1000000; dprintf("system_time: %Ld\n", system_time()); - dprintf("system_time_offset: %Ld\n", sRealTimeData->system_time_offset); + dprintf("system_time_offset: %Ld\n", systemTimeOffset); dprintf("current_time: %lu\n", currentTime); } else { // If there was an argument, reset the system and hw time. @@ -122,7 +124,8 @@ rtc_init(kernel_args *args) void set_real_time_clock(uint32 currentTime) { - atomic_set64(&sRealTimeData->system_time_offset, currentTime * 1000000LL - system_time()); + arch_rtc_set_system_time_offset(sRealTimeData, + currentTime * 1000000LL - system_time()); rtc_system_to_hw(); } @@ -130,14 +133,15 @@ set_real_time_clock(uint32 currentTime) uint32 real_time_clock(void) { - return (sRealTimeData->system_time_offset + system_time()) / 1000000; + return (arch_rtc_get_system_time_offset(sRealTimeData) + system_time()) + / 1000000; } bigtime_t real_time_clock_usecs(void) { - return sRealTimeData->system_time_offset + system_time(); + return arch_rtc_get_system_time_offset(sRealTimeData) + system_time(); } @@ -315,18 +319,23 @@ _user_set_timezone(time_t timezoneOffset, bool daylightSavingTime) if (geteuid() != 0) return B_NOT_ALLOWED; - TRACE(("old system_time_offset %Ld old %Ld new %Ld gmt %d\n", sRealTimeData->system_time_offset, sTimezoneOffset, offset, sIsGMT)); + TRACE(("old system_time_offset %Ld old %Ld new %Ld gmt %d\n", + arch_rtc_get_system_time_offset(sRealTimeData), sTimezoneOffset, offset, + sIsGMT)); // We only need to update our time offset if the hardware clock // does not run in the local timezone. // Since this is shared data, we need to update it atomically. - if (!sIsGMT) - atomic_add64(&sRealTimeData->system_time_offset, sTimezoneOffset - offset); + if (!sIsGMT) { + arch_rtc_set_system_time_offset(sRealTimeData, + sTimezoneOffset - offset); + } sTimezoneOffset = offset; sDaylightSavingTime = daylightSavingTime; - TRACE(("new system_time_offset %Ld\n", sRealTimeData->system_time_offset)); + TRACE(("new system_time_offset %Ld\n", + arch_rtc_get_system_time_offset(sRealTimeData))); return B_OK; } diff --git a/src/system/libroot/os/arch/ppc/system_time.S b/src/system/libroot/os/arch/ppc/system_time.S index 16d0d80074..d425d756b2 100644 --- a/src/system/libroot/os/arch/ppc/system_time.S +++ b/src/system/libroot/os/arch/ppc/system_time.S @@ -1,5 +1,5 @@ /* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Copyright 2003, Axel D�fler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ @@ -7,16 +7,11 @@ .text -// ToDo: note, this function absolutely doesn't do what it should do. -// It only reads out the time base register, but it doesn't compute -// the real system time from its value. -// To do so, the kernel has to provide the appropriate system dependent -// conversion factors. - -/* uint64 system_time(void) +/* int64 __ppc_get_time_base(void) * r3/r4 */ -FUNCTION(system_time): +FUNCTION(__ppc_get_time_base): + /* get TB (time base) register */ carry: mftbu %r3 mftb %r4 mftbu %r5 // read the upper half again diff --git a/src/system/libroot/os/arch/ppc/time.c b/src/system/libroot/os/arch/ppc/time.c index 343a9c5251..1ee63294fc 100644 --- a/src/system/libroot/os/arch/ppc/time.c +++ b/src/system/libroot/os/arch/ppc/time.c @@ -3,15 +3,21 @@ * Distributed under the terms of the MIT License. */ +#include +#include #include #include -#include void -__arch_init_time(struct real_time_data *data) +__arch_init_time(struct real_time_data *data, bool setDefaults) { - // TODO: Implement! -} + if (setDefaults) { + data->arch_data.data[0].system_time_offset = 0; + data->arch_data.system_time_conversion_factor = 1000000000LL; + data->arch_data.version = 0; + } + __ppc_setup_system_time(&data->arch_data.system_time_conversion_factor); +} diff --git a/src/system/libroot/os/arch/x86/system_time.S b/src/system/libroot/os/arch/x86/system_time.S index 7dd25fde4e..cb9e12a836 100644 --- a/src/system/libroot/os/arch/x86/system_time.S +++ b/src/system/libroot/os/arch/x86/system_time.S @@ -11,7 +11,7 @@ cv_factor: .word 0 -FUNCTION(setup_system_time): +FUNCTION(__x86_setup_system_time): movl 4(%esp),%eax movl %eax,cv_factor ret diff --git a/src/system/libroot/os/arch/x86/time.c b/src/system/libroot/os/arch/x86/time.c index 80c312d1a3..307af3ffc4 100644 --- a/src/system/libroot/os/arch/x86/time.c +++ b/src/system/libroot/os/arch/x86/time.c @@ -10,10 +10,21 @@ void -__arch_init_time(struct real_time_data *data) +__arch_init_time(struct real_time_data *data, bool setDefaults) { + if (setDefaults) { + data->arch_data.system_time_offset = 0; + data->arch_data.system_time_conversion_factor = 100000; + } + // ToDo: this should only store a pointer to that value - // ToDo: this function should not clobber the global name space - setup_system_time(data->system_time_conversion_factor); + __x86_setup_system_time(data->arch_data.system_time_conversion_factor); +} + + +bigtime_t +__arch_get_system_time_offset(struct real_time_data *data) +{ + return atomic_get64(&data->arch_data.system_time_offset); } diff --git a/src/system/libroot/os/time.c b/src/system/libroot/os/time.c index ab4fb71061..46da5e97a7 100644 --- a/src/system/libroot/os/time.c +++ b/src/system/libroot/os/time.c @@ -14,16 +14,14 @@ #include -static struct real_time_data sRealTimeDefaults = { - 0, - 100000 -}; +static struct real_time_data sRealTimeDefaults; static struct real_time_data *sRealTimeData; void __init_time(void) { + bool setDefaults = false; area_id dataArea; area_info info; @@ -31,24 +29,26 @@ __init_time(void) if (dataArea < 0 || get_area_info(dataArea, &info) < B_OK) { syslog(LOG_ERR, "error finding real time data area: %s\n", strerror(dataArea)); sRealTimeData = &sRealTimeDefaults; + setDefaults = true; } else sRealTimeData = (struct real_time_data *)info.address; - __arch_init_time(sRealTimeData); + __arch_init_time(sRealTimeData, setDefaults); } uint32 real_time_clock(void) { - return (sRealTimeData->system_time_offset + system_time()) / 1000000; + return (__arch_get_system_time_offset(sRealTimeData) + system_time()) + / 1000000; } bigtime_t real_time_clock_usecs(void) { - return sRealTimeData->system_time_offset + system_time(); + return __arch_get_system_time_offset(sRealTimeData) + system_time(); }