소스 검색

Use plain C in timer_rdtsc for division instead of inline asssembly.

This also fixes a bug in rdtsc_currticks when the result did not fix in %eax

Signed-off-by: Alexey Zaytsev <zaytsev.a@protei.ru>
tags/v0.9.4
Alexey Zaytsev 16 년 전
부모
커밋
8de54ef9aa
1개의 변경된 파일21개의 추가작업 그리고 43개의 파일을 삭제
  1. 21
    43
      src/arch/i386/drivers/timer_rdtsc.c

+ 21
- 43
src/arch/i386/drivers/timer_rdtsc.c 파일 보기

@@ -14,54 +14,32 @@
14 14
 #define rdtscll(val) \
15 15
      __asm__ __volatile__ ("rdtsc" : "=A" (val))
16 16
 
17
-static unsigned long long calibrate_tsc(void)
17
+
18
+/* Measure how many clocks we get in one microsecond */
19
+static inline uint64_t calibrate_tsc(void)
18 20
 {
19
-	uint32_t startlow, starthigh;
20
-	uint32_t endlow, endhigh;
21
-
22
-	rdtsc(startlow,starthigh);
23
-	i386_timer2_udelay(USECS_IN_MSEC/2);
24
-	rdtsc(endlow,endhigh);
25
-
26
-	/* 64-bit subtract - gcc just messes up with long longs */
27
-	/* XXX ORLY? Check it. */
28
-	__asm__("subl %2,%0\n\t"
29
-		"sbbl %3,%1"
30
-		:"=a" (endlow), "=d" (endhigh)
31
-		:"g" (startlow), "g" (starthigh),
32
-		"0" (endlow), "1" (endhigh));
33
-
34
-	/* Error: ECPUTOOFAST */
35
-	if (endhigh)
36
-		goto bad_ctc;
37
-
38
-	endlow *= MSECS_IN_SEC*2;
39
-	return endlow;
40
-
41
-	/*
42
-	 * The CTC wasn't reliable: we got a hit on the very first read,
43
-	 * or the CPU was so fast/slow that the quotient wouldn't fit in
44
-	 * 32 bits..
45
-	 */
46
-bad_ctc:
47
-	return 0;
21
+
22
+	uint64_t rdtsc_start;
23
+	uint64_t rdtsc_end;
24
+
25
+	rdtscll(rdtsc_start);
26
+	i386_timer2_udelay(USECS_IN_MSEC);
27
+	rdtscll(rdtsc_end);
28
+	
29
+	return (rdtsc_end - rdtsc_start) / USECS_IN_MSEC;
48 30
 }
49
-static uint32_t clocks_per_second = 0;
50 31
 
32
+static uint32_t clocks_per_usec = 0;
33
+
34
+/* We measure time in microseconds. */
51 35
 static tick_t rdtsc_currticks(void)
52 36
 {
53
-	uint32_t clocks_high, clocks_low;
54
-	uint32_t currticks;
37
+	uint64_t clocks;
55 38
 
56 39
 	/* Read the Time Stamp Counter */
57
-	rdtsc(clocks_low, clocks_high);
58
-
59
-	/* currticks = clocks / clocks_per_tick; */
60
-	__asm__("divl %1"
61
-		:"=a" (currticks)
62
-		:"r" (clocks_per_second/USECS_IN_SEC), "0" (clocks_low), "d" (clocks_high));
40
+	rdtscll(clocks);
63 41
 
64
-	return currticks;
42
+	return clocks / clocks_per_usec;
65 43
 }
66 44
 
67 45
 static int rdtsc_ts_init(void)
@@ -71,10 +49,10 @@ static int rdtsc_ts_init(void)
71 49
 
72 50
 	get_cpuinfo(&cpu_info);
73 51
 	if (cpu_info.features & X86_FEATURE_TSC) {
74
-		clocks_per_second = calibrate_tsc();
75
-		if (clocks_per_second) {
52
+		clocks_per_usec= calibrate_tsc();
53
+		if (clocks_per_usec) {
76 54
 			DBG("RDTSC ticksource installed. CPU running at %ld Mhz\n",
77
-				clocks_per_second/(1000*1000));
55
+				clocks_per_usec);
78 56
 			return 0;
79 57
 		}
80 58
 	}

Loading…
취소
저장