Re: Re: using videodevX under PPC computer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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 __umoddi3



libgcc 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.

  Gerd


Attached 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);

[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux