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/realmode.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        "tos.h"
    3 #include        "../port/lib.h"
    4 #include        "mem.h"
    5 #include        "dat.h"
    6 #include        "fns.h"
    7 #include        "io.h"
    8 #include        "ureg.h"
    9 #include        "../port/error.h"
   10 
   11 /*
   12  * Back the processor into real mode to run a BIOS call,
   13  * then return.  This must be used carefully, since it 
   14  * completely disables hardware interrupts (e.g., the i8259)
   15  * while running.  It is *not* using VM86 mode. 
   16  * Maybe that's really the right answer, but real mode
   17  * is fine for now.  We don't expect to use this very much --
   18  * just for VGA and APM.
   19  */
   20 #define realmoderegs (*(Ureg*)RMUADDR)
   21 
   22 #define LORMBUF (RMBUF-KZERO)
   23 
   24 static Ureg rmu;
   25 static Lock rmlock;
   26 
   27 void
   28 realmode(Ureg *ureg)
   29 {
   30         int s;
   31         ulong cr3;
   32         extern void realmode0(void);    /* in l.s */
   33         extern void i8259off(void), i8259on(void);
   34 
   35         if(getconf("*norealmode"))
   36                 return;
   37 
   38         lock(&rmlock);
   39         realmoderegs = *ureg;
   40 
   41         /* copy l.s so that it can be run from 16-bit mode */
   42         memmove((void*)RMCODE, (void*)KTZERO, 0x1000);
   43 
   44         s = splhi();
   45         m->pdb[PDX(0)] = m->pdb[PDX(KZERO)];    /* identity map low */
   46         cr3 = getcr3();
   47         putcr3(PADDR(m->pdb));
   48         i8259off();
   49         realmode0();
   50         if(m->tss){
   51                 /*
   52                  * Called from memory.c before initialization of mmu.
   53                  * Don't turn interrupts on before the kernel is ready!
   54                  */
   55                 i8259on();
   56         }
   57         m->pdb[PDX(0)] = 0;     /* remove low mapping */
   58         putcr3(cr3);
   59         splx(s);
   60         *ureg = realmoderegs;
   61         unlock(&rmlock);
   62 }
   63 
   64 static long
   65 rtrapread(Chan*, void *a, long n, vlong off)
   66 {
   67         if(off < 0)
   68                 error("badarg");
   69         if(n+off > sizeof rmu)
   70                 n = sizeof rmu - off;
   71         if(n <= 0)
   72                 return 0;
   73         memmove(a, (char*)&rmu+off, n);
   74         return n;
   75 }
   76 
   77 static long
   78 rtrapwrite(Chan*, void *a, long n, vlong off)
   79 {
   80         if(off || n != sizeof rmu)
   81                 error("write a Ureg");
   82         memmove(&rmu, a, sizeof rmu);
   83         /*
   84          * Sanity check
   85          */
   86         if(rmu.trap == 0x10){   /* VBE */
   87                 rmu.es = (LORMBUF>>4)&0xF000;
   88                 rmu.di = LORMBUF&0xFFFF;
   89         }else
   90                 error("invalid trap arguments");
   91         realmode(&rmu);
   92         return n;
   93 }
   94 
   95 static long
   96 rmemrw(int isr, void *a, long n, vlong off)
   97 {
   98         if(off >= 1024*1024 || off+n >= 1024*1024)
   99                 return 0;
  100         if(off < 0 || n < 0)
  101                 error("bad offset/count");
  102         if(isr)
  103                 memmove(a, KADDR((ulong)off), n);
  104         else{
  105                 /* writes are more restricted */
  106                 if(LORMBUF <= off && off < LORMBUF+BY2PG
  107                 && off+n <= LORMBUF+BY2PG)
  108                         {}
  109                 else
  110                         error("bad offset/count in write");
  111                 memmove(KADDR((ulong)off), a, n);
  112         }
  113         return n;
  114 }
  115 
  116 static long
  117 rmemread(Chan*, void *a, long n, vlong off)
  118 {
  119         return rmemrw(1, a, n, off);
  120 }
  121 
  122 static long
  123 rmemwrite(Chan*, void *a, long n, vlong off)
  124 {
  125         return rmemrw(0, a, n, off);
  126 }
  127 
  128 void
  129 realmodelink(void)
  130 {
  131         addarchfile("realmode", 0660, rtrapread, rtrapwrite);
  132         addarchfile("realmodemem", 0660, rmemread, rmemwrite);
  133 }
  134 

Cache object: ecde8f442c617d152b52b16c706eba5b


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