xref: /haiku/src/system/kernel/arch/m68k/arch_real_time_clock.cpp (revision b30304acc8c37e678a1bf66976d15bdab103f931)
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