static void putchar(int);
static char *printnum(char *, unsigned long, int);
-static void _doprint(void (*)(int), char const *, va_list);
+static void _doprint(void (*)(int), const char *, va_list);
+void
+cpuid_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;
+}
void
dump_regs(struct regs *regs)
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("eip %8x eflags %8x cs %8x ds %8x\n",
- regs->eip, regs->eflags, regs->cs, regs->ds);
- printf("es %8x fs %8x uss %8x uesp %8x\n",
- regs->es, regs->fs, regs->uss, regs->uesp);
+ 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);
- if (regs->trapno != -1 || regs->errno != -1)
- printf("trapno %8x errno %8x\n", regs->trapno, regs->errno);
- printf("cr0 %8lx cr2 %8x cr3 %8lx cr4 %8lx\n",
+ printf("cr0 %8lx cr2 %8x cr3 %8lx cr4 %8lx\n\n",
(long)oldctx.cr0, get_cr2(),
(long)oldctx.cr3, (long)oldctx.cr4);
}
* but still powerful enough for most tasks.
*/
static void
-_doprint(void (*put)(int), char const *fmt, va_list ap)
+_doprint(void (*put)(int), const char *fmt, va_list ap)
{
register char *str, c;
int lflag, zflag, nflag;