On Wed, 7 Jun 2000, Ryuichi Oikawa wrote:
Geert did explain the problem. It is due to incorrect offset estimation.
Let me explain your case in detail. The authur of fbdev module seems to
assume frame buffer size as a multiple of page size:
fbdevhw.c
void* fbdevHWMapVidmem(ScrnInfoPtr pScrn)
{
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
TRACE_ENTER("MapVidmem");
if (NULL == fPtr->fbmem) {
fPtr->fboff = fPtr->fix.smem_len & (PAGE_SIZE-1);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fPtr->fbmem = mmap(NULL, fPtr->fix.smem_len, PROT_READ | PROT_WRITE,
MAP_SHARED, fPtr->fd, 0);
but the fact is different from his assumption. As you know very well,
controlfb adjusts fb memory size by subtracting display offset(in your
case 80 = 0x50 bytes) so that
fboff = (4M - 0x50) & 0xfff = 0xfb0
fbmem = smem_start & 0xfffff000 = smem_start - 0x50.
Thus your Xserver's video memory starts at offset
(fbmem + fboff) - smem_start = 0xfb0 - 0x50 = 0xf60 = 3936 bytes.
Now you understand the fix is very simple:
- fPtr->fboff = fPtr->fix.smem_len & (PAGE_SIZE-1);
+ fPtr->fboff = fPtr->fix.smem_start & (PAGE_SIZE-1);
That's not sufficient (perhaps it is in this case, though): both fix.smem_start
and fix.smem_len may be not page aligned. To catch all cases, you have to use
the formula from my previous posting.
But looking through the XF4 fbdev support code I saw two more mistakes
causing potential problem. One is a confusion of virtual screen width
with screen pitch:
fbdev.c
pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
Yes, this is wrong as the authur noted, but interestingly this code spreads
over the all drivers supporting fbdev, though I can't distinguish which is
the original :^) Maybe polite solution is to fix each driver, but quick
fix will be
+ pScrn->displayWidth = fPtr->fix.line_width /
+ (fPtr->var.bits_per_pixel >> 3)
Typo: the field is called `line_length', not `line_width'.
And that formula is valid for chunky displays only, not for interleaved
bitplanes (I suppose pScrn->displayWidth is the width of one line in memory,
counted in pixel units?).
If line_length is 0, you must fallback to xres_virtual / bytes_per_pixel.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven ------------- Sony Software Development Center Europe (SDCE)
Geert.Uytterhoeven@sonycom.com ------------------- Sint-Stevens-Woluwestraat 55
Voice +32-2-7248638 Fax +32-2-7262686 ---------------- B-1130 Brussels, Belgium
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
quoted
Now you understand the fix is very simple:
- fPtr->fboff = fPtr->fix.smem_len & (PAGE_SIZE-1);
+ fPtr->fboff = fPtr->fix.smem_start & (PAGE_SIZE-1);
That's not sufficient (perhaps it is in this case, though): both fix.smem_start
and fix.smem_len may be not page aligned. To catch all cases, you have to use
the formula from my previous posting.
Did that just get lost between XFree release 3 and 4, or did we have it
wrong all along? I wonder if that was what caused problems on some m68k
Mac video hardware ...
quoted
Yes, this is wrong as the authur noted, but interestingly this code spreads
over the all drivers supporting fbdev, though I can't distinguish which is
the original :^) Maybe polite solution is to fix each driver, but quick
fix will be
+ pScrn->displayWidth = fPtr->fix.line_width /
+ (fPtr->var.bits_per_pixel >> 3)
Typo: the field is called `line_length', not `line_width'.
And that formula is valid for chunky displays only, not for interleaved
bitplanes (I suppose pScrn->displayWidth is the width of one line in memory,
counted in pixel units?).
If line_length is 0, you must fallback to xres_virtual / bytes_per_pixel.
Is the displayWidth / xres_virtual synonymous to the line length (offset
between start of subsequent lines), or might displayWidth be used for
something else altogether? displayWidth seems a misnomer (on some
hardware, there's no video RAM between the end of one scan line and the
probably page aligned start of the next ...)?
Michael
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
On Wed, 7 Jun 2000, Michael Schmitz wrote:
quoted
quoted
Now you understand the fix is very simple:
- fPtr->fboff = fPtr->fix.smem_len & (PAGE_SIZE-1);
+ fPtr->fboff = fPtr->fix.smem_start & (PAGE_SIZE-1);
That's not sufficient (perhaps it is in this case, though): both fix.smem_start
and fix.smem_len may be not page aligned. To catch all cases, you have to use
the formula from my previous posting.
Did that just get lost between XFree release 3 and 4, or did we have it
wrong all along? I wonder if that was what caused problems on some m68k
Mac video hardware ...
It should be correct in 3.3.x.
quoted
quoted
Yes, this is wrong as the authur noted, but interestingly this code spreads
over the all drivers supporting fbdev, though I can't distinguish which is
the original :^) Maybe polite solution is to fix each driver, but quick
fix will be
+ pScrn->displayWidth = fPtr->fix.line_width /
+ (fPtr->var.bits_per_pixel >> 3)
Typo: the field is called `line_length', not `line_width'.
And that formula is valid for chunky displays only, not for interleaved
bitplanes (I suppose pScrn->displayWidth is the width of one line in memory,
counted in pixel units?).
If line_length is 0, you must fallback to xres_virtual / bytes_per_pixel.
Is the displayWidth / xres_virtual synonymous to the line length (offset
between start of subsequent lines), or might displayWidth be used for
something else altogether? displayWidth seems a misnomer (on some
hardware, there's no video RAM between the end of one scan line and the
probably page aligned start of the next ...)?
At least in 3.3.6, X wasn't capable of handling displays where the offset to
the next line was not equal to what you'd expect from xres_virtual. The only
way to make such hardware work is to fake the virtual screen width
(displayWidth) by something derived from line_length.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/