[coreboot] Intel native graphics init: Questions about GTT setup

Paul Menzel paulepanter at users.sourceforge.net
Mon Jun 9 00:22:48 CEST 2014


Dear coreboot folks,


since Linux 3.12+ graphics stolen memory seems to be used, which causes
a regression with coreboot and native graphics init at least on the
Intel 945 based Lenovo X60 [1].

This seems to be solved by properly setting register `PGETBL_CTL` [2],
but the Linux kernel Intel graphics driver still reports a GTT (Graphics
Translation Table) related error during start-up, but everything else
seems to work.

        [    1.235640] [drm] GPU crash dump saved to /sys/class/drm/card0/error
        [    1.236583] [drm] GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.
        [    1.236583] [drm] Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel
        [    1.236583] [drm] drm/i915 developers can then reassign to the right component if it's not a kernel issue.
        [    1.236583] [drm] The gpu crash dump is required to analyze gpu hangs, so please always attach it.
        [    1.236583] i915: render error detected, EIR: 0x00000010
        [    1.236583] i915: page table error
        [    1.236583] i915:   PGTBL_ER: 0x00000013
        [    1.236583] [drm:i915_report_and_clear_eir] *ERROR* EIR stuck: 0x00000010, masking
        [    1.236583] i915: render error detected, EIR: 0x00000010
        [    1.236583] i915: page table error
        [    1.236583] i915:   PGTBL_ER: 0x00000013

Looking further into the native graphics init code for Intel IGDs, I
wonder what `setgtt()` does.

Looking at Google Link, where this was introduced, there is the code
below.

        $ nl -ba src/mainboard/google/link/i915.c
        […]
            95	void io_i915_WRITE32(unsigned long val, unsigned long addr)
            96	{
            97		if (verbose & vio)
            98			printk(BIOS_SPEW, "%s: outl %08lx\n", regname(addr), val);
            99		outl(addr, addrport);
           100		outl(val, dataport);
           101	}
           102	
           103	
           104	/*
           105	  2560
           106	  4 words per
           107	  4 *p
           108	  10240
           109	  4k bytes per page
           110	  4096/p
           111	  2.50
           112	  1700 lines
           113	  1700 * p
           114	  4250.00
           115	  PTEs
           116	*/
           117	static void
           118	setgtt(int start, int end, unsigned long base, int inc)
           119	{
           120		int i;
           121	
           122		for(i = start; i < end; i++){
           123			u32 word = base + i*inc;
           124			WRITE32(word|1,(i*4)|1);
           125		}
           126	}
        […]
           349		/* GTT is the Global Translation Table for the graphics pipeline.
           350		 * It is used to translate graphics addresses to physical
           351		 * memory addresses. As in the CPU, GTTs map 4K pages.
           352		 * There are 32 bits per pixel, or 4 bytes,
           353		 * which means 1024 pixels per page.
           354		 * There are 4250 GTTs on Link:
           355		 * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page.
           356		 * The setgtt function adds a further bit of flexibility:
           357		 * it allows you to set a range (the first two parameters) to point
           358		 * to a physical address (third parameter);the physical address is
           359		 * incremented by a count (fourth parameter) for each GTT in the
           360		 * range.
           361		 * Why do it this way? For ultrafast startup,
           362		 * we can point all the GTT entries to point to one page,
           363		 * and set that page to 0s:
           364		 * memset(physbase, 0, 4096);
           365		 * setgtt(0, 4250, physbase, 0);
           366		 * this takes about 2 ms, and is a win because zeroing
           367		 * the page takes a up to 200 ms. We will be exploiting this
           368		 * trick in a later rev of this code.
           369		 * This call sets the GTT to point to a linear range of pages
           370		 * starting at physbase.
           371		 */
           372		setgtt(0, FRAME_BUFFER_PAGES, physbase, 4096);
           373		printk(BIOS_SPEW, "memset %p to 0 for %d bytes\n",
           374			(void *)graphics, FRAME_BUFFER_BYTES);
        […]
        $ git grep FRAME_BUFFER src/mainboard/google/link/i915io.h
        src/mainboard/google/link/i915io.h:#define FRAME_BUFFER_PAGES ((2560*1700)/1024)
        src/mainboard/google/link/i915io.h:#define FRAME_BUFFER_BYTES (FRAME_BUFFER_PAGES*4096)

Looking at the code of the Lenovo X60 with the resolution of 1024×768,
instead of `FRAME_BUFFER_PAGES` = 768 it is the higher number 800.
Otherwise there are graphical corruptions on the GRUB screen.

Furthermore Vladimir’s native graphics patch up for review in Gerrit [3]
uses the code below [3].

       /* Setup GTT. */    
       for (i = 0; i < 0x2000; i++)       
       {           
              outl((i << 2) | 1, piobase);         
              outl(pphysbase + (i << 12) + 1, piobase + 4);        
       }

This is equivalent to `setgtt(0, 8192, physbase, 4096)`. As the code
should be not hardcoded to one resolution (for example the Lenovo T60
has a different one than the Lenovo X60), the code should be dynamic.

Unfortunately, I did not find anything in the datasheet [4][5]
explaining, why this `setgtt()` is needed at all. I guess this was
figured out by tracing the Video BIOS? Ron, Denis, Peter, Vladimir, it’d
be great if you could explain that to me?

At least on Intel 945, the GTT is 256 KB big and is placed below TOLUD
into the graphics stolen memory, which is currently hardcoded to 8 MB.
So how should the pages be setup then?


Thanks,

Paul


[1] https://bugs.freedesktop.org/show_bug.cgi?id=79038
[2] http://review.coreboot.org/5927
[3] http://review.coreboot.org/#/c/5320/9/src/northbridge/intel/i945/gma.c
[4] http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/mobile-945-express-chipset-datasheet.pdf
[5] https://01.org/linuxgraphics/sites/default/files/documentation/965_g35_vol_1_graphics_core_0.pdf
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20140609/58fccaba/attachment.asc>


More information about the coreboot mailing list