bye, Ilan Justin Schoeman wrote:
Ilan Finci wrote:Thanks,I've looked at the code of do_div on PPC, and it uses % and /. Will it still work?Also, I tried to use do_div on i386 (kernel 2.4.18), and I get wrong answer. Attached is a small test program, where do_div is the version from the i386 sources, and do_div1 is the version from PPC sources.The first one give wrong answer, while the second one works fine. What am I missing? Will the code in v4l2 that uses do_div works on Intel platforms?Thanks, Ilan Gerd Knorr wrote:/lib/modules/2.4.16/kernel/drivers/media/video/videodevX.o: unresolved symbol __udivdi3 /lib/modules/2.4.16/kernel/drivers/media/video/videodevX.o: unresolved symbol __umoddi3libgcc functions for 64bit math, which are not present in the kernel because it isn't linked against libgcc.I see in videodevX.c that the function v4l2_math_div6432(...) I see that for intel cpus, there is an assembly code, and for others, a use of the '/' and '%', can this be the problem?Yes. The modules in http://bytesex.org/patches/12_v4l2-2.4.19-pre2.diff.gz have this fixed, they use the kernel functions for 64bit division. GerdAttached is a completely untested patch (well, it does build...) for videodevX, that adds Gerd's math routines. Please give it a try, and let me know if it works.-justin ------------------------------------------------------------------------ diff -urN videodevX/videodev.h videodevX-newdiv/videodev.h --- videodevX/videodev.h Thu Jun 14 07:45:23 2001 +++ videodevX-newdiv/videodev.h Thu Mar 14 10:58:56 2002 @@ -879,9 +879,6 @@ extern void *v4l2_q_yank_node(struct v4l2_queue *q, struct v4l2_q_node *node); extern int v4l2_q_last(struct v4l2_queue *q);-/* Math functions */-extern u32 v4l2_math_div6432(u64 a, u32 d, u32 *r); - /* Time functions */ extern unsigned long v4l2_timestamp_divide(stamp_t t, unsigned long p_100ns); diff -urN videodevX/videodevX.c videodevX-newdiv/videodevX.c --- videodevX/videodevX.c Thu Jun 14 07:45:23 2001 +++ videodevX-newdiv/videodevX.c Thu Mar 14 11:03:42 2002 @@ -42,19 +42,18 @@ * 2.4 devfs support ported from 2.4 kernels by * Dan Merillat <dan@xxxxxxxxxxxx> * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman) + * Arch independant division hacked for Gerd Knor's v4l2 patch */#ifndef __KERNEL__#define __KERNEL__ #endif-#include <linux/config.h> #ifndef EXPORT_SYMTAB #define EXPORT_SYMTAB #endif-#include <linux/version.h> #include <linux/module.h> #include <linux/types.h> @@ -66,13 +65,13 @@ #include <linux/errno.h> #include "videodev.h"-#if LINUX_VERSION_CODE >= 0x020100 #include <asm/uaccess.h> #endif #include <asm/system.h> #include <asm/pgtable.h> #include <asm/io.h> +#include <asm/div64.h>#ifdef CONFIG_KMOD#include <linux/kmod.h> @@ -1132,7 +1131,7 @@ int count, int *eof, void *data) { int len = 0; - struct videodev_proc_data *d; + struct videodev_proc_data *d = NULL; struct list_head *tmp;list_for_each (tmp, &videodev_proc_list) {@@ -1765,41 +1764,15 @@ * Math functions */-u32-v4l2_math_div6432(u64 a, u32 d, u32 *r) -{ - u32 q, m; -#ifdef __i386__ -/* Danger: This function will fault if the quotient exceeds (1<<32) - 1 */ - __asm__ __volatile__ ( - " movl %2,%%eax\n" - " movl %3,%%edx\n" - " divl %4\n" - " movl %%eax,%0\n" - " movl %%edx,%1\n" - : "=g" (q), "=g" (m) - : "g" ((u32)a), "g" ((u32)(a >> 32)), "g" (d) - : "eax", "edx" - ); -#else - q = a / d; - m = a % d; -#endif - if (r) *r = m; - return q; -} - unsigned long v4l2_timestamp_divide(stamp_t t, unsigned long p_100ns) { - /* Note: 't' is in 1ns units, 'p_100ns' is in 100ns units, */ - /* and the quotient is rounded */ - u64 p; - - p = (u64)p_100ns * 100; /* 1ns units */ - t >>= 6; /* /64 to allow p_100ns longer than 4 secs. */ - p >>= 6; /* to keep quotient the same */ - return v4l2_math_div6432((u64)t + (p >> 1), (u32)p, NULL); + u32 p; + + p = ((u64)p_100ns * 100) >> 6; + t = (t >> 6) + (p >> 1); + do_div(t,p); + return t; }/* Force the timestamp to be an integer multiple of p_100ns */@@ -1877,13 +1850,16 @@ unsigned long v4l2_video_std_tpf(struct v4l2_standard *vs) { - return v4l2_math_div6432( - (u64)vs->framerate.numerator * 10000000 - + vs->framerate.denominator / 2, - vs->framerate.denominator, - NULL); + u64 a; + u32 b; + + a = (u64)vs->framerate.numerator * 10000000 + vs->framerate.denominator / 2; + b = vs->framerate.denominator; + do_div(a,b); + return a; }+/* Used only in v4l2_video_std_confirm() */ static void catc1p2e6(__u8 *s, char c, int n) @@ -2139,7 +2115,6 @@ EXPORT_SYMBOL(v4l2_q_peek_tail); EXPORT_SYMBOL(v4l2_q_yank_node); EXPORT_SYMBOL(v4l2_q_last); -EXPORT_SYMBOL(v4l2_math_div6432); EXPORT_SYMBOL(v4l2_timestamp_divide); EXPORT_SYMBOL(v4l2_timestamp_correct); EXPORT_SYMBOL(v4l2_masterclock_register);
-- Ilan Finci Engineering Manager Advanced Technology Development MobilEye Vision Technologies Ltd 24 Mishol Hadkalim st. Jerusalem, 97278, Israel Tel: 972-2-5866989 ext. 105 Fax: 972-2-5867720 E-Fax: 1-801-912-3251 Email: mailto:Ilan.Finci@xxxxxxxxxxxx http://www.mobileye.com
# This is a BitKeeper generated patch for the following project: # Project Name: Video4Linux Two integration to the ACP4 # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # drivers/videodevX/videodevX.c 1.1 -> 1.4 # drivers/videodevX/videodev.h 1.1 -> 1.2 diff -Nru a/drivers/videodevX/videodev.h b/drivers/videodevX/videodev.h --- a/drivers/videodevX/videodev.h Thu Mar 14 11:44:28 2002 +++ b/drivers/videodevX/videodev.h Thu Mar 14 11:44:28 2002 @@ -886,9 +886,6 @@ extern void *v4l2_q_yank_node(struct v4l2_queue *q, struct v4l2_q_node *node); extern int v4l2_q_last(struct v4l2_queue *q); -/* Math functions */ -extern u32 v4l2_math_div6432(u64 a, u32 d, u32 *r); - /* Time functions */ extern unsigned long v4l2_timestamp_divide(stamp_t t, unsigned long p_100ns); diff -Nru a/drivers/videodevX/videodevX.c b/drivers/videodevX/videodevX.c --- a/drivers/videodevX/videodevX.c Thu Mar 14 11:44:28 2002 +++ b/drivers/videodevX/videodevX.c Thu Mar 14 11:44:28 2002 @@ -42,19 +42,18 @@ * 2.4 devfs support ported from 2.4 kernels by * Dan Merillat <dan@xxxxxxxxxxxx> * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman) + * Arch independant division hacked for Gerd Knor's v4l2 patch */ #ifndef __KERNEL__ #define __KERNEL__ #endif - #include <linux/config.h> #ifndef EXPORT_SYMTAB #define EXPORT_SYMTAB #endif - #include <linux/version.h> #include <linux/module.h> #include <linux/types.h> @@ -66,13 +65,13 @@ #include <linux/errno.h> #include "videodev.h" - #if LINUX_VERSION_CODE >= 0x020100 #include <asm/uaccess.h> #endif #include <asm/system.h> #include <asm/pgtable.h> #include <asm/io.h> +#include <asm/div64.h> #ifdef CONFIG_KMOD #include <linux/kmod.h> @@ -1155,7 +1154,7 @@ int count, int *eof, void *data) { int len = 0; - struct videodev_proc_data *d = 0; + struct videodev_proc_data *d = NULL; struct list_head *tmp; list_for_each (tmp, &videodev_proc_list) { @@ -1791,41 +1790,15 @@ * Math functions */ -u32 -v4l2_math_div6432(u64 a, u32 d, u32 *r) -{ - u32 q, m; -#ifdef __i386__ -/* Danger: This function will fault if the quotient exceeds (1<<32) - 1 */ - __asm__ __volatile__ ( - " movl %2,%%eax\n" - " movl %3,%%edx\n" - " divl %4\n" - " movl %%eax,%0\n" - " movl %%edx,%1\n" - : "=g" (q), "=g" (m) - : "g" ((u32)a), "g" ((u32)(a >> 32)), "g" (d) - : "eax", "edx" - ); -#else - q = a / d; - m = a % d; -#endif - if (r) *r = m; - return q; -} - unsigned long v4l2_timestamp_divide(stamp_t t, unsigned long p_100ns) { - /* Note: 't' is in 1ns units, 'p_100ns' is in 100ns units, */ - /* and the quotient is rounded */ - u64 p; - - p = (u64)p_100ns * 100; /* 1ns units */ - t >>= 6; /* /64 to allow p_100ns longer than 4 secs. */ - p >>= 6; /* to keep quotient the same */ - return v4l2_math_div6432((u64)t + (p >> 1), (u32)p, NULL); + u32 p; + + p = ((u64)p_100ns * 100) >> 6; + t = (t >> 6) + (p >> 1); + do_div(t,p); + return t; } /* Force the timestamp to be an integer multiple of p_100ns */ @@ -1903,13 +1876,16 @@ unsigned long v4l2_video_std_tpf(struct v4l2_standard *vs) { - return v4l2_math_div6432( - (u64)vs->framerate.numerator * 10000000 - + vs->framerate.denominator / 2, - vs->framerate.denominator, - NULL); + u64 a; + u32 b; + + a = (u64)vs->framerate.numerator * 10000000 + vs->framerate.denominator / 2; + b = vs->framerate.denominator; + do_div(a,b); + return a; } + /* Used only in v4l2_video_std_confirm() */ static void catc1p2e6(__u8 *s, char c, int n) @@ -2165,7 +2141,6 @@ EXPORT_SYMBOL(v4l2_q_peek_tail); EXPORT_SYMBOL(v4l2_q_yank_node); EXPORT_SYMBOL(v4l2_q_last); -EXPORT_SYMBOL(v4l2_math_div6432); EXPORT_SYMBOL(v4l2_timestamp_divide); EXPORT_SYMBOL(v4l2_timestamp_correct); EXPORT_SYMBOL(v4l2_masterclock_register);
<<attachment: smime.p7s>>