public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Nicolas Aspert <Nicolas.Aspert@epfl.ch>
To: Didier Moens <moensd@xs4all.be>
Cc: Robert Love <rml@tech9.net>,
	skraw@ithnet.com, linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [Fwd: Re: OOPS in agpgart (2.4.13, 2.4.15pre7)]
Date: Tue, 27 Nov 2001 08:57:17 +0100	[thread overview]
Message-ID: <3C03475D.6090303@epfl.ch> (raw)
In-Reply-To: <linux.kernel.3C021570.4000603@dmb.rug.ac.be> <3C022BB4.7080707@epfl.ch> <1006808870.817.0.camel@phantasy> <3C02BF41.1010303@xs4all.be>

[-- Attachment #1: Type: text/plain, Size: 1765 bytes --]

Didier Moens wrote:

 > Dear Robert, Nicolas, Stephan,   :)
 >
 >
 > I got two patches :
 >
 >
 > 1. From Stephan, to test whether my assumption about the secondary
 > device was right :
 >
 > Stephan wrote :
 >
 > But if you want you can check that out pretty simple: just add a "break"
 > right
 > after the case :
 >
 >                 case PCI_DEVICE_ID_INTEL_830_M_0:
 > ---> break;
 >
 >                         i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
 >


What is the result if you place the 'break' a few lines below, just
before the 'agp_bridge.type = NOT_SUPPORTED;' ? Does the module still
loads ?


 > This patch left me with a loaded agpgart, and accelerated X (DRM/DRI).
 > The acceleration is still not up to par with an ATI Mobility-128 (30%
 > lower, while it should be at least 200% faster), but I suspect an X
 > CVS-problem here.
 >
 > Quitting and restarting X leaves me with a locked black screen.
 >


The origin of the problem is not obvious... as you said, it could be a
DRI/DRM/X related problem (-> hard to trace). In order to be sure AGP is 
functioning correctly, I suggest that you run this good old test program 
(attached) after loading the AGP module (but before starting X). I 
buried out this little fellow from the utah-glx project. All it does is 
trying to write some data to the agp memory. Try it with both flavors of 
the module (mine+your fix and the one from Stephan), and share the 
output with us ;-)

Good luck


 > Conclusion : Stephan's break-patch loads agpgart, loads X, and locks
 > when reloading X ; Nicolas' patch (when combined with Stephan's first
 > patch) loads agpgart and locks X hard.
 >



-- 
Nicolas Aspert      Signal Processing Laboratory (LTS)
Swiss Federal Institute of Technology (EPFL)


[-- Attachment #2: testgart.c --]
[-- Type: text/plain, Size: 6977 bytes --]

#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);
}


  reply	other threads:[~2001-11-27  7:57 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <linux.kernel.3C021570.4000603@dmb.rug.ac.be>
2001-11-26 11:47 ` [Fwd: Re: OOPS in agpgart (2.4.13, 2.4.15pre7)] Nicolas Aspert
2001-11-26 21:07   ` Robert Love
2001-11-26 22:16     ` Didier Moens
2001-11-27  7:57       ` Nicolas Aspert [this message]
     [not found]       ` <20011127101148.C5778@crystal.2d3d.co.za>
     [not found]         ` <3C034CAE.2090103@dmb.rug.ac.be>
2001-11-27  9:10           ` Abraham vd Merwe
2001-11-27  9:52             ` Didier Moens
2001-11-27 10:05               ` Nicolas Aspert
2001-11-27 10:48                 ` Didier Moens
2001-11-27 11:12                   ` Stephan von Krawczynski
2001-11-27 11:43                     ` Nicolas Aspert
2001-11-27 12:10                       ` Stephan von Krawczynski
2001-11-27 12:49                       ` Didier Moens
2001-11-27 10:51       ` Stephan von Krawczynski
2001-11-26 12:43 ` [PATCH]Re: " Nicolas Aspert
2001-11-26 10:12 Didier Moens

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C03475D.6090303@epfl.ch \
    --to=nicolas.aspert@epfl.ch \
    --cc=linux-kernel@vger.kernel.org \
    --cc=moensd@xs4all.be \
    --cc=rml@tech9.net \
    --cc=skraw@ithnet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox