The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/vgavesa.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include "u.h"
    2 #include "../port/lib.h"
    3 #include "mem.h"
    4 #include "dat.h"
    5 #include "fns.h"
    6 #include "io.h"
    7 #include "../port/error.h"
    8 #include "ureg.h"
    9 
   10 #define Image   IMAGE
   11 #include <draw.h>
   12 #include <memdraw.h>
   13 #include <cursor.h>
   14 #include "screen.h"
   15 
   16 
   17 static void *hardscreen;
   18 
   19 #define WORD(p) ((p)[0] | ((p)[1]<<8))
   20 #define LONG(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))
   21 #define PWORD(p, v) (p)[0] = (v); (p)[1] = (v)>>8
   22 #define PLONG(p, v) (p)[0] = (v); (p)[1] = (v)>>8; (p)[2] = (v)>>16; (p)[3] = (v)>>24
   23 
   24 extern void realmode(Ureg*);
   25 
   26 static uchar*
   27 vbesetup(Ureg *u, int ax)
   28 {
   29         ulong pa;
   30 
   31         pa = PADDR(RMBUF);
   32         memset(u, 0, sizeof *u);
   33         u->ax = ax;
   34         u->es = (pa>>4)&0xF000;
   35         u->di = pa&0xFFFF;
   36         return (void*)RMBUF;
   37 }
   38 
   39 static void
   40 vbecall(Ureg *u)
   41 {
   42         u->trap = 0x10;
   43         realmode(u);
   44         if((u->ax&0xFFFF) != 0x004F)
   45                 error("vesa bios error");
   46 }
   47 
   48 static void
   49 vbecheck(void)
   50 {
   51         Ureg u;
   52         uchar *p;
   53 
   54         p = vbesetup(&u, 0x4F00);
   55         strcpy((char*)p, "VBE2");
   56         vbecall(&u);
   57         if(memcmp((char*)p, "VESA", 4) != 0)
   58                 error("bad vesa signature");
   59         if(p[5] < 2)
   60                 error("bad vesa version");
   61 }
   62 
   63 static int
   64 vbegetmode(void)
   65 {
   66         Ureg u;
   67 
   68         vbesetup(&u, 0x4F03);
   69         vbecall(&u);
   70         return u.bx;
   71 }
   72 
   73 static uchar*
   74 vbemodeinfo(int mode)
   75 {
   76         uchar *p;
   77         Ureg u;
   78 
   79         p = vbesetup(&u, 0x4F01);
   80         u.cx = mode;
   81         vbecall(&u);
   82         return p;
   83 }
   84 
   85 static void
   86 vesalinear(VGAscr *, int, int)
   87 {
   88         int i, mode, size;
   89         uchar *p;
   90         ulong paddr;
   91         Pcidev *pci;
   92 
   93         vbecheck();
   94         mode = vbegetmode();
   95         /* bochs loses the top bits - cannot use this
   96         if((mode&(1<<14)) == 0)
   97                 error("not in linear graphics mode");
   98         */
   99         mode &= 0x3FFF;
  100         p = vbemodeinfo(mode);
  101         if(!(WORD(p+0) & (1<<4)))
  102                 error("not in VESA graphics mode");
  103         if(!(WORD(p+0) & (1<<7)))
  104                 error("not in linear graphics mode");
  105 
  106         paddr = LONG(p+40);
  107         size = WORD(p+20)*WORD(p+16);
  108         size = PGROUND(size);
  109 
  110         /*
  111          * figure out max size of memory so that we have
  112          * enough if the screen is resized.
  113          */
  114         pci = nil;
  115         while((pci = pcimatch(pci, 0, 0)) != nil){
  116                 if(pci->ccrb != Pcibcdisp)
  117                         continue;
  118                 for(i=0; i<nelem(pci->mem); i++)
  119                         if(paddr == (pci->mem[i].bar&~0x0F)){
  120                                 if(pci->mem[i].size > size)
  121                                         size = pci->mem[i].size;
  122                                 goto havesize;
  123                         }
  124         }
  125 
  126         /* no pci - heuristic guess */
  127         if(size < 4*1024*1024)
  128                 size = 4*1024*1024;
  129         else
  130                 size = ROUND(size, 1024*1024);
  131 
  132 havesize:
  133         if(size > 16*1024*1024)         /* probably arbitrary; could increase */
  134                 size = 16*1024*1024;
  135         hardscreen = vmap(paddr, size);
  136         mtrr(paddr, size, "wc");
  137 //      vgalinearaddr(scr, paddr, size);
  138 }
  139 
  140 static void
  141 vesaflush(VGAscr *scr, Rectangle r)
  142 {
  143         int t, w, wid, off;
  144         ulong *hp, *sp, *esp;
  145 
  146         if(rectclip(&r, scr->gscreen->r) == 0)
  147                 return;
  148 
  149         hp = hardscreen;
  150         sp = (ulong*)(scr->gscreendata->bdata + scr->gscreen->zero);
  151         t = (r.max.x * scr->gscreen->depth + 2*BI2WD-1) / BI2WD;
  152         w = (r.min.x * scr->gscreen->depth) / BI2WD;
  153         w = (t - w) * BY2WD;
  154         wid = scr->gscreen->width;
  155         off = r.min.y * wid + (r.min.x * scr->gscreen->depth) / BI2WD;
  156 
  157         hp += off;
  158         sp += off;
  159         esp = sp + Dy(r) * wid;
  160         while(sp < esp){
  161                 memmove(hp, sp, w);
  162                 hp += wid;
  163                 sp += wid;
  164         }
  165 }
  166 
  167 VGAdev vgavesadev = {
  168         "vesa",
  169         0,
  170         0,
  171         0,
  172         vesalinear,
  173         0,
  174         0,
  175         0,
  176         0,
  177         vesaflush,
  178 };

Cache object: 28614c7e2c2ad42b848b6734ff76e26b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.