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/alphapc/devvga.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 /*
    2  * VGA controller
    3  */
    4 #include "u.h"
    5 #include "../port/lib.h"
    6 #include "mem.h"
    7 #include "dat.h"
    8 #include "fns.h"
    9 #include "io.h"
   10 #include "../port/error.h"
   11 
   12 #define Image   IMAGE
   13 #include <draw.h>
   14 #include <memdraw.h>
   15 #include <cursor.h>
   16 #include "screen.h"
   17 
   18 extern uchar    *vgabios;
   19 
   20 enum {
   21         Qdir,
   22         Qvgactl,
   23         Qvgabios,
   24 };
   25 
   26 static Dirtab vgadir[] = {
   27         ".",    { Qdir, 0, QTDIR },             0,      0550,
   28         "vgactl",       { Qvgactl, 0 },         0,      0660,
   29         "vgabios",      { Qvgabios, 0 },                0x10000,        0440,
   30 };
   31 
   32 static void
   33 vgareset(void)
   34 {
   35         /* reserve the 'standard' vga registers */
   36         if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0)
   37                 panic("vga ports already allocated"); 
   38         if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0)
   39                 panic("vga ports already allocated"); 
   40         conf.monitor = 1;
   41 }
   42 
   43 static Chan*
   44 vgaattach(char* spec)
   45 {
   46         if(*spec && strcmp(spec, ""))
   47                 error(Eio);
   48         return devattach('v', spec);
   49 }
   50 
   51 Walkqid*
   52 vgawalk(Chan* c, Chan *nc, char** name, int nname)
   53 {
   54         return devwalk(c, nc, name, nname, vgadir, nelem(vgadir), devgen);
   55 }
   56 
   57 static int
   58 vgastat(Chan* c, uchar* dp, int n)
   59 {
   60         return devstat(c, dp, n, vgadir, nelem(vgadir), devgen);
   61 }
   62 
   63 static Chan*
   64 vgaopen(Chan* c, int omode)
   65 {
   66         return devopen(c, omode, vgadir, nelem(vgadir), devgen);
   67 }
   68 
   69 static void
   70 vgaclose(Chan*)
   71 {
   72 }
   73 
   74 static void
   75 checkport(int start, int end)
   76 {
   77         /* standard vga regs are OK */
   78         if(start >= 0x2b0 && end <= 0x2df+1)
   79                 return;
   80         if(start >= 0x3c0 && end <= 0x3da+1)
   81                 return;
   82 
   83         if(iounused(start, end))
   84                 return;
   85         error(Eperm);
   86 }
   87 
   88 static long
   89 vgaread(Chan* c, void* a, long n, vlong off)
   90 {
   91         int len;
   92         char *p, *s;
   93         VGAscr *scr;
   94         ulong offset = off;
   95         char chbuf[30];
   96 
   97         switch((ulong)c->qid.path){
   98 
   99         case Qdir:
  100                 return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
  101 
  102         case Qvgactl:
  103                 scr = &vgascreen[0];
  104 
  105                 p = malloc(READSTR);
  106                 if(waserror()){
  107                         free(p);
  108                         nexterror();
  109                 }
  110 
  111                 len = 0;
  112 
  113                 if(scr->dev)
  114                         s = scr->dev->name;
  115                 else
  116                         s = "cga";
  117                 len += snprint(p+len, READSTR-len, "type %s\n", s);
  118 
  119                 if(scr->gscreen) {
  120                         len += snprint(p+len, READSTR-len, "size %dx%dx%d %s\n",
  121                                 scr->gscreen->r.max.x, scr->gscreen->r.max.y,
  122                                 scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan));
  123 
  124                         if(Dx(scr->gscreen->r) != Dx(physgscreenr) 
  125                         || Dy(scr->gscreen->r) != Dy(physgscreenr))
  126                                 len += snprint(p+len, READSTR-len, "actualsize %dx%d\n",
  127                                         physgscreenr.max.x, physgscreenr.max.y);
  128                 }
  129 
  130                 len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
  131                 len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
  132                 len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
  133                 snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->paddr);
  134                 n = readstr(offset, a, n, p);
  135                 poperror();
  136                 free(p);
  137 
  138                 return n;
  139 
  140         case Qvgabios:
  141                 if(vgabios == nil)
  142                         error(Egreg);
  143                 if(offset&0x80000000)
  144                         offset &= ~0x800E0000;
  145                 if(offset+n > 0x10000)
  146                         n = 0x10000-offset;
  147                 if(n < 0)
  148                         return 0;
  149                 memmove(a, vgabios+offset, n);
  150                 return n;
  151 
  152         default:
  153                 error(Egreg);
  154                 break;
  155         }
  156 
  157         return 0;
  158 }
  159 
  160 static char Ebusy[] = "vga already configured";
  161 
  162 static void
  163 vgactl(char* a)
  164 {
  165         int align, i, n, size, x, y, z;
  166         char *chanstr, *field[6], *p;
  167         ulong chan;
  168         VGAscr *scr;
  169         extern VGAdev *vgadev[];
  170         extern VGAcur *vgacur[];
  171         Rectangle r;
  172 
  173         n = tokenize(a, field, nelem(field));
  174         if(n < 1)
  175                 error(Ebadarg);
  176 
  177         scr = &vgascreen[0];
  178         if(strcmp(field[0], "hwgc") == 0){
  179                 if(n < 2)
  180                         error(Ebadarg);
  181 
  182                 if(strcmp(field[1], "off") == 0){
  183                         lock(&cursor);
  184                         if(scr->cur){
  185                                 if(scr->cur->disable)
  186                                         scr->cur->disable(scr);
  187                                 scr->cur = nil;
  188                         }
  189                         unlock(&cursor);
  190                         return;
  191                 }
  192 
  193                 for(i = 0; vgacur[i]; i++){
  194                         if(strcmp(field[1], vgacur[i]->name))
  195                                 continue;
  196                         lock(&cursor);
  197                         if(scr->cur && scr->cur->disable)
  198                                 scr->cur->disable(scr);
  199                         scr->cur = vgacur[i];
  200                         if(scr->cur->enable)
  201                                 scr->cur->enable(scr);
  202                         unlock(&cursor);
  203                         return;
  204                 }
  205         }
  206         else if(strcmp(field[0], "type") == 0){
  207                 if(n < 2)
  208                         error(Ebadarg);
  209 
  210                 for(i = 0; vgadev[i]; i++){
  211                         if(strcmp(field[1], vgadev[i]->name))
  212                                 continue;
  213                         if(scr->dev && scr->dev->disable)
  214                                 scr->dev->disable(scr);
  215                         scr->dev = vgadev[i];
  216                         if(scr->dev->enable)
  217                                 scr->dev->enable(scr);
  218                         return;
  219                 }
  220         }
  221         else if(strcmp(field[0], "size") == 0){
  222                 if(n < 3)
  223                         error(Ebadarg);
  224                 if(drawhasclients())
  225                         error(Ebusy);
  226 
  227                 x = strtoul(field[1], &p, 0);
  228                 if(x == 0 || x > 2048)
  229                         error(Ebadarg);
  230                 if(*p)
  231                         p++;
  232 
  233                 y = strtoul(p, &p, 0);
  234                 if(y == 0 || y > 2048)
  235                         error(Ebadarg);
  236                 if(*p)
  237                         p++;
  238 
  239                 z = strtoul(p, &p, 0);
  240 
  241                 chanstr = field[2];
  242                 if((chan = strtochan(chanstr)) == 0)
  243                         error("bad channel");
  244 
  245                 if(chantodepth(chan) != z)
  246                         error("depth, channel do not match");
  247 
  248                 cursoroff(1);
  249                 deletescreenimage();
  250                 if(screensize(x, y, z, chan))
  251                         error(Egreg);
  252                 vgascreenwin(scr);
  253                 cursoron(1);
  254                 return;
  255         }
  256         else if(strcmp(field[0], "actualsize") == 0){
  257                 if(scr->gscreen == nil)
  258                         error("set the screen size first");
  259 
  260                 if(n < 2)
  261                         error(Ebadarg);
  262                 x = strtoul(field[1], &p, 0);
  263                 if(x == 0 || x > 2048)
  264                         error(Ebadarg);
  265                 if(*p)
  266                         p++;
  267 
  268                 y = strtoul(p, nil, 0);
  269                 if(y == 0 || y > 2048)
  270                         error(Ebadarg);
  271 
  272                 if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y)
  273                         error("physical screen bigger than virtual");
  274 
  275                 r = Rect(0,0,x,y);
  276                 if(!eqrect(r, scr->gscreen->r)){
  277                         if(scr->cur == nil || scr->cur->doespanning == 0)
  278                                 error("virtual screen not supported");
  279                 }
  280 
  281                 physgscreenr = r;
  282                 return;
  283         }
  284         else if(strcmp(field[0], "palettedepth") == 0){
  285                 if(n < 2)
  286                         error(Ebadarg);
  287 
  288                 x = strtoul(field[1], &p, 0);
  289                 if(x != 8 && x != 6)
  290                         error(Ebadarg);
  291 
  292                 scr->palettedepth = x;
  293                 return;
  294         }
  295         else if(strcmp(field[0], "drawinit") == 0){
  296                 if(scr && scr->dev && scr->dev->drawinit)
  297                         scr->dev->drawinit(scr);
  298                 return;
  299         }
  300         else if(strcmp(field[0], "linear") == 0){
  301                 if(n < 2)
  302                         error(Ebadarg);
  303 
  304                 size = strtoul(field[1], 0, 0);
  305                 if(n < 3)
  306                         align = 0;
  307                 else
  308                         align = strtoul(field[2], 0, 0);
  309                 if(screenaperture(size, align))
  310                         error("not enough free address space");
  311                 return;
  312         }
  313 /*      else if(strcmp(field[0], "memset") == 0){
  314                 if(n < 4)
  315                         error(Ebadarg);
  316                 memset((void*)strtoul(field[1], 0, 0), atoi(field[2]), atoi(field[3]));
  317                 return;
  318         }
  319 */
  320         else if(strcmp(field[0], "blank") == 0){
  321                 if(n < 1)
  322                         error(Ebadarg);
  323                 drawblankscreen(1);
  324                 return;
  325         }
  326         else if(strcmp(field[0], "blanktime") == 0){
  327                 if(n < 2)
  328                         error(Ebadarg);
  329                 blanktime = strtoul(field[1], 0, 0);
  330                 return;
  331         }
  332         else if(strcmp(field[0], "hwaccel") == 0){
  333                 if(n < 2)
  334                         error(Ebadarg);
  335                 if(strcmp(field[1], "on") == 0)
  336                         hwaccel = 1;
  337                 else if(strcmp(field[1], "off") == 0)
  338                         hwaccel = 0;
  339                 return;
  340         }
  341         else if(strcmp(field[0], "hwblank") == 0){
  342                 if(n < 2)
  343                         error(Ebadarg);
  344                 if(strcmp(field[1], "on") == 0)
  345                         hwblank = 1;
  346                 else if(strcmp(field[1], "off") == 0)
  347                         hwblank = 0;
  348                 return;
  349         }
  350 
  351         error(Ebadarg);
  352 }
  353 
  354 static long
  355 vgawrite(Chan* c, void* a, long n, vlong off)
  356 {
  357         char *p;
  358         ulong offset = off;
  359 
  360         switch((ulong)c->qid.path){
  361 
  362         case Qdir:
  363                 error(Eperm);
  364 
  365         case Qvgactl:
  366                 if(offset || n >= READSTR)
  367                         error(Ebadarg);
  368                 p = malloc(READSTR);
  369                 if(waserror()){
  370                         free(p);
  371                         nexterror();
  372                 }
  373                 memmove(p, a, n);
  374                 p[n] = 0;
  375                 vgactl(p);
  376                 poperror();
  377                 free(p);
  378                 return n;
  379 
  380         default:
  381                 error(Egreg);
  382                 break;
  383         }
  384 
  385         return 0;
  386 }
  387 
  388 Dev vgadevtab = {
  389         'v',
  390         "vga",
  391 
  392         vgareset,
  393         devinit,        
  394         devshutdown,
  395         vgaattach,
  396         vgawalk,
  397         vgastat,
  398         vgaopen,
  399         devcreate,
  400         vgaclose,
  401         vgaread,
  402         devbread,
  403         vgawrite,
  404         devbwrite,
  405         devremove,
  406         devwstat,
  407 };

Cache object: 656b79e5b202dfe2739095d51c2e2934


[ 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.