[PARPORT] Patch[2.4.0pre3t2]: Parport TSC Timings

From: Gunther Mayer (gunther.mayer@braunschweig.okersurf.de)
Date: Sun Jul 02 2000 - 09:42:37 EDT

  • Next message: Tim Waugh: "Re: [PARPORT] Patch[2.4.0pre3t2]: Parport TSC Timings"

    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