pc32 bios - Add bios_oem_strings from FreeBSD
authorAlex Hornung <ahornung@gmail.com>
Fri, 2 Oct 2009 21:02:19 +0000 (22:02 +0100)
committerAlex Hornung <ahornung@gmail.com>
Sun, 4 Oct 2009 13:02:41 +0000 (14:02 +0100)
* Import bios_oem_strings to search for specific strings in the BIOS to
  identify vendors.

Obtained-from: FreeBSD

sys/platform/pc32/i386/bios.c
sys/platform/pc32/include/pc/bios.h

index 16f51c7..86fa7cc 100644 (file)
@@ -451,3 +451,81 @@ bios16(struct bios_args *args, char *fmt, ...)
     cpu_invltlb();
     return (i);
 }
+
+int
+bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen)
+{
+       size_t idx = 0;
+       struct bios_oem_signature *sig;
+       u_int from, to;
+       u_char c, *s, *se, *str, *bios_str;
+       size_t i, off, len, tot;
+
+       if ( !oem || !buffer || maxlen<2 )
+               return(-1);
+
+       sig = oem->signature;
+       if (!sig)
+               return(-2);
+
+       from = oem->range.from;
+       to = oem->range.to;
+       if ( (to<=from) || (from<BIOS_START) || (to>(BIOS_START+BIOS_SIZE)) )
+               return(-3);
+
+       while (sig->anchor != NULL) {
+               str = sig->anchor;
+               len = strlen(str);
+               off = sig->offset;
+               tot = sig->totlen;
+               /* make sure offset doesn't go beyond bios area */
+               if ( (to+off)>(BIOS_START+BIOS_SIZE) ||
+                                       ((from+off)<BIOS_START) ) {
+                       kprintf("sys/i386/i386/bios.c: sig '%s' "
+                               "from 0x%0x to 0x%0x offset %d "
+                               "out of BIOS bounds 0x%0x - 0x%0x\n",
+                               str, from, to, off,
+                               BIOS_START, BIOS_START+BIOS_SIZE);
+                       return(-4);
+               }
+               /* make sure we don't overrun return buffer */
+               if (idx + tot > maxlen - 1) {
+                       kprintf("sys/i386/i386/bios.c: sig '%s' "
+                               "idx %d + tot %d = %d > maxlen-1 %d\n",
+                               str, idx, tot, idx+tot, maxlen-1);
+                       return(-5);
+               }
+               bios_str = NULL;
+               s = (u_char *)BIOS_PADDRTOVADDR(from);
+               se = (u_char *)BIOS_PADDRTOVADDR(to-len);
+               for (; s<se; s++) {
+                       if (!bcmp(str, s, len)) {
+                               bios_str = s;
+                               break;
+                       }
+               }
+               /*
+               *  store pretty version of totlen bytes of bios string with
+               *  given offset; 0x20 - 0x7E are printable; uniquify spaces
+               */
+               if (bios_str) {
+                       for (i=0; i<tot; i++) {
+                               c = bios_str[i+off];
+                               if ( (c < 0x20) || (c > 0x7E) )
+                                       c = ' ';
+                               if (idx == 0) {
+                                       if (c != ' ')
+                                               buffer[idx++] = c;
+                               } else if ( (c != ' ') ||
+                                       ((c == ' ') && (buffer[idx-1] != ' ')) )
+                                               buffer[idx++] = c;
+                       }
+               }
+               sig++;
+       }
+       /* remove a final trailing space */
+       if ( (idx > 1) && (buffer[idx-1] == ' ') )
+               idx--;
+       buffer[idx] = '\0';
+       return (idx);
+}
index 8c73600..13c443d 100644 (file)
@@ -295,3 +295,20 @@ struct bios_smap {
     u_int64_t  length;
     u_int32_t  type;
 } __attribute__ ((packed));
+
+struct bios_oem_signature {
+       char * anchor;          /* search anchor string in BIOS memory */
+       size_t offset;          /* offset from anchor (may be negative) */
+       size_t totlen;          /* total length of BIOS string to copy */
+} __packed;
+struct bios_oem_range {
+       u_int from;             /* shouldn't be below 0xe0000 */
+       u_int to;               /* shouldn't be above 0xfffff */
+} __packed;
+struct bios_oem {
+       struct bios_oem_range range;
+       struct bios_oem_signature signature[];
+} __packed;
+
+extern int
+bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);