1 /* 2 * Copyright 2007, François Revol, revol@free.fr. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 6 * All rights reserved. Distributed under the terms of the MIT License. 7 */ 8 9 #include <arch/real_time_clock.h> 10 11 #include <arch_platform.h> 12 #include <real_time_data.h> 13 #include <smp.h> 14 15 16 static spinlock sSetArchDataLock; 17 18 status_t 19 arch_rtc_init(kernel_args *args, struct real_time_data *data) 20 { 21 // init the platform RTC service 22 status_t error = M68KPlatform::Default()->InitRTC(args, data); 23 if (error != B_OK) 24 return error; 25 26 // init the arch specific part of the real_time_data 27 data->arch_data.data[0].system_time_offset = 0; 28 // cvFactor = 2^32 * 1000000 / tbFreq 29 // => (tb * cvFactor) >> 32 = (tb * 2^32 * 1000000 / tbFreq) >> 32 30 // = tb / tbFreq * 1000000 = time in us 31 data->arch_data.system_time_conversion_factor 32 = uint32((uint64(1) << 32) * 1000000 33 / args->arch_args.time_base_frequency); 34 data->arch_data.version = 0; 35 36 // init spinlock 37 sSetArchDataLock = 0; 38 39 // init system_time() conversion factor 40 __m68k_setup_system_time(&data->arch_data.system_time_conversion_factor); 41 42 return B_OK; 43 } 44 45 46 uint32 47 arch_rtc_get_hw_time(void) 48 { 49 return M68KPlatform::Default()->GetHardwareRTC(); 50 } 51 52 53 void 54 arch_rtc_set_hw_time(uint32 seconds) 55 { 56 M68KPlatform::Default()->SetHardwareRTC(seconds); 57 } 58 59 60 void 61 arch_rtc_set_system_time_offset(struct real_time_data *data, bigtime_t offset) 62 { 63 cpu_status state = disable_interrupts(); 64 acquire_spinlock(&sSetArchDataLock); 65 66 int32 version = data->arch_data.version + 1; 67 data->arch_data.data[version % 2].system_time_offset = offset; 68 data->arch_data.version = version; 69 70 release_spinlock(&sSetArchDataLock); 71 restore_interrupts(state); 72 } 73 74 75 bigtime_t 76 arch_rtc_get_system_time_offset(struct real_time_data *data) 77 { 78 int32 version; 79 bigtime_t offset; 80 do { 81 version = data->arch_data.version; 82 offset = data->arch_data.data[version % 2].system_time_offset; 83 } while (version != data->arch_data.version); 84 85 return offset; 86 } 87