Messages in this thread Patch in this message | | | Date | Mon, 3 Aug 1998 21:07:31 +0200 | From | Gerd Knorr <> | Subject | Re: FB and MTRR |
| |
In lists.linux.kernel you write:
>In lists.linux.kernel you write:
>>On Sat, 1 Aug 1998, Richard Gooch wrote: >>> Hi, Geert. IIRC, you wrote a note about using the FB code on i386, >>> and at the end you mentioned using /proc/mtrr to speed up
>Already done (but I want boot that kernel at least once before >mailing patches).
ok, here we go. Some new vesafb bits. Changed:
* doc update, I hope less confusing now... * does the mtrr thing mentioned above automatically at startup. Killed the two doc lines, as they are not required any more :-) * some startup-asm hacking, passes more information. * started support for the VESA Protected Mode Interface. Does NOT work for me and is therefore disabled by default. Once this works we will hopefully get a nice speedup becauce we can use YPAN for scrolling then.
Gerd
PS: Anyone has the full VESA 2.0 specs? I have just a magazine article which is'nt very verbose wrt. Protected Mode Interface.
-------------------------------------------------------------- diff -urN kernel/2.1.113/Documentation/fb/vesafb.txt linux/Documentation/fb/vesafb.txt --- kernel/2.1.113/Documentation/fb/vesafb.txt Thu Jul 30 23:04:01 1998 +++ linux/Documentation/fb/vesafb.txt Mon Aug 3 20:44:38 1998 @@ -30,11 +30,13 @@ ============== Switching modes is done using the vga=... boot parameter. Read -Documentation/svga.txt for details. With vesafb both text and -graphics modes work. Text modes are handled by vgafb, graphic modes -by the new vesafb.c. +Documentation/svga.txt for details. -The graphic modes are not in the list which you get if you boot with +You should compile in both vgacon (for text mode) and vesafb (for +graphics mode). Which of them takes over the console depends on +whenever the specified mode is text or graphics. + +The graphic modes are NOT in the list which you get if you boot with vga=ask and hit return. Here are some mode numbers: | 640x480 800x600 1024x768 @@ -44,17 +46,22 @@ 64k | 0x111 0x114 0x117 16M | 0x112 0x115 0x118 -Note 1: this are the VESA mode numbers. The video mode select code - expects 0x200 + VESA mode number. -Note 2: lilo can't handle hex, for booting with "vga=??" you have to - transform the numbers to decimal. +This are the VESA mode numbers. The video mode select code expects +0x200 + VESA mode number. Therefore you have to enter "305" at the +"vga=ask" prompt to boot into 1024x768x8. + +If this does'nt work, this might be becauce your BIOS does not support +linear framebuffers or becauce it does'nt support this mode at all. +Even if your board does, it might be the BIOS does not. VESA BIOS +Extentions v2.0 are required, 1.2 is NOT sufficient. You'll get a +"bad mode number" message if something goes wrong. + +Note: LILO can't handle hex, for booting directly with "vga=mode-number" + you have to transform the numbers to decimal. Speed it up! ============ - -Check /usr/src/linux/Documentation/mtrr.txt, enabling write-combining -for the framebuffer memory gives a performance boost. There are two ways to do console scrolling: redraw the screen completely, or by copying around the video memory. You can select one diff -urN kernel/2.1.113/arch/i386/boot/video.S linux/arch/i386/boot/video.S --- kernel/2.1.113/arch/i386/boot/video.S Thu Jul 30 23:03:41 1998 +++ linux/arch/i386/boot/video.S Mon Jul 27 23:09:06 1998 @@ -85,6 +85,9 @@ #define PARAM_LFB_SIZE 0x1c #define PARAM_LFB_LINELENGTH 0x24 #define PARAM_LFB_COLORS 0x26 +#define PARAM_VESAPM_SEG 0x2e +#define PARAM_VESAPM_OFF 0x30 +#define PARAM_LFB_PAGES 0x32 ! Define DO_STORE according to CONFIG_VIDEO_RETAIN #ifdef CONFIG_VIDEO_RETAIN @@ -236,13 +239,14 @@ seg fs mov [PARAM_LFB_DEPTH],ax - mov eax,(di+40) + mov al,(di+29) + mov ah,#0 seg fs - mov [PARAM_LFB_BASE],eax + mov [PARAM_LFB_PAGES],ax - mov eax,(di+44) + mov eax,(di+40) seg fs - mov [PARAM_LFB_SIZE],eax + mov [PARAM_LFB_BASE],eax mov eax,(di+31) seg fs @@ -251,7 +255,30 @@ mov eax,(di+35) seg fs mov [PARAM_LFB_COLORS+4],eax - + + ! get video mem size + lea di,modelist+1024 + mov ax,#0x4f00 + int 0x10 + + xor eax,eax + mov ax,(di+18) + seg fs + mov [PARAM_LFB_SIZE],eax + + ! get protected mode interface informations + mov ax,#0x4f0a + xor bx,bx + xor di,di + int 0x10 + cmp ax,#0x004f + jnz no_pm + seg fs + mov [PARAM_VESAPM_SEG],es + seg fs + mov [PARAM_VESAPM_OFF],di + +no_pm: ret ! diff -urN kernel/2.1.113/drivers/video/vesafb.c linux/drivers/video/vesafb.c --- kernel/2.1.113/drivers/video/vesafb.c Mon Aug 3 00:33:31 1998 +++ linux/drivers/video/vesafb.c Mon Aug 3 20:37:58 1998 @@ -21,8 +21,10 @@ #include <linux/selection.h> #include <linux/ioport.h> #include <linux/init.h> +#include <linux/config.h> #include <asm/io.h> +#include <asm/mtrr.h> #include "fbcon.h" #include "fbcon-cfb8.h" @@ -77,9 +79,14 @@ static struct fb_info fb_info; static struct { u_char red, green, blue, pad; } palette[256]; -static int inverse = 0; - -static int currcon = 0; +static int inverse = 0; +static int currcon = 0; +static int ypanstep = 0; + +static int pmi = 0; /* use VESA protected mode interface ? */ +static unsigned short *pmi_base = 0; +static void (*pmi_start)(void); +static void (*pmi_pal)(void); /* --------------------------------------------------------------------- */ /* speed up scrolling */ @@ -111,8 +118,34 @@ return(0); } -static int fb_update_var(int con, struct fb_info *info) +static int vesafb_pan_display(struct fb_var_screeninfo *var, int con, + struct fb_info *info) +{ +#if 0 + printk("vesafb: pan: yoffset=%d\n",var->yoffset); +#endif + if (!pmi) + return -EINVAL; + if (var->xoffset || var->yoffset+var->yres > var->yres_virtual) + return -EINVAL; + + __asm__ __volatile__( + "call *(%%edi)" + : /* no return value */ + : "a" (0x4f07), /* EAX */ + "b" (0), /* EBX */ + "c" (0), /* ECX */ + "d" (var->yoffset), /* EDX */ + "D" (&pmi_start)); /* EDI */ + return 0; +} + +static int vesafb_update_var(int con, struct fb_info *info) { + if (con == currcon && pmi) { + struct fb_var_screeninfo *var = &fb_display[currcon].var; + return vesafb_pan_display(var,con,info); + } return 0; } @@ -127,7 +160,7 @@ fix->type = video_type; fix->visual = video_visual; fix->xpanstep=0; - fix->ypanstep=0; + fix->ypanstep=ypanstep; fix->ywrapstep=0; fix->line_length=video_linelength; return 0; @@ -317,13 +350,6 @@ return 0; } -static int vesafb_pan_display(struct fb_var_screeninfo *var, int con, - struct fb_info *info) -{ - /* no panning */ - return -EINVAL; -} - static int vesafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, int con, struct fb_info *info) @@ -363,6 +389,8 @@ vesafb_scroll = USE_REDRAW; else if (! strcmp(this_opt, "memmove")) vesafb_scroll = USE_MEMMOVE; + else if (! strcmp(this_opt, "pmi")) + pmi = 1; else if (!strncmp(this_opt, "font:", 5)) strcpy(fb_info.fontname, this_opt+5); } @@ -400,15 +428,42 @@ video_width = screen_info.lfb_width; video_height = screen_info.lfb_height; video_linelength = screen_info.lfb_linelength; - video_size = video_linelength * video_height /* screen_info.lfb_size */; + video_size = screen_info.lfb_size * 65536; video_visual = (video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; video_vbase = ioremap((unsigned long)video_base, video_size); - printk("vesafb: %dx%dx%d, linelength=%d\n", - video_width, video_height, video_bpp, video_linelength); - printk("vesafb: framebuffer at 0x%p, mapped to 0x%p, size %d\n", - video_base, video_vbase, video_size); + printk("vesafb: framebuffer at 0x%p, mapped to 0x%p, size %dk\n", + video_base, video_vbase, video_size/1024); + printk("vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", + video_width, video_height, video_bpp, video_linelength, screen_info.pages); + + if (screen_info.vesapm_seg) { + if (screen_info.vesapm_seg < 0xc000) + pmi = 0; /* don't try to use some DOS TSR ... */ + printk("vesafb: protected mode interface info at %04x:%04x, %s\n", + screen_info.vesapm_seg,screen_info.vesapm_off, + pmi ? "enabled" : "disabled"); + } else + pmi = 0; + + if (pmi) { + pmi_base = (unsigned short*)(__PAGE_OFFSET+((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); + pmi_start = (void*)((char*)pmi_base + pmi_base[1]); + pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); + printk("vesafb: pmi: set display start : %p\n",pmi_start); + printk("vesafb: pmi: set palette : %p\n",pmi_pal); + printk("vesafb: pmi: required ports : "); + for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++) + printk("%x ",pmi_base[i]); + printk("\nvesavb: pmi: required mem areas: "); + for (i++; pmi_base[i] != 0xffff; i+=3) + printk("%lx+%x ", + ((unsigned long)pmi_base[i]<<16) + + pmi_base[i+1], pmi_base[i+3]); + printk("\n"); + } + if (vesafb_scroll == USE_REDRAW) printk("vesafb: scrolling=redraw\n"); if (vesafb_scroll == USE_MEMMOVE) printk("vesafb: scrolling=memmove\n"); @@ -418,6 +473,13 @@ vesafb_defined.yres_virtual=video_height; vesafb_defined.bits_per_pixel=video_bpp; + if (pmi && screen_info.pages) { + /* set up ypan using VESA Protected Mode Interface */ + vesafb_defined.yres_virtual = video_height * screen_info.pages; + ypanstep = 1; + printk("vesafb: using pmi for ypan\n"); + } + if (video_bpp > 8) { vesafb_defined.red.offset = screen_info.red_pos; vesafb_defined.red.length = screen_info.red_size; @@ -451,6 +513,9 @@ video_cmap_len = 256; } request_region(0x3c0, 32, "vga+"); +#ifdef CONFIG_MTRR + mtrr_add(video_base, video_size, MTRR_TYPE_WRCOMB, 0); +#endif strcpy(fb_info.modename, "VESA VGA"); fb_info.changevar = NULL; @@ -458,7 +523,7 @@ fb_info.fbops = &vesafb_ops; fb_info.disp=&disp; fb_info.switch_con=&vesafb_switch; - fb_info.updatevar=&fb_update_var; + fb_info.updatevar=&vesafb_update_var; fb_info.blank=&vesafb_blank; vesafb_set_disp(-1); diff -urN kernel/2.1.113/include/linux/tty.h linux/include/linux/tty.h --- kernel/2.1.113/include/linux/tty.h Thu Jul 30 23:03:55 1998 +++ linux/include/linux/tty.h Mon Aug 3 00:45:00 1998 @@ -69,7 +69,10 @@ unsigned char blue_pos; /* 0x2b */ unsigned char rsvd_size; /* 0x2c */ unsigned char rsvd_pos; /* 0x2d */ - /* 0x2e -- 0x3f reserved for future expansion */ + unsigned short vesapm_seg; /* 0x2e */ + unsigned short vesapm_off; /* 0x30 */ + unsigned short pages; /* 0x32 */ + /* 0x34 -- 0x3f reserved for future expansion */ }; extern struct screen_info screen_info; -- Gerd Knorr <kraxel@cs.tu-berlin.de> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html
| |