Hi,
this patch shows some register access times if TSC is available.
I think this is very useful to diagnose performance
and correctness problems (e.g. timing on PCI cards).
This proves:
My PCI cards take 500ns for inb/outb, whereas my mainboard device takes 1300ns.
My Mainboard P3B-F seems to have 4.33MHz ISA speed (750ns *8/4.33 ~ 1350),
anybody knows why this isn't 8 MHz ?
Please test and mail some results...
Regards, Gunther
example output:
------------
...
parport0: PC-style at 0x378 (0x778) [PCSPP,TRISTATE,EPP,ECP]
parport0: timing[ns] data r/w=1329/1316, status r/w=1306/1329, epp r/w=1306/1329 (rdtsc=42)
parport1: PC-style at 0xd000 (0xb800) [PCSPP,TRISTATE,ECP]
parport1: timing[ns] data r/w=506/540, status r/w=490/503, epp r/w=490/483 (rdtsc=33)
parport2: PC-style at 0xa478 [PCSPP,TRISTATE,EPP]
parport2: timing[ns] data r/w=547/422, status r/w=552/445, epp r/w=552/614 (rdtsc=32)
parport3: PC-style at 0xa578 [PCSPP,TRISTATE,EPP]
parport3: timing[ns] data r/w=569/422, status r/w=552/425, epp r/w=3098/445 (rdtsc=32)
diff -ur linux-240t3p2-orig/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- linux-240t3p2-orig/arch/i386/kernel/i386_ksyms.c Sun Jul 2 11:06:04 2000
+++ linux/arch/i386/kernel/i386_ksyms.c Sun Jul 2 14:57:26 2000
@@ -26,6 +26,7 @@
extern void dump_thread(struct pt_regs *, struct user *);
extern spinlock_t rtc_lock;
+extern unsigned long cpu_hz;
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
extern void machine_real_restart(unsigned char *, int);
@@ -65,6 +66,7 @@
EXPORT_SYMBOL(get_cmos_time);
EXPORT_SYMBOL(apm_bios_info);
EXPORT_SYMBOL(gdt);
+EXPORT_SYMBOL(cpu_hz);
EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
diff -ur linux-240t3p2-orig/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- linux-240t3p2-orig/drivers/parport/parport_pc.c Sun Jul 2 11:06:12 2000
+++ linux/drivers/parport/parport_pc.c Sun Jul 2 15:05:16 2000
@@ -60,6 +60,11 @@
#include <linux/parport_pc.h>
#include <asm/parport.h>
+#if defined (__i386__)
+#include <asm/msr.h>
+extern unsigned long cpu_hz;
+#endif
+
#define PARPORT_PC_MAX_PORTS PARPORT_MAX
/* ECR modes */
@@ -1966,6 +1971,43 @@
return p->dma;
}
+/* Use TSC to get accurate access times for the registers.
+ * This can help to provide better understanding in order
+ * to optimize this driver and let it work correctly for
+ * PCI cards...
+ */
+void port_timing(int b, int num)
+{
+#if defined (__i386__)
+ int l0,l1,l2,l3,l4,l5,l6,l7,d;
+ int b1=b+1, b3=b+3;
+
+ int f= cpu_hz/1000000;
+ if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
+ rdtscl(l0);
+ rdtscl(l1);
+ d=inb(b);
+ rdtscl(l2);
+ outb(d,b);
+ rdtscl(l3);
+ d=inb(b1);
+ rdtscl(l4);
+ outb(d,b1);
+ rdtscl(l5);
+ d=inb(b3);
+ rdtscl(l6);
+ outb(d,b3);
+ rdtscl(l7);
+ d=l1-l0;
+ printk("parport%d: timing[ns] data r/w=%d/%d, status r/w=%d/%d, epp r/w=%d/%d (rdtsc=%d)\n",
+ num, ((l2-l1-d)*1000)/f,((l3-l2-d)*1000)/f,((l4-l3-d)*1000)/f,
+ ((l5-l4-d)*1000)/f,((l6-l5-d)*1000)/f,((l7-l6-d)*1000)/f,l1-l0);
+ }
+#endif
+ return;
+}
+
+
/* --- Initialisation code -------------------------------- */
struct parport *__devinit parport_pc_probe_port (unsigned long int base,
@@ -2155,6 +2197,7 @@
/* Now that we've told the sharing engine about the port, and
found out its characteristics, let the high-level drivers
know about it. */
+ port_timing(p->base, p->portnum);
parport_announce_port (p);
return p;
-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --
This archive was generated by hypermail 2b29 : Sun Jul 02 2000 - 09:44:21 EDT