diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas-rtc.c | 105 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso32/datapage.S | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso32/gettimeofday.S | 12 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso64/datapage.S | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso64/gettimeofday.S | 31 |
9 files changed, 146 insertions, 21 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 9a74b7ab03a4..046b4bf1f21e 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -25,7 +25,7 @@ obj-$(CONFIG_PPC_OF) += of_device.o | |||
25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o |
26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
27 | rtaspci-$(CONFIG_PPC64) := rtas_pci.o | 27 | rtaspci-$(CONFIG_PPC64) := rtas_pci.o |
28 | obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y) | 28 | obj-$(CONFIG_PPC_RTAS) += rtas.o rtas-rtc.o $(rtaspci-y) |
29 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 29 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o |
30 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o | 30 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o |
31 | obj-$(CONFIG_LPARCFG) += lparcfg.o | 31 | obj-$(CONFIG_LPARCFG) += lparcfg.o |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 4550eb4f4fbd..91538d2445bf 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -270,13 +270,15 @@ int main(void) | |||
270 | DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); | 270 | DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); |
271 | DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); | 271 | DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); |
272 | DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); | 272 | DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); |
273 | DEFINE(TSPC64_TV_SEC, offsetof(struct timespec, tv_sec)); | ||
274 | DEFINE(TSPC64_TV_NSEC, offsetof(struct timespec, tv_nsec)); | ||
273 | DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec)); | 275 | DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec)); |
274 | DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec)); | 276 | DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec)); |
275 | #else | 277 | #else |
276 | DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec)); | 278 | DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec)); |
277 | DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec)); | 279 | DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec)); |
278 | DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec)); | 280 | DEFINE(TSPC32_TV_SEC, offsetof(struct timespec, tv_sec)); |
279 | DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec)); | 281 | DEFINE(TSPC32_TV_NSEC, offsetof(struct timespec, tv_nsec)); |
280 | #endif | 282 | #endif |
281 | /* timeval/timezone offsets for use by vdso */ | 283 | /* timeval/timezone offsets for use by vdso */ |
282 | DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); | 284 | DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); |
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 5063c603fad4..8d60fa99fc4b 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -24,7 +24,7 @@ | |||
24 | * Copyright 2002-2004 MontaVista Software, Inc. | 24 | * Copyright 2002-2004 MontaVista Software, Inc. |
25 | * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> | 25 | * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> |
26 | * Copyright 2004 Freescale Semiconductor, Inc | 26 | * Copyright 2004 Freescale Semiconductor, Inc |
27 | * PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com> | 27 | * PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org> |
28 | * | 28 | * |
29 | * This program is free software; you can redistribute it and/or modify it | 29 | * This program is free software; you can redistribute it and/or modify it |
30 | * under the terms of the GNU General Public License as published by the | 30 | * under the terms of the GNU General Public License as published by the |
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c new file mode 100644 index 000000000000..7b948662704c --- /dev/null +++ b/arch/powerpc/kernel/rtas-rtc.c | |||
@@ -0,0 +1,105 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/time.h> | ||
3 | #include <linux/timer.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/rtc.h> | ||
6 | #include <linux/delay.h> | ||
7 | #include <asm/prom.h> | ||
8 | #include <asm/rtas.h> | ||
9 | #include <asm/time.h> | ||
10 | |||
11 | |||
12 | #define MAX_RTC_WAIT 5000 /* 5 sec */ | ||
13 | #define RTAS_CLOCK_BUSY (-2) | ||
14 | unsigned long __init rtas_get_boot_time(void) | ||
15 | { | ||
16 | int ret[8]; | ||
17 | int error, wait_time; | ||
18 | unsigned long max_wait_tb; | ||
19 | |||
20 | max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; | ||
21 | do { | ||
22 | error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); | ||
23 | if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { | ||
24 | wait_time = rtas_extended_busy_delay_time(error); | ||
25 | /* This is boot time so we spin. */ | ||
26 | udelay(wait_time*1000); | ||
27 | error = RTAS_CLOCK_BUSY; | ||
28 | } | ||
29 | } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); | ||
30 | |||
31 | if (error != 0 && printk_ratelimit()) { | ||
32 | printk(KERN_WARNING "error: reading the clock failed (%d)\n", | ||
33 | error); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]); | ||
38 | } | ||
39 | |||
40 | /* NOTE: get_rtc_time will get an error if executed in interrupt context | ||
41 | * and if a delay is needed to read the clock. In this case we just | ||
42 | * silently return without updating rtc_tm. | ||
43 | */ | ||
44 | void rtas_get_rtc_time(struct rtc_time *rtc_tm) | ||
45 | { | ||
46 | int ret[8]; | ||
47 | int error, wait_time; | ||
48 | unsigned long max_wait_tb; | ||
49 | |||
50 | max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; | ||
51 | do { | ||
52 | error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); | ||
53 | if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { | ||
54 | if (in_interrupt() && printk_ratelimit()) { | ||
55 | memset(&rtc_tm, 0, sizeof(struct rtc_time)); | ||
56 | printk(KERN_WARNING "error: reading clock" | ||
57 | " would delay interrupt\n"); | ||
58 | return; /* delay not allowed */ | ||
59 | } | ||
60 | wait_time = rtas_extended_busy_delay_time(error); | ||
61 | msleep(wait_time); | ||
62 | error = RTAS_CLOCK_BUSY; | ||
63 | } | ||
64 | } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); | ||
65 | |||
66 | if (error != 0 && printk_ratelimit()) { | ||
67 | printk(KERN_WARNING "error: reading the clock failed (%d)\n", | ||
68 | error); | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | rtc_tm->tm_sec = ret[5]; | ||
73 | rtc_tm->tm_min = ret[4]; | ||
74 | rtc_tm->tm_hour = ret[3]; | ||
75 | rtc_tm->tm_mday = ret[2]; | ||
76 | rtc_tm->tm_mon = ret[1] - 1; | ||
77 | rtc_tm->tm_year = ret[0] - 1900; | ||
78 | } | ||
79 | |||
80 | int rtas_set_rtc_time(struct rtc_time *tm) | ||
81 | { | ||
82 | int error, wait_time; | ||
83 | unsigned long max_wait_tb; | ||
84 | |||
85 | max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; | ||
86 | do { | ||
87 | error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, | ||
88 | tm->tm_year + 1900, tm->tm_mon + 1, | ||
89 | tm->tm_mday, tm->tm_hour, tm->tm_min, | ||
90 | tm->tm_sec, 0); | ||
91 | if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { | ||
92 | if (in_interrupt()) | ||
93 | return 1; /* probably decrementer */ | ||
94 | wait_time = rtas_extended_busy_delay_time(error); | ||
95 | msleep(wait_time); | ||
96 | error = RTAS_CLOCK_BUSY; | ||
97 | } | ||
98 | } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); | ||
99 | |||
100 | if (error != 0 && printk_ratelimit()) | ||
101 | printk(KERN_WARNING "error: setting the clock failed (%d)\n", | ||
102 | error); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index fdbd9f9122f2..608fee7c7e20 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <asm/firmware.h> | 59 | #include <asm/firmware.h> |
60 | #include <asm/xmon.h> | 60 | #include <asm/xmon.h> |
61 | #include <asm/udbg.h> | 61 | #include <asm/udbg.h> |
62 | #include <asm/kexec.h> | ||
62 | 63 | ||
63 | #include "setup.h" | 64 | #include "setup.h" |
64 | 65 | ||
@@ -415,6 +416,10 @@ void __init setup_system(void) | |||
415 | */ | 416 | */ |
416 | unflatten_device_tree(); | 417 | unflatten_device_tree(); |
417 | 418 | ||
419 | #ifdef CONFIG_KEXEC | ||
420 | kexec_setup(); /* requires unflattened device tree. */ | ||
421 | #endif | ||
422 | |||
418 | /* | 423 | /* |
419 | * Fill the ppc64_caches & systemcfg structures with informations | 424 | * Fill the ppc64_caches & systemcfg structures with informations |
420 | * retreived from the device-tree. Need to be called before | 425 | * retreived from the device-tree. Need to be called before |
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S index a08c26e87835..f6b38472318d 100644 --- a/arch/powerpc/kernel/vdso32/datapage.S +++ b/arch/powerpc/kernel/vdso32/datapage.S | |||
@@ -77,8 +77,9 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq) | |||
77 | mflr r12 | 77 | mflr r12 |
78 | .cfi_register lr,r12 | 78 | .cfi_register lr,r12 |
79 | bl __get_datapage@local | 79 | bl __get_datapage@local |
80 | lwz r3,CFG_TB_TICKS_PER_SEC(r3) | ||
81 | lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) | 80 | lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) |
81 | lwz r3,CFG_TB_TICKS_PER_SEC(r3) | ||
82 | mtlr r12 | 82 | mtlr r12 |
83 | blr | ||
83 | .cfi_endproc | 84 | .cfi_endproc |
84 | V_FUNCTION_END(__kernel_get_tbfreq) | 85 | V_FUNCTION_END(__kernel_get_tbfreq) |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index aeb5fc9b87b3..0a32a41d50b0 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
@@ -83,7 +83,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
83 | /* Check for supported clock IDs */ | 83 | /* Check for supported clock IDs */ |
84 | cmpli cr0,r3,CLOCK_REALTIME | 84 | cmpli cr0,r3,CLOCK_REALTIME |
85 | cmpli cr1,r3,CLOCK_MONOTONIC | 85 | cmpli cr1,r3,CLOCK_MONOTONIC |
86 | cror cr0,cr0,cr1 | 86 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
87 | bne cr0,99f | 87 | bne cr0,99f |
88 | 88 | ||
89 | mflr r12 /* r12 saves lr */ | 89 | mflr r12 /* r12 saves lr */ |
@@ -91,7 +91,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
91 | mr r10,r3 /* r10 saves id */ | 91 | mr r10,r3 /* r10 saves id */ |
92 | mr r11,r4 /* r11 saves tp */ | 92 | mr r11,r4 /* r11 saves tp */ |
93 | bl __get_datapage@local /* get data page */ | 93 | bl __get_datapage@local /* get data page */ |
94 | mr r9, r3 /* datapage ptr in r9 */ | 94 | mr r9,r3 /* datapage ptr in r9 */ |
95 | beq cr1,50f /* if monotonic -> jump there */ | 95 | beq cr1,50f /* if monotonic -> jump there */ |
96 | 96 | ||
97 | /* | 97 | /* |
@@ -173,10 +173,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
173 | add r4,r4,r7 | 173 | add r4,r4,r7 |
174 | lis r5,NSEC_PER_SEC@h | 174 | lis r5,NSEC_PER_SEC@h |
175 | ori r5,r5,NSEC_PER_SEC@l | 175 | ori r5,r5,NSEC_PER_SEC@l |
176 | cmpli cr0,r4,r5 | 176 | cmpl cr0,r4,r5 |
177 | cmpli cr1,r4,0 | ||
177 | blt 1f | 178 | blt 1f |
178 | subf r4,r5,r4 | 179 | subf r4,r5,r4 |
179 | addi r3,r3,1 | 180 | addi r3,r3,1 |
181 | 1: bge cr1,1f | ||
182 | addi r3,r3,-1 | ||
183 | add r4,r4,r5 | ||
180 | 1: stw r3,TSPC32_TV_SEC(r11) | 184 | 1: stw r3,TSPC32_TV_SEC(r11) |
181 | stw r4,TSPC32_TV_NSEC(r11) | 185 | stw r4,TSPC32_TV_NSEC(r11) |
182 | 186 | ||
@@ -210,7 +214,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) | |||
210 | /* Check for supported clock IDs */ | 214 | /* Check for supported clock IDs */ |
211 | cmpwi cr0,r3,CLOCK_REALTIME | 215 | cmpwi cr0,r3,CLOCK_REALTIME |
212 | cmpwi cr1,r3,CLOCK_MONOTONIC | 216 | cmpwi cr1,r3,CLOCK_MONOTONIC |
213 | cror cr0,cr0,cr1 | 217 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
214 | bne cr0,99f | 218 | bne cr0,99f |
215 | 219 | ||
216 | li r3,0 | 220 | li r3,0 |
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S index e67eda0f8cda..6393e4137bc7 100644 --- a/arch/powerpc/kernel/vdso64/datapage.S +++ b/arch/powerpc/kernel/vdso64/datapage.S | |||
@@ -80,5 +80,6 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq) | |||
80 | bl V_LOCAL_FUNC(__get_datapage) | 80 | bl V_LOCAL_FUNC(__get_datapage) |
81 | ld r3,CFG_TB_TICKS_PER_SEC(r3) | 81 | ld r3,CFG_TB_TICKS_PER_SEC(r3) |
82 | mtlr r12 | 82 | mtlr r12 |
83 | blr | ||
83 | .cfi_endproc | 84 | .cfi_endproc |
84 | V_FUNCTION_END(__kernel_get_tbfreq) | 85 | V_FUNCTION_END(__kernel_get_tbfreq) |
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index d371c02a8c0e..1a89094715cc 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
@@ -1,4 +1,5 @@ | |||
1 | /* | 1 | |
2 | /* | ||
2 | * Userland implementation of gettimeofday() for 64 bits processes in a | 3 | * Userland implementation of gettimeofday() for 64 bits processes in a |
3 | * ppc64 kernel for use in the vDSO | 4 | * ppc64 kernel for use in the vDSO |
4 | * | 5 | * |
@@ -68,7 +69,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
68 | /* Check for supported clock IDs */ | 69 | /* Check for supported clock IDs */ |
69 | cmpwi cr0,r3,CLOCK_REALTIME | 70 | cmpwi cr0,r3,CLOCK_REALTIME |
70 | cmpwi cr1,r3,CLOCK_MONOTONIC | 71 | cmpwi cr1,r3,CLOCK_MONOTONIC |
71 | cror cr0,cr0,cr1 | 72 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
72 | bne cr0,99f | 73 | bne cr0,99f |
73 | 74 | ||
74 | mflr r12 /* r12 saves lr */ | 75 | mflr r12 /* r12 saves lr */ |
@@ -84,16 +85,17 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
84 | 85 | ||
85 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | 86 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ |
86 | 87 | ||
87 | lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */ | 88 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ |
88 | ori r7,r7,0xca00 | 89 | ori r7,r7,16960 |
89 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | 90 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ |
90 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | 91 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ |
91 | std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ | 92 | std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ |
92 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | 93 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ |
93 | mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) / | 94 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / |
94 | * XSEC_PER_SEC | 95 | * XSEC_PER_SEC |
95 | */ | 96 | */ |
96 | rldicl r0,r0,44,20 | 97 | rldicl r0,r0,44,20 |
98 | mulli r0,r0,1000 /* nsec = usec * 1000 */ | ||
97 | std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ | 99 | std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ |
98 | 100 | ||
99 | mtlr r12 | 101 | mtlr r12 |
@@ -106,15 +108,16 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
106 | 108 | ||
107 | 50: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | 109 | 50: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ |
108 | 110 | ||
109 | lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */ | 111 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ |
110 | ori r7,r7,0xca00 | 112 | ori r7,r7,16960 |
111 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | 113 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ |
112 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | 114 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ |
113 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | 115 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ |
114 | mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) / | 116 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / |
115 | * XSEC_PER_SEC | 117 | * XSEC_PER_SEC |
116 | */ | 118 | */ |
117 | rldicl r6,r0,44,20 | 119 | rldicl r6,r0,44,20 |
120 | mulli r6,r6,1000 /* nsec = usec * 1000 */ | ||
118 | 121 | ||
119 | /* now we must fixup using wall to monotonic. We need to snapshot | 122 | /* now we must fixup using wall to monotonic. We need to snapshot |
120 | * that value and do the counter trick again. Fortunately, we still | 123 | * that value and do the counter trick again. Fortunately, we still |
@@ -123,8 +126,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
123 | * can be used | 126 | * can be used |
124 | */ | 127 | */ |
125 | 128 | ||
126 | lwz r4,WTOM_CLOCK_SEC(r9) | 129 | lwa r4,WTOM_CLOCK_SEC(r3) |
127 | lwz r7,WTOM_CLOCK_NSEC(r9) | 130 | lwa r7,WTOM_CLOCK_NSEC(r3) |
128 | 131 | ||
129 | /* We now have our result in r4,r7. We create a fake dependency | 132 | /* We now have our result in r4,r7. We create a fake dependency |
130 | * on that result and re-check the counter | 133 | * on that result and re-check the counter |
@@ -144,10 +147,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
144 | add r7,r7,r6 | 147 | add r7,r7,r6 |
145 | lis r9,NSEC_PER_SEC@h | 148 | lis r9,NSEC_PER_SEC@h |
146 | ori r9,r9,NSEC_PER_SEC@l | 149 | ori r9,r9,NSEC_PER_SEC@l |
147 | cmpli cr0,r7,r9 | 150 | cmpl cr0,r7,r9 |
151 | cmpli cr1,r7,0 | ||
148 | blt 1f | 152 | blt 1f |
149 | subf r7,r9,r7 | 153 | subf r7,r9,r7 |
150 | addi r4,r4,1 | 154 | addi r4,r4,1 |
155 | 1: bge cr1,1f | ||
156 | addi r4,r4,-1 | ||
157 | add r7,r7,r9 | ||
151 | 1: std r4,TSPC64_TV_SEC(r11) | 158 | 1: std r4,TSPC64_TV_SEC(r11) |
152 | std r7,TSPC64_TV_NSEC(r11) | 159 | std r7,TSPC64_TV_NSEC(r11) |
153 | 160 | ||
@@ -181,7 +188,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) | |||
181 | /* Check for supported clock IDs */ | 188 | /* Check for supported clock IDs */ |
182 | cmpwi cr0,r3,CLOCK_REALTIME | 189 | cmpwi cr0,r3,CLOCK_REALTIME |
183 | cmpwi cr1,r3,CLOCK_MONOTONIC | 190 | cmpwi cr1,r3,CLOCK_MONOTONIC |
184 | cror cr0,cr0,cr1 | 191 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
185 | bne cr0,99f | 192 | bne cr0,99f |
186 | 193 | ||
187 | li r3,0 | 194 | li r3,0 |