diff --git a/boot/Makefile b/boot/Makefile index 9c506df..5957202 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -5,7 +5,7 @@ PROG = boot SRCS = srt0.S gdt.S boot.c OBJS = srt0.o gdt.o boot.o -ESRCS = pccon.c sricon.c print.c fmt.c a20.c time.c mem.c +ESRCS = pccon.c sricon.c print.c fmt.c a20.c time.c mem.c cpu.c OBJS += $(ESRCS:.c=.o) include $(SDIR)/Makefile.inc diff --git a/boot/boot.c b/boot/boot.c index 4a90533..2c2db99 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -7,6 +7,7 @@ static void machdep(void); void (*probe1[])(void) = { a20up, coninit, memprobe, + cpuidprobe, }; void (*probe2[])(void) = { }; diff --git a/boot/cpu.c b/boot/cpu.c new file mode 100644 index 0000000..760ae9c --- /dev/null +++ b/boot/cpu.c @@ -0,0 +1,56 @@ +#include +#include "dat.h" +#include "fn.h" + +#define EFLAG_ID 0x00200000 +#define CPUID(code, a, b, c, d) \ + __asm volatile("cpuid" \ + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ + : "a" (code)) + +void* +memset(void *dst, int v, int l) +{ + char *p = dst; + for(int i = 0; i < l; ++i) + *p++ = 0; + return dst; +} + +void +cpuidprobe(void) +{ + int canuse; + union{ + struct{u32 a,b,d,c;}; + char arr[16]; + }r = {0,}; + + __asm volatile("pushfl\n\t" + "popl %2\n\t" + "xorl %2, %0\n\t" /* Invert ID sotred in EFLAGS */ + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "xorl %2, %0\n\t" + : "=r" (canuse) + : "0" (EFLAG_ID), "r" (0) /* "EFLAGS_ID" same location "canuse" */ + : "cc"); + if(canuse != EFLAG_ID){ + print("cpuid not available\n"); + return; + } + + // print vendor + CPUID(0x00, r.a, r.b, r.c, r.d); + print("CPU vender: %s\n", r.arr+4); + // Is running on Hypervisor? + // But nothing to do... + memset(&r, 0,sizeof(r)); + CPUID(0x01, r.a, r.b, r.c, r.d); + if(r.c & (1<<31)){ + CPUID(1<<30, r.a, r.b, r.c, r.d); + print("Running on Hypervisor: %s\n", r.arr+4); + } +} \ No newline at end of file diff --git a/boot/fn.h b/boot/fn.h index faa32d0..300cb28 100644 --- a/boot/fn.h +++ b/boot/fn.h @@ -29,6 +29,9 @@ void a20up(void); // mem.c void memprobe(void); +// cpu.c +void cpuidprobe(void); + // time.c long getsecs(void);