uint32_t tcg_hash_extend(uint32_t addr, uint32_t len, uint32_t pcr) { struct TCG_HashAll tcg_hash_all; struct TCG_PassTroughtToTPM tcg_passtrough_to_tpm; char _unused[0x22]; tcg_hash_all.ipb_length = 0x0010; tcg_hash_all._reserved = 0x0000; tcg_hash_all.hash_data_ptr = addr; tcg_hash_all.hash_data_len = len; tcg_hash_all.algorithm_id = TPM_ALGO_SHA1; tcg_passtrough_to_tpm.ipb_length = 0x002a; tcg_passtrough_to_tpm._reserved1 = 0x0000; tcg_passtrough_to_tpm.opb_length = 0x0022; tcg_passtrough_to_tpm._reserved2 = 0x0000; tcg_passtrough_to_tpm.tpm_tag = __htons(TPM_TAG_RQU_COMMAND); tcg_passtrough_to_tpm.input_size = __htonl(0x00000022); tcg_passtrough_to_tpm.cmd_ordinal = __htonl(TPM_ORD_Extend); tcg_passtrough_to_tpm.pcr = __htonl(pcr); v86.addr = 0x1a; v86.eax = 0xbb05; v86.ebx = TCG_MAGIC; v86.ecx = 0x00000000; v86.edx = 0x00000000; v86.es = VTOPSEG(&tcg_hash_all); v86.edi = VTOPOFF(&tcg_hash_all); v86.ds = VTOPSEG(&tcg_passtrough_to_tpm.hash); v86.esi = VTOPOFF(&tcg_passtrough_to_tpm.hash); v86int(); if (v86.eax != TCG_PC_OK) return (v86.eax); v86.addr = 0x1a; v86.eax = 0xbb02; v86.ebx = TCG_MAGIC; v86.ecx = 0x00000000; v86.edx = 0x00000000; v86.es = VTOPSEG(&tcg_passtrough_to_tpm); v86.edi = VTOPOFF(&tcg_passtrough_to_tpm); v86.ds = VTOPSEG(&_unused); v86.esi = VTOPOFF(&_unused); v86int(); return (v86.eax); }
/* Caller must leave room for ethernet, ip, and udp headers in front!! */ ssize_t pxesendudp(struct iodesc *d, void *pkt, size_t len) { t_PXENV_UDP_WRITE *uw = (void *) pxe_command_buf; uw->status = 0; uw->ip = d->destip.s_addr; uw->gw = gateip.s_addr; uw->src_port = d->myport; uw->dst_port = d->destport; uw->buffer_size = len; uw->buffer.segment = VTOPSEG(pkt); uw->buffer.offset = VTOPOFF(pkt); pxe_call(PXENV_UDP_WRITE); if (uw->status != PXENV_STATUS_SUCCESS) { /* XXX This happens a lot; it shouldn't. */ if (uw->status != PXENV_STATUS_FAILURE) printf("sendudp: PXENV_UDP_WRITE failed: 0x%x\n", uw->status); return -1; } return len; }
void bios_getsmap(void) { int n; n = 0; smaplen = 0; /* Count up segments in system memory map */ v86.ebx = 0; do { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe820*/ v86.eax = 0xe820; v86.ecx = sizeof(struct smap); v86.edx = SMAPSIG; v86.es = VTOPSEG(&smap); v86.edi = VTOPOFF(&smap); v86int(); if ((v86.efl & 1) || (v86.eax != SMAPSIG)) break; n++; } while (v86.ebx != 0); if (n == 0) return; n += 10; /* spare room */ smapbase = malloc(n * sizeof(*smapbase)); /* Save system memory map */ v86.ebx = 0; do { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe820*/ v86.eax = 0xe820; v86.ecx = sizeof(struct smap); v86.edx = SMAPSIG; v86.es = VTOPSEG(&smapbase[smaplen]); v86.edi = VTOPOFF(&smapbase[smaplen]); v86int(); smaplen++; if ((v86.efl & 1) || (v86.eax != SMAPSIG)) break; } while (v86.ebx != 0 && smaplen < n); }
/* * Return the BIOS time-of-day value. * * XXX uses undocumented BCD support from libstand. */ static int bios_seconds(void) { int hr, minute, sec; unsigned char bios_time[6]; v86.ctl = 0; v86.addr = 0x1c; /* int 0x1c, function 0 */ v86.eax = 0x0000; v86.es = VTOPSEG(bios_time); v86.ebx = VTOPOFF(bios_time); v86int(); hr = bcd2bin(bios_time[3]); minute = bcd2bin(bios_time[4]); sec = bcd2bin(bios_time[5]); return (hr * 3600 + minute * 60 + sec); }
time_t time(time_t *t) { static time_t lasttime, now; int hr, min, sec; #ifdef PC98 unsigned char bios_time[6]; #endif v86.ctl = 0; #ifdef PC98 v86.addr = 0x1c; /* int 0x1c, function 0 */ v86.eax = 0x0000; v86.es = VTOPSEG(bios_time); v86.ebx = VTOPOFF(bios_time); #else v86.addr = 0x1a; /* int 0x1a, function 2 */ v86.eax = 0x0200; #endif v86int(); #ifdef PC98 hr = bcd2bin(bios_time[3]); min = bcd2bin(bios_time[4]); sec = bcd2bin(bios_time[5]); #else hr = bcd2bin((v86.ecx & 0xff00) >> 8); /* hour in %ch */ min = bcd2bin(v86.ecx & 0xff); /* minute in %cl */ sec = bcd2bin((v86.edx & 0xff00) >> 8); /* second in %dh */ #endif now = hr * 3600 + min * 60 + sec; if (now < lasttime) now += 24 * 3600; lasttime = now; if (t != NULL) *t = now; return(now); }
/* * Receive a UDP packet and validate it for us. * Caller leaves room for the headers (Ether, IP, UDP). */ ssize_t pxereadudp(struct iodesc *d, void *pkt, size_t len, time_t tleft) { t_PXENV_UDP_READ *ur = (void *) pxe_command_buf; struct udphdr *uh; struct ip *ip; uh = (struct udphdr *)pkt - 1; ip = (struct ip *)uh - 1; bzero(ur, sizeof(*ur)); ur->dest_ip = d->myip.s_addr; ur->d_port = d->myport; ur->buffer_size = len; ur->buffer.segment = VTOPSEG(pkt); ur->buffer.offset = VTOPOFF(pkt); /* XXX Timeout unused. */ pxe_call(PXENV_UDP_READ); if (ur->status != PXENV_STATUS_SUCCESS) { /* XXX This happens a lot; it shouldn't. */ if (ur->status != PXENV_STATUS_FAILURE) printf("readudp: PXENV_UDP_READ_failed: 0x%0x\n", ur->status); return -1; } ip->ip_src.s_addr = ur->src_ip; uh->uh_sport = ur->s_port; uh->uh_dport = d->myport; return ur->buffer_size; }
void bios_getmem(void) { uint64_t size; /* Parse system memory map */ v86.ebx = 0; do { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe820*/ v86.eax = 0xe820; v86.ecx = sizeof(struct bios_smap_xattr); v86.edx = SMAP_SIG; v86.es = VTOPSEG(&smap); v86.edi = VTOPOFF(&smap); v86int(); if ((V86_CY(v86.efl)) || (v86.eax != SMAP_SIG)) break; /* look for a low-memory segment that's large enough */ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && (smap.length >= (512 * 1024))) { bios_basemem = smap.length; b_bios_probed |= B_BASEMEM_E820; } /* look for the first segment in 'extended' memory */ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000) && !(bios_getquirks() & BQ_DISTRUST_E820_EXTMEM)) { bios_extmem = smap.length; b_bios_probed |= B_EXTMEM_E820; } /* * Look for the largest segment in 'extended' memory beyond * 1MB but below 4GB. */ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && (smap.base < 0x100000000ull)) { size = smap.length; /* * If this segment crosses the 4GB boundary, truncate it. */ if (smap.base + size > 0x100000000ull) size = 0x100000000ull - smap.base; if (size > high_heap_size) { high_heap_size = size; high_heap_base = smap.base; } } } while (v86.ebx != 0); /* Fall back to the old compatibility function for base memory */ if (bios_basemem == 0) { v86.ctl = 0; v86.addr = 0x12; /* int 0x12 */ v86int(); bios_basemem = (v86.eax & 0xffff) * 1024; b_bios_probed |= B_BASEMEM_12; } /* Fall back through several compatibility functions for extended memory */ if (bios_extmem == 0) { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe801*/ v86.eax = 0xe801; v86int(); if (!(V86_CY(v86.efl))) { /* * Clear high_heap; it may end up overlapping * with the segment we're determining here. * Let the default "steal stuff from top of * bios_extmem" code below pick up on it. */ high_heap_size = 0; high_heap_base = 0; /* * %cx is the number of 1KiB blocks between 1..16MiB. * It can only be up to 0x3c00; if it's smaller then * there's a PC AT memory hole so we can't treat * it as contiguous. */ bios_extmem = (v86.ecx & 0xffff) * 1024; if (bios_extmem == (1024 * 0x3c00)) bios_extmem += (v86.edx & 0xffff) * 64 * 1024; /* truncate bios_extmem */ if (bios_extmem > 0x3ff00000) bios_extmem = 0x3ff00000; b_bios_probed |= B_EXTMEM_E801; } } if (bios_extmem == 0) { v86.ctl = 0; v86.addr = 0x15; /* int 0x15 function 0x88*/ v86.eax = 0x8800; v86int(); bios_extmem = (v86.eax & 0xffff) * 1024; b_bios_probed |= B_EXTMEM_8800; } /* Set memtop to actual top of memory */ memtop = memtop_copyin = 0x100000 + bios_extmem; /* * If we have extended memory and did not find a suitable heap * region in the SMAP, use the last 3MB of 'extended' memory as a * high heap candidate. */ if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { high_heap_size = HEAP_MIN; high_heap_base = memtop - HEAP_MIN; } }
void bios_getmem(void) { uint64_t size; /* Parse system memory map */ v86.ebx = 0; do { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe820*/ v86.eax = 0xe820; v86.ecx = sizeof(struct bios_smap); v86.edx = SMAP_SIG; v86.es = VTOPSEG(&smap); v86.edi = VTOPOFF(&smap); v86int(); if ((V86_CY(v86.efl)) || (v86.eax != SMAP_SIG)) break; /* look for a low-memory segment that's large enough */ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && (smap.length >= (512 * 1024))) bios_basemem = smap.length; /* look for the first segment in 'extended' memory */ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) { bios_extmem = smap.length; } /* * Look for the largest segment in 'extended' memory beyond * 1MB but below 4GB. */ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && (smap.base < 0x100000000ull)) { size = smap.length; /* * If this segment crosses the 4GB boundary, truncate it. */ if (smap.base + size > 0x100000000ull) size = 0x100000000ull - smap.base; if (size > high_heap_size) { high_heap_size = size; high_heap_base = smap.base; } } } while (v86.ebx != 0); /* Fall back to the old compatibility function for base memory */ if (bios_basemem == 0) { v86.ctl = 0; v86.addr = 0x12; /* int 0x12 */ v86int(); bios_basemem = (v86.eax & 0xffff) * 1024; } /* Fall back through several compatibility functions for extended memory */ if (bios_extmem == 0) { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe801*/ v86.eax = 0xe801; v86int(); if (!(V86_CY(v86.efl))) { bios_extmem = ((v86.ecx & 0xffff) + ((v86.edx & 0xffff) * 64)) * 1024; } } if (bios_extmem == 0) { v86.ctl = 0; v86.addr = 0x15; /* int 0x15 function 0x88*/ v86.eax = 0x8800; v86int(); bios_extmem = (v86.eax & 0xffff) * 1024; } /* Set memtop to actual top of memory */ memtop = memtop_copyin = 0x100000 + bios_extmem; /* * If we have extended memory and did not find a suitable heap * region in the SMAP, use the last 3MB of 'extended' memory as a * high heap candidate. */ if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { high_heap_size = HEAP_MIN; high_heap_base = memtop - HEAP_MIN; } }
void bios_getsmap(void) { struct smap_buf buf; STAILQ_HEAD(smap_head, smap_buf) head = STAILQ_HEAD_INITIALIZER(head); struct smap_buf *cur, *next; u_int n, x; STAILQ_INIT(&head); n = 0; x = 0; v86.ebx = 0; do { v86.ctl = V86_FLAGS; v86.addr = 0x15; v86.eax = 0xe820; /* int 0x15 function 0xe820 */ v86.ecx = SMAP_BUFSIZE; v86.edx = SMAP_SIG; v86.es = VTOPSEG(&buf); v86.edi = VTOPOFF(&buf); v86int(); if (V86_CY(v86.efl) || v86.eax != SMAP_SIG || v86.ecx < sizeof(buf.smap) || v86.ecx > SMAP_BUFSIZE) break; next = malloc(sizeof(*next)); if (next == NULL) break; next->smap = buf.smap; if (v86.ecx == SMAP_BUFSIZE) { next->xattr = buf.xattr; x++; } STAILQ_INSERT_TAIL(&head, next, bufs); n++; } while (v86.ebx != 0); smaplen = n; if (smaplen > 0) { smapbase = malloc(smaplen * sizeof(*smapbase)); if (smapbase != NULL) { n = 0; STAILQ_FOREACH(cur, &head, bufs) smapbase[n++] = cur->smap; } if (smaplen == x) { smapattr = malloc(smaplen * sizeof(*smapattr)); if (smapattr != NULL) { n = 0; STAILQ_FOREACH(cur, &head, bufs) smapattr[n++] = cur->xattr & SMAP_XATTR_MASK; } } else smapattr = NULL; cur = STAILQ_FIRST(&head); while (cur != NULL) { next = STAILQ_NEXT(cur, bufs); free(cur); cur = next; } } }
void bios_getsmap(void) { int n; n = 0; smaplen = 0; /* Count up segments in system memory map */ v86.ebx = 0; do { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe820*/ v86.eax = 0xe820; v86.ecx = sizeof(struct smap); v86.edx = SMAPSIG; v86.es = VTOPSEG(&smap); v86.edi = VTOPOFF(&smap); v86int(); if ((v86.efl & 1) || (v86.eax != SMAPSIG)) break; n++; } while (v86.ebx != 0); if (n == 0) return; n += 10; /* spare room */ smapbase = malloc(n * sizeof(*smapbase)); /* Save system memory map */ v86.ebx = 0; do { v86.ctl = V86_FLAGS; v86.addr = 0x15; /* int 0x15 function 0xe820*/ v86.eax = 0xe820; v86.ecx = sizeof(struct smap); v86.edx = SMAPSIG; v86.es = VTOPSEG(&smap); v86.edi = VTOPOFF(&smap); v86int(); /* * Our heap is now in high memory and must be removed from * the smap so the kernel does not blow away passed-in * arguments, smap, kenv, etc. * * This wastes a little memory. */ if (smap.type == 1 && smap.base + smap.length > heapbase && smap.base < memtop) { if (smap.base <= heapbase) { if (heapbase - smap.base) { smapbase[smaplen] = smap; smapbase[smaplen].length = heapbase - smap.base; ++smaplen; } } if (smap.base + smap.length >= memtop) { if (smap.base + smap.length - memtop) { smapbase[smaplen] = smap; smapbase[smaplen].base = memtop; smapbase[smaplen].length = smap.base + smap.length - memtop; ++smaplen; } } } else { smapbase[smaplen] = smap; ++smaplen; } if ((v86.efl & 1) || (v86.eax != SMAPSIG)) break; } while (v86.ebx != 0 && smaplen < n); }