Files
xen/tools/firmware/hvmloader/util.c
T
kaf24@localhost.localdomain 10a74ed0a2 [HVM] [SMBIOS] Duplicate UUID into serial number in SMBIOS tables.
Windows zeroes out the UUID in the SMBIOS tables, but the identifier
is often needed by systems management code.  Duplicating the UUID
as the virtual system's serial number should help.

Signed-off-by: Andrew D. Ball <aball@us.ibm.com>
2006-08-28 12:59:07 +01:00

231 lines
4.1 KiB
C

/*
* util.c: Helper library functions for HVMLoader.
*
* Leendert van Doorn, leendert@watson.ibm.com
* Copyright (c) 2005, International Business Machines Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
#include "../acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */
#include "util.h"
#include <stdint.h>
void outw(uint16_t addr, uint16_t val)
{
__asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
}
void outb(uint16_t addr, uint8_t val)
{
__asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
}
uint8_t inb(uint16_t addr)
{
uint8_t val;
__asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
return val;
}
char *itoa(char *a, unsigned int i)
{
unsigned int _i = i, x = 0;
do {
x++;
_i /= 10;
} while (_i != 0);
a += x;
*a-- = '\0';
do {
*a-- = (i % 10) + '0';
i /= 10;
} while (i != 0);
return a + 1;
}
int strcmp(const char *cs, const char *ct)
{
signed char res;
while (((res = *cs - *ct++) == 0) && (*cs++ != '\0'))
continue;
return res;
}
void *memcpy(void *dest, const void *src, unsigned n)
{
int t0, t1, t2;
__asm__ __volatile__(
"cld\n"
"rep; movsl\n"
"testb $2,%b4\n"
"je 1f\n"
"movsw\n"
"1: testb $1,%b4\n"
"je 2f\n"
"movsb\n"
"2:"
: "=&c" (t0), "=&D" (t1), "=&S" (t2)
: "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
: "memory"
);
return dest;
}
void puts(const char *s)
{
while (*s)
outb(0xE9, *s++);
}
char *
strcpy(char *dest, const char *src)
{
char *p = dest;
while (*src)
*p++ = *src++;
*p = 0;
return dest;
}
char *
strncpy(char *dest, const char *src, unsigned n)
{
int i = 0;
char *p = dest;
/* write non-NUL characters from src into dest until we run
out of room in dest or encounter a NUL in src */
while (i < n && *src) {
*p++ = *src++;
++i;
}
/* pad remaining bytes of dest with NUL bytes */
while (i < n) {
*p++ = 0;
++i;
}
return dest;
}
unsigned
strlen(const char *s)
{
int i = 0;
while (*s++)
++i;
return i;
}
void *
memset(void *s, int c, unsigned n)
{
uint8_t b = (uint8_t) c;
uint8_t *p = (uint8_t *)s;
int i;
for (i = 0; i < n; ++i)
*p++ = b;
return s;
}
int
memcmp(const void *s1, const void *s2, unsigned n)
{
unsigned i;
uint8_t *p1 = (uint8_t *) s1;
uint8_t *p2 = (uint8_t *) s2;
for (i = 0; i < n; ++i) {
if (p1[i] < p2[i])
return -1;
else if (p1[i] > p2[i])
return 1;
}
return 0;
}
void
cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
__asm__ __volatile__(
"cpuid"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (idx) );
}
/* Write a two-character hex representation of 'byte' to digits[].
Pre-condition: sizeof(digits) >= 2 */
void
byte_to_hex(char *digits, uint8_t byte)
{
uint8_t nybbel = byte >> 4;
if (nybbel > 9)
digits[0] = 'a' + nybbel-10;
else
digits[0] = '0' + nybbel;
nybbel = byte & 0x0f;
if (nybbel > 9)
digits[1] = 'a' + nybbel-10;
else
digits[1] = '0' + nybbel;
}
/* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID
string.
Pre-condition: sizeof(dest) >= 37 */
void
uuid_to_string(char *dest, uint8_t *uuid)
{
int i = 0;
char *p = dest;
for (i = 0; i < 4; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 4; i < 6; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 6; i < 8; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 8; i < 10; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 10; i < 16; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
}