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);
+}
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);