⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 xen 3.2.2 源码
💻 C
字号:
/* * util.c: Commonly used utility functions. * * 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 <stdarg.h>#include "util.h"#include "machine.h"#define	isdigit(c)	((c) >= '0' && (c) <= '9')#define	min(a, b)	((a) < (b) ? (a) : (b))static void putchar(int);static char *printnum(char *, unsigned long, int);static void _doprint(void (*)(int), const char *, va_list);voidcpuid_addr_value(uint64_t addr, uint64_t *value){	uint32_t addr_low   = (uint32_t)addr;	uint32_t addr_high  = (uint32_t)(addr >> 32);	uint32_t value_low, value_high;	static unsigned int addr_leaf;	if (!addr_leaf) {		unsigned int eax, ebx, ecx, edx;		__asm__ __volatile__(			"cpuid"			: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)			: "0" (0x40000000));		addr_leaf = eax + 1;	}	__asm__ __volatile__(		"cpuid"		: "=c" (value_low), "=d" (value_high)		: "a" (addr_leaf), "0" (addr_low), "1" (addr_high)		: "ebx");	*value = (uint64_t)value_high << 32 | value_low;}voiddump_regs(struct regs *regs){	printf("eax    %8x ecx    %8x edx    %8x ebx    %8x\n",		regs->eax, regs->ecx, regs->edx, regs->ebx);	printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",		regs->esp, regs->ebp, regs->esi, regs->edi);	printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);	printf("eip    %8x cs     %8x eflags %8x\n",		regs->eip, regs->cs, regs->eflags);	printf("uesp   %8x uss    %8x\n",		regs->uesp, regs->uss);	printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",		regs->ves, regs->vds, regs->vfs, regs->vgs);	printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n\n",		(long)oldctx.cr0, get_cr2(),		(long)oldctx.cr3, (long)oldctx.cr4);}#ifdef DEBUGvoidhexdump(unsigned char *data, int sz){	unsigned char *d;	int i;	for (d = data; sz > 0; d += 16, sz -= 16) {		int n = sz > 16 ? 16 : sz;		printf("%08x: ", (unsigned)d);		for (i = 0; i < n; i++)			printf("%02x%c", d[i], i == 7 ? '-' : ' ');		for (; i < 16; i++)			printf("  %c", i == 7 ? '-' : ' ');		printf("   ");		for (i = 0; i < n; i++)			printf("%c", d[i] >= ' ' && d[i] <= '~' ? d[i] : '.');		printf("\n");	}}voidprint_e820_map(struct e820entry *map, int entries){	struct e820entry *m;	if (entries > 32)		entries = 32;	for (m = map; m < &map[entries]; m++) {		printf("%08lx%08lx - %08lx%08lx ",			(unsigned long) (m->addr >> 32),			(unsigned long) (m->addr),			(unsigned long) ((m->addr+m->size) >> 32),			(unsigned long) ((m->addr+m->size)));		switch (m->type) {		case E820_RAM:			printf("(RAM)\n"); break;		case E820_RESERVED:			printf("(Reserved)\n"); break;		case E820_ACPI:			printf("(ACPI Data)\n"); break;		case E820_NVS:			printf("(ACPI NVS)\n"); break;		default:			printf("(Type %ld)\n", m->type); break;		}	}}voiddump_dtr(unsigned long addr, unsigned long size){	unsigned long long entry;	unsigned long base, limit;	int i;	for (i = 0; i < size; i += 8) {		entry = ((unsigned long long *) addr)[i >> 3];		base = (((entry >> (56-24)) & 0xFF000000) |			((entry >> (32-16)) & 0x00FF0000) |			((entry >> (   16)) & 0x0000FFFF));		limit = (((entry >> (48-16)) & 0x000F0000) |		         ((entry           ) & 0x0000FFFF));		if (entry & (1ULL << (23+32))) /* G */			limit = (limit << 12) | 0xFFF;		printf("[0x%x] = 0x%08x%08x, base 0x%lx, limit 0x%lx\n", i,			(unsigned)(entry >> 32), (unsigned)(entry),			base, limit);	}}voiddump_vmx_context(struct vmx_assist_context *c){	printf("eip 0x%lx, esp 0x%lx, eflags 0x%lx\n",		(long) c->eip, (long) c->esp, (long) c->eflags);	printf("cr0 0x%lx, cr3 0x%lx, cr4 0x%lx\n",		(long)c->cr0, (long)c->cr3, (long)c->cr4);	printf("idtr: limit 0x%lx, base 0x%lx\n",		(long)c->idtr_limit, (long)c->idtr_base);	printf("gdtr: limit 0x%lx, base 0x%lx\n",		(long)c->gdtr_limit, (long)c->gdtr_base);	printf("cs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->cs_sel, (long)c->cs_limit, (long)c->cs_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->cs_arbytes.fields.seg_type,		c->cs_arbytes.fields.s,		c->cs_arbytes.fields.dpl,		c->cs_arbytes.fields.p,		c->cs_arbytes.fields.avl,		c->cs_arbytes.fields.default_ops_size,		c->cs_arbytes.fields.g,		c->cs_arbytes.fields.null_bit);	printf("ds: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->ds_sel, (long)c->ds_limit, (long)c->ds_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->ds_arbytes.fields.seg_type,		c->ds_arbytes.fields.s,		c->ds_arbytes.fields.dpl,		c->ds_arbytes.fields.p,		c->ds_arbytes.fields.avl,		c->ds_arbytes.fields.default_ops_size,		c->ds_arbytes.fields.g,		c->ds_arbytes.fields.null_bit);	printf("es: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->es_sel, (long)c->es_limit, (long)c->es_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->es_arbytes.fields.seg_type,		c->es_arbytes.fields.s,		c->es_arbytes.fields.dpl,		c->es_arbytes.fields.p,		c->es_arbytes.fields.avl,		c->es_arbytes.fields.default_ops_size,		c->es_arbytes.fields.g,		c->es_arbytes.fields.null_bit);	printf("ss: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->ss_sel, (long)c->ss_limit, (long)c->ss_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->ss_arbytes.fields.seg_type,		c->ss_arbytes.fields.s,		c->ss_arbytes.fields.dpl,		c->ss_arbytes.fields.p,		c->ss_arbytes.fields.avl,		c->ss_arbytes.fields.default_ops_size,		c->ss_arbytes.fields.g,		c->ss_arbytes.fields.null_bit);	printf("fs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->fs_sel, (long)c->fs_limit, (long)c->fs_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->fs_arbytes.fields.seg_type,		c->fs_arbytes.fields.s,		c->fs_arbytes.fields.dpl,		c->fs_arbytes.fields.p,		c->fs_arbytes.fields.avl,		c->fs_arbytes.fields.default_ops_size,		c->fs_arbytes.fields.g,		c->fs_arbytes.fields.null_bit);	printf("gs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->gs_sel, (long)c->gs_limit, (long)c->gs_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->gs_arbytes.fields.seg_type,		c->gs_arbytes.fields.s,		c->gs_arbytes.fields.dpl,		c->gs_arbytes.fields.p,		c->gs_arbytes.fields.avl,		c->gs_arbytes.fields.default_ops_size,		c->gs_arbytes.fields.g,		c->gs_arbytes.fields.null_bit);	printf("tr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->tr_sel, (long)c->tr_limit, (long)c->tr_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->tr_arbytes.fields.seg_type,		c->tr_arbytes.fields.s,		c->tr_arbytes.fields.dpl,		c->tr_arbytes.fields.p,		c->tr_arbytes.fields.avl,		c->tr_arbytes.fields.default_ops_size,		c->tr_arbytes.fields.g,		c->tr_arbytes.fields.null_bit);	printf("ldtr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",		(long)c->ldtr_sel, (long)c->ldtr_limit, (long)c->ldtr_base);	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",		c->ldtr_arbytes.fields.seg_type,		c->ldtr_arbytes.fields.s,		c->ldtr_arbytes.fields.dpl,		c->ldtr_arbytes.fields.p,		c->ldtr_arbytes.fields.avl,		c->ldtr_arbytes.fields.default_ops_size,		c->ldtr_arbytes.fields.g,		c->ldtr_arbytes.fields.null_bit);	printf("GDTR <0x%lx,0x%lx>:\n",		(long)c->gdtr_base, (long)c->gdtr_limit);	dump_dtr(c->gdtr_base, c->gdtr_limit);}#endif /* DEBUG *//* * Lightweight printf that doesn't drag in everything under the sun. */intprintf(const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	_doprint(putchar, fmt, ap);	va_end(ap);	return 0; /* for gcc compat */}intvprintf(const char *fmt, va_list ap){	_doprint(putchar, fmt, ap);	return 0; /* for gcc compat */}voidpanic(const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	_doprint(putchar, fmt, ap);	putchar('\n');	va_end(ap);	halt();}unsignedstrlen(const char *s){	const char *q = s;	while (*s++)		/* void */;	return s - q - 1;}static voidputchar(int ch){	outb(0xE9, ch);}/* * A stripped down version of doprint, * but still powerful enough for most tasks. */static void_doprint(void (*put)(int), const char *fmt, va_list ap){	register char *str, c;	int lflag, zflag, nflag;	char buffer[17];	unsigned value;	int i, slen, pad;	for ( ; *fmt != '\0'; fmt++) {		pad = zflag = nflag = lflag = 0;		if (*fmt == '%') {			c = *++fmt;			if (c == '-' || isdigit(c)) {				if (c == '-') {					nflag = 1;					c = *++fmt;				}				zflag = c == '0';				for (pad = 0; isdigit(c); c = *++fmt)					pad = (pad * 10) + c - '0';			}			if (c == 'l') { /* long extension */				lflag = 1;				c = *++fmt;			}			if (c == 'd' || c == 'u' || c == 'o' || c == 'x') {				if (lflag)					value = va_arg(ap, unsigned);				else					value = (unsigned) va_arg(ap, unsigned int);				str = buffer;				printnum(str, value,					c == 'o' ? 8 : (c == 'x' ? 16 : 10));				goto printn;			} else if (c == 'O' || c == 'D' || c == 'X') {				value = va_arg(ap, unsigned);				str = buffer;				printnum(str, value,					c == 'O' ? 8 : (c == 'X' ? 16 : 10));			printn:				slen = strlen(str);				for (i = pad - slen; i > 0; i--)					put(zflag ? '0' : ' ');				while (*str) put(*str++);			} else if (c == 's') {				str = va_arg(ap, char *);				slen = strlen(str);				if (nflag == 0)					for (i = pad - slen; i > 0; i--) put(' ');				while (*str) put(*str++);				if (nflag)					for (i = pad - slen; i > 0; i--) put(' ');			} else if (c == 'c')				put(va_arg(ap, int));			else				put(*fmt);		} else			put(*fmt);	}}static char *printnum(char *p, unsigned long num, int base){	unsigned long n;	if ((n = num/base) > 0)		p = printnum(p, n, base);	*p++ = "0123456789ABCDEF"[(int)(num % base)];	*p = '\0';	return p;}void *memset(void *s, int c, unsigned n){        int t0, t1;        __asm__ __volatile__ ("cld; rep; stosb"                : "=&c" (t0), "=&D" (t1)                : "a" (c), "1" (s), "0" (n)                : "memory");        return s;}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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -