1/* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8 9#include <asm_defs.h> 10 11 12/* saves the conversion factor needed for system_time */ 13.lcomm cv_factor 4 14.lcomm cv_factor_nsecs 4 15.lcomm cv_factor_nsecs_shift 1 16 17 18.text 19 20 21FUNCTION(__x86_setup_system_time): 22 movl 4(%esp), %eax 23 movl %eax, cv_factor 24 movl 8(%esp), %eax 25 movl %eax, cv_factor_nsecs 26 movb 12(%esp), %al 27 movb %al, cv_factor_nsecs_shift 28 ret 29FUNCTION_END(__x86_setup_system_time) 30 31 32/* int64 system_time(); */ 33FUNCTION(system_time): 34 pushl %ebx 35 pushl %ecx 36 movl cv_factor, %ebx 37 38 /* load 64-bit factor into %eax (low), %edx (high) */ 39 rdtsc /* time in %edx,%eax */ 40 41 movl %edx, %ecx /* save high half */ 42 mull %ebx /* truncate %eax, but keep %edx */ 43 movl %ecx, %eax 44 movl %edx, %ecx /* save high half of low */ 45 mull %ebx /*, %eax*/ 46 /* now compute [%edx, %eax] + [%ecx], propagating carry */ 47 subl %ebx, %ebx /* need zero to propagate carry */ 48 addl %ecx, %eax 49 adc %ebx, %edx 50 popl %ecx 51 popl %ebx 52 ret 53FUNCTION_END(system_time) 54 55 56/* int64 system_time_nsecs(); */ 57FUNCTION(system_time_nsecs): 58 testb $0, cv_factor_nsecs_shift 59 jne 1f 60 61 /* same algorithm as system_time(), just with a different factor */ 62 63 pushl %ebx 64 pushl %ecx 65 movl cv_factor_nsecs, %ebx 66 67 /* load 64-bit factor into %eax (low), %edx (high) */ 68 rdtsc /* time in %edx,%eax */ 69 70 movl %edx, %ecx /* save high half */ 71 mull %ebx /* truncate %eax, but keep %edx */ 72 movl %ecx, %eax 73 movl %edx, %ecx /* save high half of low */ 74 mull %ebx /*, %eax*/ 75 /* now compute [%edx, %eax] + [%ecx], propagating carry */ 76 subl %ebx, %ebx /* need zero to propagate carry */ 77 addl %ecx, %eax 78 adc %ebx, %edx 79 popl %ecx 80 popl %ebx 81 ret 82 831: 84 /* TSC frequency is less than 1 GHz -- we shift everything up 16 bit */ 85 86 pushl %ebx 87 pushl %ecx 88 pushl %esi 89 movl cv_factor_nsecs, %ebx 90 91 /* load 64-bit factor into %eax (low), %edx (high) */ 92 rdtsc /* time in %edx,%eax */ 93 94 /* save high half */ 95 movl %edx, %ecx 96 97 /* multiply low half by conversion factor */ 98 mull %ebx 99 100 /* save result */ 101 movl %eax, %esi /* low half -> %esi */ 102 movl %ecx, %eax 103 movl %edx, %ecx /* high half -> %ecx */ 104 105 /* multiply high half by conversion factor */ 106 mull %ebx 107 108 /* now compute [%edx, %eax] + [%ecx], propagating carry */ 109 xorl %ebx, %ebx /* need zero to propagate carry */ 110 addl %ecx, %eax 111 adc %ebx, %edx 112 113 /* shift the result left 16 bit */ 114 shl $16, %edx 115 movl %eax, %ebx 116 shr $16, %ebx 117 orw %bx, %dx 118 shl $16, %eax 119 120 /* add the high 16 bit of the low half of the low product */ 121 shr $16, %esi 122 orw %si, %ax 123 124 popl %esi 125 popl %ecx 126 popl %ebx 127 ret 128FUNCTION_END(system_time_nsecs) 129