diff options
Diffstat (limited to 'arch/ppc64/kernel/vdso32/gettimeofday.S')
-rw-r--r-- | arch/ppc64/kernel/vdso32/gettimeofday.S | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/arch/ppc64/kernel/vdso32/gettimeofday.S b/arch/ppc64/kernel/vdso32/gettimeofday.S deleted file mode 100644 index e243c1d24af7..000000000000 --- a/arch/ppc64/kernel/vdso32/gettimeofday.S +++ /dev/null | |||
@@ -1,140 +0,0 @@ | |||
1 | /* | ||
2 | * Userland implementation of gettimeofday() for 32 bits processes in a | ||
3 | * ppc64 kernel for use in the vDSO | ||
4 | * | ||
5 | * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org), IBM Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | #include <linux/config.h> | ||
13 | #include <asm/processor.h> | ||
14 | #include <asm/ppc_asm.h> | ||
15 | #include <asm/vdso.h> | ||
16 | #include <asm/asm-offsets.h> | ||
17 | #include <asm/unistd.h> | ||
18 | |||
19 | .text | ||
20 | /* | ||
21 | * Exact prototype of gettimeofday | ||
22 | * | ||
23 | * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); | ||
24 | * | ||
25 | */ | ||
26 | V_FUNCTION_BEGIN(__kernel_gettimeofday) | ||
27 | .cfi_startproc | ||
28 | mflr r12 | ||
29 | .cfi_register lr,r12 | ||
30 | |||
31 | mr r10,r3 /* r10 saves tv */ | ||
32 | mr r11,r4 /* r11 saves tz */ | ||
33 | bl __get_datapage@local /* get data page */ | ||
34 | mr r9, r3 /* datapage ptr in r9 */ | ||
35 | bl __do_get_xsec@local /* get xsec from tb & kernel */ | ||
36 | bne- 2f /* out of line -> do syscall */ | ||
37 | |||
38 | /* seconds are xsec >> 20 */ | ||
39 | rlwinm r5,r4,12,20,31 | ||
40 | rlwimi r5,r3,12,0,19 | ||
41 | stw r5,TVAL32_TV_SEC(r10) | ||
42 | |||
43 | /* get remaining xsec and convert to usec. we scale | ||
44 | * up remaining xsec by 12 bits and get the top 32 bits | ||
45 | * of the multiplication | ||
46 | */ | ||
47 | rlwinm r5,r4,12,0,19 | ||
48 | lis r6,1000000@h | ||
49 | ori r6,r6,1000000@l | ||
50 | mulhwu r5,r5,r6 | ||
51 | stw r5,TVAL32_TV_USEC(r10) | ||
52 | |||
53 | cmpli cr0,r11,0 /* check if tz is NULL */ | ||
54 | beq 1f | ||
55 | lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */ | ||
56 | lwz r5,CFG_TZ_DSTTIME(r9) | ||
57 | stw r4,TZONE_TZ_MINWEST(r11) | ||
58 | stw r5,TZONE_TZ_DSTTIME(r11) | ||
59 | |||
60 | 1: mtlr r12 | ||
61 | li r3,0 | ||
62 | blr | ||
63 | |||
64 | 2: mr r3,r10 | ||
65 | mr r4,r11 | ||
66 | li r0,__NR_gettimeofday | ||
67 | sc | ||
68 | b 1b | ||
69 | .cfi_endproc | ||
70 | V_FUNCTION_END(__kernel_gettimeofday) | ||
71 | |||
72 | /* | ||
73 | * This is the core of gettimeofday(), it returns the xsec | ||
74 | * value in r3 & r4 and expects the datapage ptr (non clobbered) | ||
75 | * in r9. clobbers r0,r4,r5,r6,r7,r8 | ||
76 | */ | ||
77 | __do_get_xsec: | ||
78 | .cfi_startproc | ||
79 | /* Check for update count & load values. We use the low | ||
80 | * order 32 bits of the update count | ||
81 | */ | ||
82 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
83 | andi. r0,r8,1 /* pending update ? loop */ | ||
84 | bne- 1b | ||
85 | xor r0,r8,r8 /* create dependency */ | ||
86 | add r9,r9,r0 | ||
87 | |||
88 | /* Load orig stamp (offset to TB) */ | ||
89 | lwz r5,CFG_TB_ORIG_STAMP(r9) | ||
90 | lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) | ||
91 | |||
92 | /* Get a stable TB value */ | ||
93 | 2: mftbu r3 | ||
94 | mftbl r4 | ||
95 | mftbu r0 | ||
96 | cmpl cr0,r3,r0 | ||
97 | bne- 2b | ||
98 | |||
99 | /* Substract tb orig stamp. If the high part is non-zero, we jump to the | ||
100 | * slow path which call the syscall. If it's ok, then we have our 32 bits | ||
101 | * tb_ticks value in r7 | ||
102 | */ | ||
103 | subfc r7,r6,r4 | ||
104 | subfe. r0,r5,r3 | ||
105 | bne- 3f | ||
106 | |||
107 | /* Load scale factor & do multiplication */ | ||
108 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ | ||
109 | lwz r6,(CFG_TB_TO_XS+4)(r9) | ||
110 | mulhwu r4,r7,r5 | ||
111 | mulhwu r6,r7,r6 | ||
112 | mullw r0,r7,r5 | ||
113 | addc r6,r6,r0 | ||
114 | |||
115 | /* At this point, we have the scaled xsec value in r4 + XER:CA | ||
116 | * we load & add the stamp since epoch | ||
117 | */ | ||
118 | lwz r5,CFG_STAMP_XSEC(r9) | ||
119 | lwz r6,(CFG_STAMP_XSEC+4)(r9) | ||
120 | adde r4,r4,r6 | ||
121 | addze r3,r5 | ||
122 | |||
123 | /* We now have our result in r3,r4. We create a fake dependency | ||
124 | * on that result and re-check the counter | ||
125 | */ | ||
126 | xor r0,r4,r4 | ||
127 | add r9,r9,r0 | ||
128 | lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
129 | cmpl cr0,r8,r0 /* check if updated */ | ||
130 | bne- 1b | ||
131 | |||
132 | /* Warning ! The caller expects CR:EQ to be set to indicate a | ||
133 | * successful calculation (so it won't fallback to the syscall | ||
134 | * method). We have overriden that CR bit in the counter check, | ||
135 | * but fortunately, the loop exit condition _is_ CR:EQ set, so | ||
136 | * we can exit safely here. If you change this code, be careful | ||
137 | * of that side effect. | ||
138 | */ | ||
139 | 3: blr | ||
140 | .cfi_endproc | ||