[Bug 29813] AGPGART related issue's in combination of ASUS motherboard
Amon_Re
ochal at kefren.be
Thu Jan 26 23:07:48 UTC 2006
Public bug reported:
https://launchpad.net/malone/bugs/29813
Affects: linux-source-2.6.15 (Ubuntu)
Severity: Normal
Priority: (none set)
Status: Unconfirmed
Description:
The following bug occurs in the last few kernels that have been
released.
When using an Asus K8V-X SE motherboard, combined with an AMD Sempron
3200 AGP is incorrectly detected.
The problem manifests itself at boot with the agpgart incorrectly
recognising the Aperture size.
Eg:
[4294680.541000] Linux agpgart interface v0.101 (c) Dave Jones
[4294680.555000] agpgart: Detected AGP bridge 0
[4294680.556000] agpgart: AGP aperture is 32M @ 0xe4000000
No matter of what Aperture size specified in the BIOS of the machine,
the reported size is *ALWAYS* 32M.
The problem seems to manifest itself when trying to use DRI aswell as
drivers from the manufacturers
DRI has been tested with 4 AGP cards sofar:
AGP ATI 9200
AGP ATI 9800
AGP ATI Rage128
AGP Nvidia MX240 (if i recall correctly, don't have the card handy right now)
X locks up with all 4 cards when DRI is enabled.
Once X locks up, the machine can't be accessed locally, only SSH access
is possible.
I have run a program "agptest" who's source i found on the 'net, these
are the results:
localhost ochal # ./test
version: 0.101
bridge id: 0x2821106
agp_mode: 0x1f000a1b
aper_base: 0xe4000000
aper_size: 32
pg_total: 112384
pg_system: 112384
pg_used: 0
entry.key : 0
entry.key : 1
Allocated 8 megs of GART memory
MemoryBenchmark: 8 mb/s
MemoryBenchmark: 8 mb/s
MemoryBenchmark: 9 mb/s
Average speed: 8 mb/s
Testing data integrity (1st pass): failed on first pass!
Testing data integrity (2nd pass): failed on second pass!
The source of the testprogam will be appended at the end of this report.
I am capable, and willing, of recompiling kernels, so do not hestitate
to ask me to test stuff.
--------------------------------------------------
The following is the lspci output:
ochal at scruffy:~$ lspci
0000:00:00.0 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.1 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.2 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.3 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.4 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.7 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:01.0 PCI bridge: VIA Technologies, Inc. VT8237 PCI bridge [K8T800/K8T890 South]
0000:00:0c.0 Multimedia video controller: Brooktree Corporation Bt878 Video Capture (rev 11)
0000:00:0c.1 Multimedia controller: Brooktree Corporation Bt878 Audio Capture (rev 11)
0000:00:0d.0 USB Controller: ALi Corporation USB 1.1 Controller (rev 03)
0000:00:0d.1 USB Controller: ALi Corporation USB 1.1 Controller (rev 03)
0000:00:0d.3 USB Controller: ALi Corporation USB 2.0 Controller (rev 01)
0000:00:0d.4 FireWire (IEEE 1394): ALi Corporation M5253 P1394 OHCI 1.1 Controller
0000:00:0f.0 RAID bus controller: VIA Technologies, Inc. VIA VT6420 SATA RAID Controller (rev 80)
0000:00:0f.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06)
0000:00:10.0 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.1 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.2 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.3 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.4 USB Controller: VIA Technologies, Inc. USB 2.0 (rev 86)
0000:00:11.0 ISA bridge: VIA Technologies, Inc. VT8237 ISA bridge [KT600/K8T800/K8T890 South]
0000:00:11.5 Multimedia audio controller: VIA Technologies, Inc. VT8233/A/8235/8237 AC97 Audio Controller (rev 60)
0000:00:12.0 Ethernet controller: VIA Technologies, Inc. VT6102 [Rhine-II] (rev 78)
0000:00:18.0 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] HyperTransport Technology Configuration
0000:00:18.1 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Address Map
0000:00:18.2 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] DRAM Controller
0000:00:18.3 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Miscellaneous Control
0000:01:00.0 VGA compatible controller: ATI Technologies Inc Radeon R300 ND [Radeon 9700 Pro]
0000:01:00.1 Display controller: ATI Technologies Inc Radeon R300 [Radeon 9700 Pro] (Secondary)
The testgart.c code:
/*
*
* Test program for AGPGART module under Linux
*
* Copyright (C) 1999 Jeff Hartmann,
* Precision Insight, Inc., Xi Graphics, Inc.
*
*/
#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);
}
More information about the kernel-bugs
mailing list