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/bios32.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 
    8 #define VFLAG(...)      if(vflag) print(__VA_ARGS__)
    9 
   10 #define BIOSSEG(a)      KADDR(((uint)(a))<<4)
   11 #define UPTR2INT(p)     ((uintptr)(p))
   12 
   13 #define l16get(p)       (((p)[1]<<8)|(p)[0])
   14 #define l32get(p)       (((u32int)l16get(p+2)<<16)|l16get(p))
   15 
   16 static int vflag = 0;
   17 
   18 typedef struct BIOS32sdh {              /* BIOS32 Service Directory Header */
   19         u8int   signature[4];           /* "_32_" */
   20         u8int   physaddr[4];            /* physical address of entry point */
   21         u8int   revision;
   22         u8int   length;                 /* of header in paragraphs */
   23         u8int   checksum;               /* */
   24         u8int   reserved[5];
   25 } BIOS32sdh;
   26 
   27 typedef struct BIOS32si {               /* BIOS32 Service Interface */
   28         u8int*  base;                   /* base address of service */
   29         int     length;                 /* length of service */
   30         u32int  offset;                 /* service entry-point from base */
   31 
   32         u16int  ptr[3];                 /* far pointer m16:32 */
   33 } BIOS32si;
   34 
   35 static Lock bios32lock;
   36 static u16int bios32ptr[3];
   37 static void* bios32entry;
   38 
   39 int
   40 bios32ci(BIOS32si* si, BIOS32ci* ci)
   41 {
   42         int r;
   43 
   44         lock(&bios32lock);
   45         r = bios32call(ci, si->ptr);
   46         unlock(&bios32lock);
   47 
   48         return r;
   49 }
   50 
   51 static void*
   52 rsdchecksum(void* addr, int length)
   53 {
   54         u8int *p, sum;
   55 
   56         sum = 0;
   57         for(p = addr; length-- > 0; p++)
   58                 sum += *p;
   59         if(sum == 0)
   60                 return addr;
   61 
   62         return nil;
   63 }
   64 
   65 static void*
   66 rsdscan(u8int* addr, int len, char* signature)
   67 {
   68         int sl;
   69         u8int *e, *p;
   70 
   71         e = addr+len;
   72         sl = strlen(signature);
   73         for(p = addr; p+sl < e; p += 16){
   74                 if(memcmp(p, signature, sl))
   75                         continue;
   76                 return p;
   77         }
   78 
   79         return nil;
   80 }
   81 
   82 static int
   83 bios32locate(void)
   84 {
   85         uintptr ptr;
   86         BIOS32sdh *sdh;
   87 
   88         VFLAG("bios32link\n");
   89         if((sdh = rsdscan(BIOSSEG(0xE000), 0x20000, "_32_")) == nil)
   90                 return -1;
   91         if(rsdchecksum(sdh, sizeof(BIOS32sdh)) == nil)
   92                 return -1;
   93         VFLAG("sdh @ %#p, entry %#ux\n", sdh, l32get(sdh->physaddr));
   94 
   95         bios32entry = vmap(l32get(sdh->physaddr), 4096+1);
   96         VFLAG("entry @ %#p\n", bios32entry);
   97         ptr = UPTR2INT(bios32entry);
   98         bios32ptr[0] = ptr & 0xffff;
   99         bios32ptr[1] = (ptr>>16) & 0xffff;
  100         bios32ptr[2] = KESEL;
  101         VFLAG("bios32link: ptr %ux %ux %ux\n",
  102                 bios32ptr[0], bios32ptr[1], bios32ptr[2]);
  103 
  104         return 0;
  105 }
  106 
  107 void
  108 BIOS32close(BIOS32si* si)
  109 {
  110         vunmap(si->base, si->length);
  111         free(si);
  112 }
  113 
  114 BIOS32si*
  115 bios32open(char* id)
  116 {
  117         uint ptr;
  118         BIOS32ci ci;
  119         BIOS32si *si;
  120 
  121         lock(&bios32lock);
  122         if(bios32ptr[2] == 0 && bios32locate() < 0){
  123                 unlock(&bios32lock);
  124                 return nil;
  125         }
  126 
  127         VFLAG("bios32si: %s\n", id);
  128         memset(&ci, 0, sizeof(BIOS32ci));
  129         ci.eax = (id[3]<<24|(id[2]<<16)|(id[1]<<8)|id[0]);
  130 
  131         bios32call(&ci, bios32ptr);
  132         unlock(&bios32lock);
  133 
  134         VFLAG("bios32si: eax %ux\n", ci.eax);
  135         if(ci.eax & 0xff)
  136                 return nil;
  137         VFLAG("bios32si: base %#ux length %#ux offset %#ux\n",
  138                 ci.ebx, ci.ecx, ci.edx);
  139 
  140         if((si = malloc(sizeof(BIOS32si))) == nil)
  141                 return nil;
  142         if((si->base = vmap(ci.ebx, ci.ecx)) == nil){
  143                 free(si);
  144                 return nil;
  145         }
  146         si->length = ci.ecx;
  147 
  148         ptr = UPTR2INT(si->base)+ci.edx;
  149         si->ptr[0] = ptr & 0xffff;
  150         si->ptr[1] = (ptr>>16) & 0xffff;
  151         si->ptr[2] = KESEL;
  152         VFLAG("bios32si: eax entry %ux\n", ptr);
  153 
  154         return si;
  155 }

Cache object: 560dbbd32538c0aa3af694831d0a07f7


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