Просмотр исходного кода

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 17 лет назад
Родитель
Сommit
8de54ef9aa
1 измененных файлов: 21 добавлений и 43 удалений
  1. 21
    43
      src/arch/i386/drivers/timer_rdtsc.c

+ 21
- 43
src/arch/i386/drivers/timer_rdtsc.c Просмотреть файл

14
 #define rdtscll(val) \
14
 #define rdtscll(val) \
15
      __asm__ __volatile__ ("rdtsc" : "=A" (val))
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
 static tick_t rdtsc_currticks(void)
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
 	/* Read the Time Stamp Counter */
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
 static int rdtsc_ts_init(void)
45
 static int rdtsc_ts_init(void)
71
 
49
 
72
 	get_cpuinfo(&cpu_info);
50
 	get_cpuinfo(&cpu_info);
73
 	if (cpu_info.features & X86_FEATURE_TSC) {
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
 			DBG("RDTSC ticksource installed. CPU running at %ld Mhz\n",
54
 			DBG("RDTSC ticksource installed. CPU running at %ld Mhz\n",
77
-				clocks_per_second/(1000*1000));
55
+				clocks_per_usec);
78
 			return 0;
56
 			return 0;
79
 		}
57
 		}
80
 	}
58
 	}

Загрузка…
Отмена
Сохранить