Messages in this thread |  | | Date | Tue, 14 May 1996 16:58:19 -0400 | From | Robert L Krawitz <> | Subject | Bit flipping problems solved (for me) + performance INCREASE! |
| |
Gerard Roudier sent me a program to change the memory clocking on my motherboard (Plato) from x-4-4-4 to x-3-3-3. Having new 60 ns DRAM, and figuring that I'd at least see if I had problems, I tried changing it. Not only did I get a noticeable performance boost, but problems I've had for a while copying large trees around completely went away. Evidently the slow timing was occasionally screwing something up.
Other people having problems on Neptune-based motherboards might want to give this a try.
/* * compiling: [g]cc setpci.c -o setpci * for SVR4 (not Solaris), UnixWare use: * [g]cc -DSVR4 scanpci.c -o setpci * for DOS, watcom 9.5: * wcc386p -zq -omaxet -7 -4s -s -w3 -d2 name.c * and link with PharLap or other dos extender for exe * */
#if defined(__SVR4) #if !defined(SVR4) #define SVR4 #endif #endif
#include <stdio.h> #include <sys/types.h> #if defined(SVR4) #if defined(sun) #define __EXTENSIONS__ #endif #include <sys/proc.h> #include <sys/tss.h> #if defined(NCR) #define __STDC #include <sys/sysi86.h> #undef __STDC #else #include <sys/sysi86.h> #endif #if defined(__SUNPRO_C) || defined(sun) || defined(__sun) #include <sys/psw.h> #else #include <sys/seg.h> #endif #include <sys/v86.h> #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__386BSD__) #include <sys/file.h> #include <machine/console.h> #define GCCUSESGAS #endif #if defined(__bsdi__) #include <sys/file.h> #include <sys/ioctl.h> #include <i386/isa/pcconsioctl.h> #define GCCUSESGAS #endif #if defined(SCO) #include <sys/console.h> #include <sys/param.h> #include <sys/immu.h> #include <sys/region.h> #include <sys/proc.h> #include <sys/tss.h> #include <sys/sysi86.h> #include <sys/v86.h> #endif #if defined(Lynx_22) #define GCCUSESGAS #endif
#if defined(__WATCOMC__)
#include <stdlib.h> void outl(unsigned port, unsigned data); #pragma aux outl = "out dx, eax" parm [dx] [eax]; void outb(unsigned port, unsigned data); #pragma aux outb = "out dx, al" parm [dx] [eax]; unsigned inl(unsigned port); #pragma aux inl = "in eax, dx" parm [dx]; unsigned inb(unsigned port); #pragma aux inb = "xor eax,eax" "in al, dx" parm [dx];
#else /* __WATCOMC__ */
#if defined(__GNUC__)
#if defined(GCCUSESGAS) #define OUTB_GCC "outb %0,%1" #define OUTL_GCC "outl %0,%1" #define INB_GCC "inb %1,%0" #define INL_GCC "inl %1,%0" #else #define OUTB_GCC "out%B0 (%1)" #define OUTL_GCC "out%L0 (%1)" #define INB_GCC "in%B0 (%1)" #define INL_GCC "in%L0 (%1)" #endif /* GCCUSESGAS */
static void outb(unsigned short port, unsigned char val) { __asm__ __volatile__(OUTB_GCC : :"a" (val), "d" (port)); } static void outl(unsigned short port, unsigned long val) { __asm__ __volatile__(OUTL_GCC : :"a" (val), "d" (port)); } static unsigned char inb(unsigned short port) { unsigned char ret; __asm__ __volatile__(INB_GCC : "=a" (ret) : "d" (port)); return ret; } static unsigned long inl(unsigned short port) { unsigned long ret; __asm__ __volatile__(INL_GCC : "=a" (ret) : "d" (port)); return ret; }
#else /* __GNUC__ */
#if defined(__STDC__) && (__STDC__ == 1) # if !defined(NCR) # define asm __asm # endif #endif
#if defined(__SUNPRO_C) /* * This section is a gross hack in if you tell anyone that I wrote it, * I'll deny it. :-) * The leave/ret instructions are the big hack to leave %eax alone on return. */ unsigned char inb(int port) { asm(" movl 8(%esp),%edx"); asm(" subl %eax,%eax"); asm(" inb (%dx)"); asm(" leave"); asm(" ret"); }
unsigned short inw(int port) { asm(" movl 8(%esp),%edx"); asm(" subl %eax,%eax"); asm(" inw (%dx)"); asm(" leave"); asm(" ret"); }
unsigned long inl(int port) { asm(" movl 8(%esp),%edx"); asm(" inl (%dx)"); asm(" leave"); asm(" ret"); }
void outb(int port, unsigned char value) { asm(" movl 8(%esp),%edx"); asm(" movl 12(%esp),%eax"); asm(" outb (%dx)"); }
void outw(int port, unsigned short value) { asm(" movl 8(%esp),%edx"); asm(" movl 12(%esp),%eax"); asm(" outw (%dx)"); }
void outl(int port, unsigned long value) { asm(" movl 8(%esp),%edx"); asm(" movl 12(%esp),%eax"); asm(" outl (%dx)"); } #else
#if defined(SVR4) # if !defined(__USLC__) # define __USLC__ # endif #endif
#include <sys/inline.h>
#endif /* SUNPRO_C */
#endif /* __GNUC__ */ #endif /* __WATCOMC__ */
void enable_os_io(); void disable_os_io();
#define M_EQ 0 /* mask and return true if equal */ #define M_NE 1 /* mask and return true if not equal */ #define TRUE 2 /* don't read config, always true */
struct condmsg { unsigned char port; unsigned char mask; unsigned char value; char flags; char *text; };
static const struct condmsg set82434lx[] = { { 0x00, 0x00, 0x00, TRUE, " memory clocks=" }, { 0x57, 0xc0, 0xc0, M_EQ, "X-3-3-3 (50ns)" }, { 0x58, 0x01, 0x00, M_EQ, ", no CAS-wait" }, { 0x53, 0x08, 0x08, M_EQ, ", read around write"}, /* { 0x57, 0xc0, 0x40, M_EQ, "X-4-4-4/X-3-3-3 (60ns)" }, */ { 0x00, 0x00, 0x00, TRUE, "\n" }, /* end marker */ { 0 } };
static const struct condmsg conf82434lx[] = { { 0x00, 0x00, 0x00, TRUE, "\tCPU: " }, { 0x50, 0xe3, 0x82, M_EQ, "Pentium, 60MHz" }, { 0x50, 0xe3, 0x83, M_EQ, "Pentium, 66MHz" }, { 0x50, 0xe3, 0xa2, M_EQ, "Pentium, 90MHz" }, { 0x50, 0xe3, 0xa3, M_EQ, "Pentium, 100MHz" }, { 0x50, 0xc2, 0x82, M_NE, "(unknown)" }, { 0x50, 0x04, 0x00, M_EQ, " (primary cache OFF)" },
{ 0x53, 0x01, 0x01, TRUE, ", CPU->Memory posting "}, { 0x53, 0x01, 0x01, M_NE, "OFF" }, { 0x53, 0x01, 0x01, M_EQ, "ON" },
{ 0x53, 0x08, 0x00, M_NE, ", read around write"},
{ 0x70, 0x04, 0x00, M_EQ, "\n\tWarning: Cache parity disabled!" }, { 0x57, 0x20, 0x00, M_NE, "\n\tWarning: DRAM parity mask!" }, { 0x57, 0x01, 0x00, M_EQ, "\n\tWarning: refresh OFF! " },
{ 0x00, 0x00, 0x00, TRUE, "\n\tCache: " }, { 0x52, 0x01, 0x00, M_EQ, "None" }, { 0x52, 0x81, 0x01, M_EQ, "" }, { 0x52, 0xc1, 0x81, M_EQ, "256KB" }, { 0x52, 0xc1, 0xc1, M_EQ, "512KB" }, { 0x52, 0x03, 0x01, M_EQ, " writethrough" }, { 0x52, 0x03, 0x03, M_EQ, " writeback" },
{ 0x52, 0x01, 0x01, M_EQ, ", cache clocks=" }, { 0x52, 0x21, 0x01, M_EQ, "3-2-2-2/4-2-2-2" }, { 0x52, 0x21, 0x21, M_EQ, "3-1-1-1" },
{ 0x52, 0x01, 0x01, M_EQ, "\n\tCache flags: " }, { 0x52, 0x11, 0x11, M_EQ, " cache-all" }, { 0x52, 0x09, 0x09, M_EQ, " byte-control" }, { 0x52, 0x05, 0x05, M_EQ, " powersaver" },
{ 0x00, 0x00, 0x00, TRUE, "\n\tDRAM:" }, { 0x57, 0x10, 0x00, M_EQ, " page mode" },
{ 0x00, 0x00, 0x00, TRUE, " memory clocks=" }, { 0x57, 0xc0, 0x00, M_EQ, "X-4-4-4 (70ns)" }, { 0x57, 0xc0, 0x40, M_EQ, "X-4-4-4/X-3-3-3 (60ns)" }, { 0x57, 0xc0, 0x80, M_EQ, "???" }, { 0x57, 0xc0, 0xc0, M_EQ, "X-3-3-3 (50ns)" }, { 0x58, 0x02, 0x02, M_EQ, ", RAS-wait" }, { 0x58, 0x01, 0x01, M_EQ, ", CAS-wait" },
{ 0x00, 0x00, 0x00, TRUE, "\n\tCPU->PCI: posting " }, { 0x53, 0x02, 0x02, M_EQ, "ON" }, { 0x53, 0x02, 0x00, M_EQ, "OFF" }, { 0x00, 0x00, 0x00, TRUE, ", burst mode " }, { 0x54, 0x02, 0x00, M_NE, "ON" }, { 0x54, 0x02, 0x00, M_EQ, "OFF" }, { 0x54, 0x04, 0x00, TRUE, ", PCI clocks=" }, { 0x54, 0x04, 0x00, M_EQ, "2-2-2-2" }, { 0x54, 0x04, 0x00, M_NE, "2-1-1-1" }, { 0x00, 0x00, 0x00, TRUE, "\n\tPCI->Memory: posting " }, { 0x54, 0x01, 0x00, M_NE, "ON" }, { 0x54, 0x01, 0x00, M_EQ, "OFF" },
{ 0x57, 0x01, 0x01, M_EQ, "\n\tRefresh:" }, { 0x57, 0x03, 0x03, M_EQ, " CAS#/RAS#(Hidden)" }, { 0x57, 0x03, 0x01, M_EQ, " RAS#Only" }, { 0x57, 0x05, 0x05, M_EQ, " BurstOf4" },
{ 0x00, 0x00, 0x00, TRUE, "\n" },
/* end marker */ { 0 } };
static char confread (int dev_num, int port) { unsigned long portw = port & ~3; unsigned long ports = (port - portw) << 3;
unsigned long l = inl(0xC000 + portw); return (l >> ports); }
static void confwrite (int dev_num, int port, unsigned char value) { unsigned long portw = port & ~3; unsigned long ports = (port - portw) << 3;
unsigned long l = inl(0xC000 + portw);
l &= (~(0xff << ports)); l |= (value << ports);
#if 1 outl(0xC000 + portw, l); #endif }
static void setconfig (int dev_num, const struct condmsg *tbl) { while (tbl->text) { int cond = 0; if (tbl->flags == TRUE) { cond = 1; } else { unsigned char v = (unsigned char) confread(dev_num, tbl->port); v &= (~tbl->mask); v |= tbl->value; confwrite(dev_num, tbl->port, v); cond = 1; } if (cond) printf ("%s", tbl->text); tbl++; } }
static void showconfig (int dev_num, const struct condmsg *tbl) { while (tbl->text) { int cond = 0; if (tbl->flags == TRUE) { cond = 1; } else { unsigned char v = (unsigned char) confread(dev_num, tbl->port); switch (tbl->flags) { case M_EQ: if ((v & tbl->mask) == tbl->value) cond = 1; break; case M_NE: if ((v & tbl->mask) != tbl->value) cond = 1; break; } } if (cond) printf ("%s", tbl->text); tbl++; } }
main(int argc, unsigned char *argv[]) { unsigned long config_cmd;
if (argc != 1) { printf("Usage: %s\n"); exit(1); } #if !defined(MSDOS) if (getuid()) { printf("This program must be run as root\n"); exit(1); } #endif
enable_os_io();
outb(0xCF8, 0xF1); outb(0xCFA, 0x00); /* bus 0 for now */
setconfig(0, set82434lx); showconfig(0, conf82434lx);
outb(0xCF8, 0x00);
disable_os_io(); }
static int io_fd;
void enable_os_io() { #if defined(SVR4) || defined(SCO) #if defined(SI86IOPL) sysi86(SI86IOPL, 3); #else sysi86(SI86V86, V86SC_IOPL, PS_IOPL); #endif #endif #if defined(linux) iopl(3); #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__386BSD__) || defined(__bsdi__) if ((io_fd = open("/dev/console", O_RDWR, 0)) < 0) { perror("/dev/console"); exit(1); } #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__386BSD__) if (ioctl(io_fd, KDENABIO, 0) < 0) { perror("ioctl(KDENABIO)"); exit(1); } #endif #if defined(__bsdi__) if (ioctl(io_fd, PCCONENABIOPL, 0) < 0) { perror("ioctl(PCCONENABIOPL)"); exit(1); } #endif #endif #if defined(MACH386) if ((io_fd = open("/dev/iopl", O_RDWR, 0)) < 0) { perror("/dev/iopl"); exit(1); } #endif }
void disable_os_io() { #if defined(SVR4) || defined(SCO) #if defined(SI86IOPL) sysi86(SI86IOPL, 0); #else sysi86(SI86V86, V86SC_IOPL, 0); #endif #endif #if defined(linux) iopl(0); #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__386BSD__) if (ioctl(io_fd, KDDISABIO, 0) < 0) { perror("ioctl(KDDISABIO)"); close(io_fd); exit(1); } close(io_fd); #endif #if defined(__bsdi__) if (ioctl(io_fd, PCCONDISABIOPL, 0) < 0) { perror("ioctl(PCCONDISABIOPL)"); close(io_fd); exit(1); } close(io_fd); #endif #if defined(MACH386) close(io_fd); #endif }
|  |