Dear Ron,
thanks a lot for taking the time to write such a detailed answer!
Am Sonntag, den 08.06.2014, 16:07 -0700 schrieb ron minnich:
Paul, many good questions. The problem is I did all this over 2 years ago and the answers won't be as good. Vladimir and Peter will likely do better. And, to reiterate, the 'replay attack' code for Link is not a good example of how to start graphics. It Just Worked, but not well.
I am aware of that. The replay code also works on the Lenovo X60, but since Linux 3.12+ 3D is broken, which we try to fix. Also the GTT code is more or less identical in master and in Vladimir’s patch set [1].
Please also note, that at least since Linux 3.11, Linux is not able anymore to set up graphics without the Video ROM or native graphics init. Unfortunately, nobody bisected this yet or notified the Linux folks of this regression. As I do not have the hardware, I won’t report that as it takes too much time to relay information.
The second iteration Furquan and I did on Falco and Pepper is really what we need to use.
That graphics code is not upstream yet, is it?
$ git grep MAINBOARD_DO_NATIVE src/mainboard/google/ src/mainboard/google/link/Makefile.inc:ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += i915.c src/mainboard/google/link/Makefile.inc:ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += i915io.c src/mainboard/google/link/Makefile.inc:ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += intel_dp.c src/mainboard/google/pit/Kconfig: select MAINBOARD_DO_NATIVE_VGA_INIT src/mainboard/google/slippy/Kconfig: select MAINBOARD_DO_NATIVE_VGA_INIT src/mainboard/google/slippy/Makefile.inc:ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += gma.c i915io.c src/mainboard/google/snow/Kconfig: select MAINBOARD_DO_NATIVE_VGA_INIT $ git grep i915lightup src/northbridge/intel/haswell/ src/mainboard/google/{falco,peppy} src/northbridge/intel/haswell/gma.c: int i915lightup(u32 physbase, u32 iobase, u32 mmiobase, u32 gfx); src/northbridge/intel/haswell/gma.c: lightup_ok = i915lightup(physbase, iobase, mmiobase, graphics_base);
So let's take it a bit at a time.
The GTT is a page table used by the graphics hardware to address memory. It translates graphics addresses to physical addresses.
Part of the hardcoding of size is because in some cases the chipset has a limited choice of sizes -- you set a bit, it takes a certain fixed size. 8 MiB is common to the older chipsets. At the same time, once the kernel starts, it's going to change the GTT anyway -- we're mainly doing GTT setup here to make it easy to paint the boot splash screens. That's it.
Note that GTT allows the graphics hardware to address anything in the low 4 GiB, and even more on some chipsets, where another set of address bits is stashed in the low 12 bits.
You can address the memory pointed to by the GTT. Use the address in one of the BARs -- IIRC, bar 0? I don't recall, maybe BAR2 -- as your address. Your references are then mapped back to physical memory addresses via the GTT mappings.
And does `setgtt()` reserves that memory? I am still missing, why `setgtt()` is needed and why we write stuff in there.
static void setgtt(int start, int end, unsigned long base, int inc) { int i;
for(i = start; i < end; i++){ u32 word = base + i*inc; WRITE32(word|1,(i*4)|1); } }
GSM is an odd duck. […]
Where does GSM come into plays I think, I meant BSM and not GSM. ;-)
Also note that the GTT is just a way to map graphics chipset references to physical addresses, and again is not really related to resolution or depth, except in two ways:
- if you don't create enough entries for the resolution, you have a problem
- if you create too many, you might waste memory
The second problem is not as serious as the first. So we just grab a lot of memory and map it, because the coreboot mappings will be replaced anyway by the driver.
Yes, that second problem has to be solved generically, when writing native graphics code, that is generic for all mainboards with that chipset.
The GTT settings are fairly safe and I think you're on the wrong track in terms of your debugging, but I could be wrong.
You should not assume that it's NOT a Linux driver problem. The Linux drivers are not well tested against coreboot, and we know of cases where they worked against the BIOS, but only by mostly luck. Sound familiar :-) ? It's the problem we've always had.
That is indeed still a possibility.
I would question this change:
PGETBL_CTL: 0x3ffc0001
PGETBL_CTL: 0x3f800001
because it doesn't come with an explanation of what it's supposed to fix.
As far as I understand it, it points to the GTT, which sits directly below TOLUD. And with that change 3D at least works under Linux 3.12+. I have no idea, if since some versions the Linux Intel graphics driver dependents more on firmware initialization and does not replace the GTT setup anymore.
[…]
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/mobil... [5] https://01.org/linuxgraphics/sites/default/files/documentation/965_g35_vol_1...
On Mon, Jun 9, 2014 at 6:00 AM, Paul Menzel < paulepanter@users.sourceforge.net> wrote:
Dear Ron,
Please also note, that at least since Linux 3.11, Linux is not able anymore to set up graphics without the Video ROM or native graphics init. Unfortunately, nobody bisected this yet or notified the Linux folks of this regression. As I do not have the hardware, I won’t report that as it takes too much time to relay information.
I've pinged someone I know about it.
The second iteration Furquan and I did on Falco and Pepper is really what we need to use.
That graphics code is not upstream yet, is it?
I guess not, I no longer do coreboot full time, so can't say when it will go in. But it's visible in the chromium repo and IMHO it's pretty good code, worth taking.
Really, those CLs are available for anyone to grab and test and push upstream. It doesn't have to just be Google people who do the job.
And does `setgtt()` reserves that memory? I am still missing, why `setgtt()` is needed and why we write stuff in there.
setgtt does not reserve that memory, and it should not. But something has to set that gtt up, and setgtt does the job.
static void setgtt(int start, int end, unsigned long base, int inc) { int i; for(i = start; i < end; i++){ u32 word = base + i*inc; WRITE32(word|1,(i*4)|1); } }
And note a trick here: if you set 'inc' to zero, you can have setgtt point all gtts at one page, load that page with a color, and get a splash screen up *very* quickly. It saves well over 100 ms.
But if you want a splash screen, you're going to need setgtt.
GSM is an odd duck. […]
Where does GSM come into plays I think, I meant BSM and not GSM. ;-)
just making sure.
Also note that the GTT is just a way to map graphics chipset references
to
physical addresses, and again is not really related to resolution or
depth,
except in two ways:
- if you don't create enough entries for the resolution, you have a
problem
- if you create too many, you might waste memory
The second problem is not as serious as the first. So we just grab a lot
of
memory and map it, because the coreboot mappings will be replaced anyway
by
the driver.
Yes, that second problem has to be solved generically, when writing native graphics code, that is generic for all mainboards with that chipset.
It does not have to be solved exactly becase the kernel drivers will not use whatever you do. So it's easiest just to grab a big chunk of RAM, point the gtt at as much of it as you need, and not worry. Again, the RAM you allocate and the GTT entries you create are ignored once the kernel starts the driver.
Or, if it's a quick boot and you don't want splash, fill one page with a nice color, and point all gtt at that one page. The speed difference is quite noticeable.
I would question this change:
PGETBL_CTL: 0x3ffc0001
PGETBL_CTL: 0x3f800001
because it doesn't come with an explanation of what it's supposed to fix.
As far as I understand it, it points to the GTT, which sits directly below TOLUD. And with that change 3D at least works under Linux 3.12+. I have no idea, if since some versions the Linux Intel graphics driver dependents more on firmware initialization and does not replace the GTT setup anymore.
Again, somebody has to dig deeper and explain what that bit is doing. What does it do and why does it help?
Good luck!
ron