Hello. 1.- testgart and the glx module with AGP enabled show memory corruption errors. 2.- The AGP gart module loads under my laptop (K6-2 450Mhz, ALI M1541 chipset, 64Mb RAM). Syslog is showing the following data: Nov 3 19:31:20 localhost kernel: Linux agpgart interface v0.99 (c) Jeff Hartmann Nov 3 19:31:20 localhost kernel: agpgart: Maximum main memory to use for agp memory: 27M Nov 3 19:31:20 localhost kernel: agpgart: Detected Ali M1541 chipset Nov 3 19:31:20 localhost kernel: agpgart: AGP aperture is 64M @ 0xe0000000 Then, the glx module using AGP modes mach64_dma=3 or mach64_dma=4 shows corrupted textures, and even crashes the machine. Trying to isolate the problem, I test the program testgart (included with this mail), and it says: version: 0.99 bridge id: 0x154110b9 agp_mode: 0x1c000203 aper_base: 0xe0000000 aper_size: 64 pg_total: 6912 pg_system: 6912 pg_used: 0 entry.key : 0 entry.key : 1 Allocated 8 megs of GART memory MemoryBenchmark: 81 mb/s MemoryBenchmark: 82 mb/s MemoryBenchmark: 82 mb/s Average speed: 81 mb/s Testing data integrity (1st pass): failed on first pass! Testing data integrity (2nd pass): failed on second pass! At the same time, the syslog is dumping lines with this shape: Nov 5 18:19:50 localhost kernel: memory : c3998d60 Nov 5 18:19:50 localhost kernel: memory : c0e8fba0 The testgart doesn't fail all the time. But the kernel-memory lines shows in the syslog anyway. With the glx module, I've also seen this line into the syslog: Nov 3 19:31:20 localhost kernel: apm: get_event: Interface not connected And then, the machine is not able to power down on halt. It says "Power down" and nothing more. cat /proc/version Linux version 2.4.0-test10 (root@panoramix) (gcc version 2.95.2 20000220 (Debian GNU/Linux)) #2 Fri Nov 3 19:52:53 CET 2000 No Oops. The testgart that I've used is attatched in this mail. The output of the ver_linux script is: -- Versions installed: (if some fields are empty or look -- unusual then possibly you have very old versions) Linux panoramix 2.4.0-test10 #2 Fri Nov 3 19:52:53 CET 2000 i586 unknown Kernel modules 2.3.19 Gnu C 2.95.2 Gnu Make 3.79.1 Binutils 2.10.91 Linux C Library 2.1.96 Dynamic linker ldd (GNU libc) 2.1.96 Procps 2.0.6 Mount 2.10o Net-tools 2.05 Kbd 0.99 Sh-utils 2.0i Modules Loaded loop agpgart ppp_deflate bsd_comp ppp_async maestro soundcore ppp_generic serial_cs pcnet_cs 8390 ipt_MASQUERADE iptable_nat ip_conntrack ip_tables ds i82365 pcmcia_core nls_iso8859-1 nls_cp437 vfat fat The /proc/cpuinfo dumps: processor : 0 vendor_id : AuthenticAMD cpu family : 5 model : 8 model name : AMD-K6(tm) 3D processor stepping : 12 cpu MHz : 451.000040 cache size : 64 KB fdiv_bug : no hlt_bug : no sep_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr mce cx8 sep mtrr pge mmx 3dnow bogomips : 901.12 The /proc/modules dumps: loop 7392 0 (autoclean) agpgart 12752 0 (autoclean) ppp_deflate 39168 0 (autoclean) bsd_comp 4160 0 (autoclean) ppp_async 6224 1 (autoclean) maestro 25360 1 (autoclean) soundcore 3664 2 (autoclean) [maestro] ppp_generic 12704 3 (autoclean) [ppp_deflate bsd_comp ppp_async] serial_cs 5616 0 (unused) pcnet_cs 11200 1 8390 6112 0 [pcnet_cs] ipt_MASQUERADE 1296 1 (autoclean) iptable_nat 12224 0 [ipt_MASQUERADE] ip_conntrack 12384 1 [ipt_MASQUERADE iptable_nat] ip_tables 9888 4 [ipt_MASQUERADE iptable_nat] ds 6608 2 [serial_cs pcnet_cs] i82365 23216 2 pcmcia_core 43392 0 [serial_cs pcnet_cs ds i82365] nls_iso8859-1 2848 1 (autoclean) nls_cp437 4352 1 (autoclean) vfat 10320 1 fat 30080 0 [vfat] The /proc/ioports dumps: 0000-001f : dma1 0020-003f : pic1 0040-005f : timer 0060-006f : keyboard 0080-008f : dma page reg 00a0-00bf : pic2 00c0-00df : dma2 00f0-00ff : fpu 0170-017f : Acer Laboratories Inc. [ALi] M5229 IDE 0170-0177 : ide1 01f0-01ff : Acer Laboratories Inc. [ALi] M5229 IDE 01f0-01f7 : ide0 02f8-02ff : serial(set) 0300-031f : pcnet_cs 0376-0376 : Acer Laboratories Inc. [ALi] M5229 IDE 0376-0376 : ide1 03c0-03df : vga+ 03e8-03ef : serial(set) 03f6-03f6 : Acer Laboratories Inc. [ALi] M5229 IDE 03f6-03f6 : ide0 03f8-03ff : serial(set) 0cf8-0cff : PCI conf1 1c20-1c3f : Acer Laboratories Inc. [ALi] M7101 PMU e000-efff : PCI Bus #01 e800-e8ff : ATI Technologies Inc 3D Rage LT Pro AGP-133 f800-f8ff : ESS Technology ES1978 Maestro 2E f800-f8ff : ESS Maestro 2E fcf0-fcff : Acer Laboratories Inc. [ALi] M5229 IDE fcf0-fcf7 : ide0 fcf8-fcff : ide1 The /proc/iomem dumps: loop 7392 0 (autoclean) agpgart 12752 0 (autoclean) ppp_deflate 39168 0 (autoclean) bsd_comp 4160 0 (autoclean) ppp_async 6224 1 (autoclean) maestro 25360 1 (autoclean) soundcore 3664 2 (autoclean) [maestro] ppp_generic 12704 3 (autoclean) [ppp_deflate bsd_comp ppp_async] serial_cs 5616 0 (unused) pcnet_cs 11200 1 8390 6112 0 [pcnet_cs] ipt_MASQUERADE 1296 1 (autoclean) iptable_nat 12224 0 [ipt_MASQUERADE] ip_conntrack 12384 1 [ipt_MASQUERADE iptable_nat] ip_tables 9888 4 [ipt_MASQUERADE iptable_nat] ds 6608 2 [serial_cs pcnet_cs] i82365 23216 2 pcmcia_core 43392 0 [serial_cs pcnet_cs ds i82365] nls_iso8859-1 2848 1 (autoclean) nls_cp437 4352 1 (autoclean) vfat 10320 1 fat 30080 0 [vfat] The lspci -vvv dumps: 00:00.0 Host bridge: Acer Laboratories Inc. [ALi] M1541 (rev 04) Subsystem: Acer Laboratories Inc. [ALi] ALI M1541 Aladdin V/V+ AGP System Controller Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=slow >TAbort- <TAbort- <MAbort+ >SERR- <PERR- Latency: 32 Region 0: Memory at e0000000 (32-bit, non-prefetchable) [size=64M] Capabilities: [b0] AGP version 1.0 Status: RQ=28 SBA+ 64bit- FW- Rate=x1,x2 Command: RQ=28 SBA+ AGP+ 64bit- FW- Rate=x2 Capabilities: [e0] Power Management version 1 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- 00:01.0 PCI bridge: Acer Laboratories Inc. [ALi] M5243 (rev 04) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=slow >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 99 Bus: primary=00, secondary=01, subordinate=01, sec-latency=99 I/O behind bridge: 0000e000-0000efff Memory behind bridge: fd000000-fecfffff Prefetchable memory behind bridge: fff00000-000fffff BridgeCtl: Parity- SERR- NoISA+ VGA+ MAbort- >Reset- FastB2B- 00:03.0 CardBus bridge: Texas Instruments PCI1251B Subsystem: Acer Laboratories Inc. [ALi]: Unknown device ac1f Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 168, cache line size 08 Interrupt: pin A routed to IRQ 11 Region 0: Memory at 10000000 (32-bit, non-prefetchable) [size=4K] Bus: primary=00, secondary=02, subordinate=05, sec-latency=176 Memory window 0: 00000000-00000000 (prefetchable) Memory window 1: 00000000-00000000 (prefetchable) I/O window 0: 00000000-00000003 I/O window 1: 00000000-00000003 BridgeCtl: Parity- SERR- ISA- VGA- MAbort- >Reset+ 16bInt+ PostWrite+ 16-bit legacy interface ports at 0001 00:03.1 CardBus bridge: Texas Instruments PCI1251B Subsystem: Acer Laboratories Inc. [ALi]: Unknown device ac1f Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 168, cache line size 08 Interrupt: pin B routed to IRQ 11 Region 0: Memory at 10001000 (32-bit, non-prefetchable) [size=4K] Bus: primary=00, secondary=06, subordinate=09, sec-latency=176 Memory window 0: 00000000-00000000 (prefetchable) Memory window 1: 00000000-00000000 (prefetchable) I/O window 0: 00000000-00000003 I/O window 1: 00000000-00000003 BridgeCtl: Parity- SERR- ISA- VGA- MAbort- >Reset+ 16bInt+ PostWrite+ 16-bit legacy interface ports at 0001 00:07.0 ISA bridge: Acer Laboratories Inc. [ALi] M1533 PCI to ISA Bridge [Aladdin IV] (rev 0a) Subsystem: Acer Laboratories Inc. [ALi] ALI M1533 Aladdin IV ISA Bridge Control: I/O+ Mem+ BusMaster+ SpecCycle+ MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort+ <MAbort+ >SERR- <PERR- Latency: 0 00:09.0 Multimedia audio controller: ESS Technology ES1978 Maestro 2E (rev 10) Subsystem: CLEVO/KAPOK Computer: Unknown device 0982 Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 64 (500ns min, 6000ns max) Interrupt: pin A routed to IRQ 5 Region 0: I/O ports at f800 [size=256] Capabilities: [c0] Power Management version 2 Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0-,D1+,D2+,D3hot+,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- 00:0f.0 IDE interface: Acer Laboratories Inc. [ALi] M5229 IDE (rev 20) (prog-if fa) Subsystem: Acer Laboratories Inc. [ALi] M5229 IDE Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 0 (500ns min, 1000ns max) Interrupt: pin A routed to IRQ 0 Region 0: I/O ports at 01f0 [size=16] Region 1: I/O ports at 03f4 Region 2: I/O ports at 0170 [size=16] Region 3: I/O ports at 0374 Region 4: I/O ports at fcf0 [size=16] 00:11.0 Bridge: Acer Laboratories Inc. [ALi] M7101 PMU (rev 09) Subsystem: Acer Laboratories Inc. [ALi]: Unknown device 1533 Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- 00:13.0 USB Controller: Acer Laboratories Inc. [ALi] M5237 USB (rev 03) (prog-if 10 [OHCI]) Subsystem: Acer Laboratories Inc. [ALi] M5237 USB Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 64, cache line size 08 Interrupt: pin A routed to IRQ 11 Region 0: Memory at fedff000 (32-bit, non-prefetchable) [size=4K] 01:00.0 VGA compatible controller: ATI Technologies Inc 3D Rage LT Pro AGP-133 (rev dc) (prog-if 00 [VGA]) Subsystem: CLEVO/KAPOK Computer: Unknown device 0982 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B- Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 66 (2000ns min), cache line size 08 Interrupt: pin A routed to IRQ 11 Region 0: Memory at fd000000 (32-bit, non-prefetchable) [size=16M] Region 1: I/O ports at e800 [size=256] Region 2: Memory at fecff000 (32-bit, non-prefetchable) [size=4K] Expansion ROM at <unassigned> [disabled] [size=128K] Capabilities: [50] AGP version 1.0 Status: RQ=255 SBA+ 64bit- FW- Rate=x1,x2 Command: RQ=28 SBA+ AGP+ 64bit- FW- Rate=x2 Capabilities: [5c] Power Management version 1 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Best regards. -- Manuel Teira
#include <stdio.h> #include <unistd.h> #include <sys/ioctl.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/time.h> #include <linux/types.h> #include <linux/agpgart.h> #include <asm/mtrr.h> #include <errno.h> unsigned char *gart; int gartfd; int mtrr; int usec( void ) { struct timeval tv; struct timezone tz; gettimeofday( &tv, &tz ); return (tv.tv_sec & 2047) * 1000000 + tv.tv_usec; } int MemoryBenchmark( void *buffer, int dwords ) { int i; int start, end; int mb; int *base; base = (int *)buffer; start = usec(); for ( i = 0 ; i < dwords ; i += 8 ) { base[i] = base[i+1] = base[i+2] = base[i+3] = base[i+4] = base[i+5] = base[i+6] = base[i+7] = 0x15151515; /* dmapad nops */ } end = usec(); mb = ( (float)dwords / 0x40000 ) * 1000000 / (end - start); printf("MemoryBenchmark: %i mb/s\n", mb ); return mb; } int insert_gart(int page, int size) { agp_allocate entry; agp_bind bind; entry.type = 0; entry.pg_count = size; #ifdef DEBUG printf("Using AGPIOC_ALLOCATE\n"); #endif if(ioctl(gartfd, AGPIOC_ALLOCATE, &entry) != 0) { perror("ioctl(AGPIOC_ALLOCATE)"); exit(1); } bind.key = entry.key; bind.pg_start = page; #ifdef DEBUG printf("Using AGPIOC_BIND\n"); #endif if(ioctl(gartfd, AGPIOC_BIND, &bind)) { perror("ioctl(AGPIOC_BIND)"); exit(1); } printf("entry.key : %i\n", entry.key); return(entry.key); } int unbind_gart(int key) { agp_unbind unbind; unbind.key = key; #ifdef DEBUG printf("Using AGPIOC_UNBIND\n"); #endif if(ioctl(gartfd, AGPIOC_UNBIND, &unbind) != 0) { perror("ioctl(AGPIOC_UNBIND)"); exit(1); } return(0); } int bind_gart(int key, int page) { agp_bind bind; bind.key = key; bind.pg_start = page; #ifdef DEBUG printf("Using AGPIOC_BIND\n"); #endif if(ioctl(gartfd, AGPIOC_BIND, &bind) != 0) { perror("ioctl(AGPIOC_BIND)"); exit(1); } return(0); } int remove_gart(int key) { #ifdef DEBUG printf("Using AGPIOC_DEALLOCATE\n"); #endif if(ioctl(gartfd, AGPIOC_DEALLOCATE, key) != 0) { perror("ioctl(GARTIOCREMOVE)"); exit(1); } return(0); } void openmtrr(void) { if ((mtrr = open("/proc/mtrr", O_WRONLY, 0)) == -1) { if (errno == ENOENT) { perror("/proc/mtrr not found: MTRR not enabled\n"); } else { perror("Error opening /proc/mtrr:"); perror("MTRR not enabled\n"); exit(1); } return; } } int CoverRangeWithMTRR( int base, int range, int type ) { int count; /* set it if we aren't just checking the number */ if ( type != -1 ) { struct mtrr_sentry sentry; sentry.base = base; sentry.size = range; sentry.type = type; if ( ioctl(mtrr, MTRRIOC_ADD_ENTRY, &sentry) == -1 ) { perror("mtrr"); exit(1); } } } int init_agp(void) { agp_info info; agp_setup setup; #ifdef DEBUG printf("Using AGPIOC_ACQUIRE\n"); #endif if(ioctl(gartfd, AGPIOC_ACQUIRE) != 0) { perror("ioctl(AGPIOC_ACQUIRE)"); exit(1); } #ifdef DEBUG printf("Using AGPIOC_INFO\n"); #endif if(ioctl(gartfd, AGPIOC_INFO, &info) != 0) { perror("ioctl(AGPIOC_INFO)"); exit(1); } printf("version: %i.%i\n", info.version.major, info.version.minor); printf("bridge id: 0x%lx\n", info.bridge_id); printf("agp_mode: 0x%lx\n", info.agp_mode); printf("aper_base: 0x%lx\n", info.aper_base); printf("aper_size: %i\n", info.aper_size); printf("pg_total: %i\n", info.pg_total); printf("pg_system: %i\n", info.pg_system); printf("pg_used: %i\n", info.pg_used); openmtrr(); if (mtrr != -1) { CoverRangeWithMTRR(info.aper_base, info.aper_size * 0x100000, MTRR_TYPE_WRCOMB); } gart = mmap(NULL, info.aper_size * 0x100000, PROT_READ | PROT_WRITE, MAP_SHARED, gartfd, 0); if(gart == (unsigned char *) 0xffffffff) { perror("mmap"); close(gartfd); exit(1); } setup.agp_mode = info.agp_mode; #ifdef DEBUG printf("Using AGPIOC_SETUP\n"); #endif if(ioctl(gartfd, AGPIOC_SETUP, &setup) != 0) { perror("ioctl(AGPIOC_SETUP)"); exit(1); } return(0); } int xchangeDummy; void FlushWriteCombining( void ) { __asm__ volatile( " push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); __asm__ volatile( " push %%eax ; push %%ebx ; push %%ecx ; push %%edx ; movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ; pop %%eax" : /* no outputs */ : /* no inputs */ ); } void BenchMark() { int i, worked = 1; i = MemoryBenchmark(gart, (1024 * 1024 * 4) / 4) + MemoryBenchmark(gart, (1024 * 1024 * 4) / 4) + MemoryBenchmark(gart, (1024 * 1024 * 4) / 4); printf("Average speed: %i mb/s\n", i /3); printf("Testing data integrity (1st pass): "); fflush(stdout); FlushWriteCombining(); for (i=0; i < 8 * 0x100000; i++) { gart[i] = i % 256; } FlushWriteCombining(); for (i=0; i < 8 * 0x100000; i++) { if(!(gart[i] == i % 256)) { #ifdef DEBUG printf("failed on %i, gart[i] = %i\n", i, gart[i]); #endif worked = 0; } } if (!worked) printf("failed on first pass!\n"); else printf("passed on first pass.\n"); unbind_gart(0); unbind_gart(1); bind_gart(0, 0); bind_gart(1, 1024); worked = 1; printf("Testing data integrity (2nd pass): "); fflush(stdout); for (i=0; i < 8 * 0x100000; i++) { if(!(gart[i] == i % 256)) { #ifdef DEBUG printf("failed on %i, gart[i] = %i\n", i, gart[i]); #endif worked = 0; } } if (!worked) printf("failed on second pass!\n"); else printf("passed on second pass.\n"); } int main() { int i; int key; int key2; agp_info info; gartfd = open("/dev/agpgart", O_RDWR); if (gartfd == -1) { perror("open"); exit(1); } init_agp(); key = insert_gart(0, 1024); key2 = insert_gart(1024, 1024); #ifdef DEBUG printf("Using AGPIOC_INFO\n"); if(ioctl(gartfd, AGPIOC_INFO, &info) != 0) { perror("ioctl(AGPIOC_INFO)"); exit(1); } printf("version: %i.%i\n", info.version.major, info.version.minor); printf("bridge id: 0x%lx\n", info.bridge_id); printf("agp_mode: 0x%lx\n", info.agp_mode); printf("aper_base: 0x%lx\n", info.aper_base); printf("aper_size: %i\n", info.aper_size); printf("pg_total: %i\n", info.pg_total); printf("pg_system: %i\n", info.pg_system); printf("pg_used: %i\n", info.pg_used); #endif printf("Allocated 8 megs of GART memory\n"); BenchMark(); remove_gart(key); remove_gart(key2); #ifdef DEBUG printf("Using AGPIOC_RELEASE\n"); #endif if(ioctl(gartfd, AGPIOC_RELEASE) != 0) { perror("ioctl(AGPIOC_RELEASE)"); exit(1); } close(gartfd); }