From b52ed331f181f149b67bdaf6c0170cb030a820a3 Mon Sep 17 00:00:00 2001 From: Daniel Reinhold Date: Sun, 20 Oct 2002 04:04:03 +0000 Subject: [PATCH] implemented the get_cpuid() function in libroot and added a new kernel app 'cpuinfo' git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1582 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/Jamfile | 17 ++++++++- src/kernel/apps/Jamfile | 1 + src/kernel/libroot/os/arch/x86/Jamfile | 8 +++- src/kernel/libroot/os/arch/x86/cpuid.S | 37 ++++++++++++++++++ src/kernel/libroot/os/systeminfo.c | 52 +++++++++++++++++++++++++- 5 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 src/kernel/libroot/os/arch/x86/cpuid.S diff --git a/src/kernel/Jamfile b/src/kernel/Jamfile index 6073bedb19..b9a95f5a61 100644 --- a/src/kernel/Jamfile +++ b/src/kernel/Jamfile @@ -72,6 +72,7 @@ KernelStaticLibraryObjects libkern.a : <$(SOURCE_GRIST)!libroot!posix>rlimit.o <$(SOURCE_GRIST)!libroot!os!arch!$(OBOS_ARCH)>atomic.o + <$(SOURCE_GRIST)!libroot!os!arch!$(OBOS_ARCH)>cpuid.o ; KernelLd stage2 @@ -195,6 +196,7 @@ KernelStaticLibraryObjects libc.a : <$(SOURCE_GRIST)!libroot!os>syscalls.o <$(SOURCE_GRIST)!libroot!os>sem.o <$(SOURCE_GRIST)!libroot!os!arch!$(OBOS_ARCH)>atomic.o + <$(SOURCE_GRIST)!libroot!os!arch!$(OBOS_ARCH)>cpuid.o <$(SOURCE_GRIST)!libroot!posix>errno.o <$(SOURCE_GRIST)!libroot!posix>dlfcn.o @@ -333,6 +335,7 @@ KernelLd libroot.so : <$(SOURCE_GRIST)!libroot!os>time.o <$(SOURCE_GRIST)!libroot!os>syscalls.o <$(SOURCE_GRIST)!libroot!os!arch!$(OBOS_ARCH)>atomic.o + <$(SOURCE_GRIST)!libroot!os!arch!$(OBOS_ARCH)>cpuid.o <$(SOURCE_GRIST)!libroot!posix>dlfcn.o <$(SOURCE_GRIST)!libroot!posix>errno.o @@ -510,7 +513,19 @@ KernelLd libglue2.o : : no_gcc ; - + +KernelLd cpuinfo : + libglue2.o + <$(SOURCE_GRIST)!apps!cpuinfo>main.o + libroot.so + : + $(SUBDIR)/ldscripts/$(OBOS_ARCH)/app.ld + : + : + : + bin/cpuinfo + ; + KernelLd init : libglue2.o <$(SOURCE_GRIST)!apps>init.o diff --git a/src/kernel/apps/Jamfile b/src/kernel/apps/Jamfile index 8d14ae3981..5eb5cbf907 100644 --- a/src/kernel/apps/Jamfile +++ b/src/kernel/apps/Jamfile @@ -2,6 +2,7 @@ SubDir OBOS_TOP src kernel apps ; KernelObjects false_main.c fibo_main.c init.c true_main.c ; +SubInclude OBOS_TOP src kernel apps cpuinfo ; SubInclude OBOS_TOP src kernel apps echo ; SubInclude OBOS_TOP src kernel apps filetest ; SubInclude OBOS_TOP src kernel apps fortune ; diff --git a/src/kernel/libroot/os/arch/x86/Jamfile b/src/kernel/libroot/os/arch/x86/Jamfile index ccf94b4fa0..afaf27c216 100644 --- a/src/kernel/libroot/os/arch/x86/Jamfile +++ b/src/kernel/libroot/os/arch/x86/Jamfile @@ -1,3 +1,9 @@ SubDir OBOS_TOP src kernel libroot os arch x86 ; -KernelObjects atomic.S ; +KernelObjects + <$(SOURCE_GRIST)>atomic.S + <$(SOURCE_GRIST)>cpuid.S + : + -fPIC -DPIC + ; + diff --git a/src/kernel/libroot/os/arch/x86/cpuid.S b/src/kernel/libroot/os/arch/x86/cpuid.S new file mode 100644 index 0000000000..69532570ae --- /dev/null +++ b/src/kernel/libroot/os/arch/x86/cpuid.S @@ -0,0 +1,37 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + +#define FUNCTION(x) .global x; .type x,@function; x + +.text + +/* void cpuid(unsigned int eax_value, unsigned int *return_data) */ +FUNCTION(cpuid): + pushl %ebx + pushl %edi + movl 12(%esp),%eax /* first arg sets up eax */ + movl 16(%esp),%edi /* second arg points to the return area */ + cpuid + movl %eax,0(%edi) /* copy the regs into the return area */ + movl %ebx,4(%edi) /* ... */ + movl %ecx,8(%edi) /* ... */ + movl %edx,12(%edi) /* ... */ + popl %edi + popl %ebx + ret + + +/* unsigned int get_eflags(void) */ +FUNCTION(get_eflags): + pushfl + popl %eax + ret + + +/* void set_eflags(unsigned int val) */ +FUNCTION(set_eflags): + pushl 4(%esp) + popfl + ret diff --git a/src/kernel/libroot/os/systeminfo.c b/src/kernel/libroot/os/systeminfo.c index c5cba3b3f6..982ea55ac0 100644 --- a/src/kernel/libroot/os/systeminfo.c +++ b/src/kernel/libroot/os/systeminfo.c @@ -8,13 +8,61 @@ #include "syscalls.h" +#ifdef __INTEL__ + +// this declaration could be placed in a header file somewhere, but it doesn't +// appear likely that any user functions besides 'get_cpuid()' would need it... +void cpuid(unsigned int selector, unsigned int *data); + + +/* + * get_cpuid() -- uses the 'cpuid' instruction to retrieve information + * about the computer make & model and the capabilities of the cpu(s) + * ...this means the function is strictly INTEL PLATFORM ONLY!!! + * + * parameters: + * info: out - the structure to hold the cpuid information + * eax_register: in - the value to place in eax before invoking 'cpuid' + * cpu_num: in - the number of the cpu to gather information about + * (currently not used) + * + * Note: the stage2 bootloader already verifies at startup time that the + * 'cpuid' instruction can be called by the host computer, so no checking + * for this is done here. + */ + status_t get_cpuid(cpuid_info *info, uint32 eax_register, uint32 cpu_num) { - // ToDo: get_cpuid() - return B_ERROR; + unsigned int data[4]; + + // call the instruction + cpuid(eax_register, data); + + // fill the info struct with the return values + info->regs.eax = data[0]; + info->regs.ebx = data[1]; + info->regs.ecx = data[2]; + info->regs.edx = data[3]; + + if (eax_register == 0) { + // fixups for this special case + char *vendor = info->eax_0.vendorid; + + // the high-order word is non-zero on some Cyrix CPUs + info->eax_0.max_eax = data[0] & 0xffff; + + // the vendor string bytes need a little re-ordering + *((unsigned int *) &vendor[0]) = data[1]; + *((unsigned int *) &vendor[4]) = data[3]; + *((unsigned int *) &vendor[8]) = data[2]; + } + + return B_OK; } +#endif + status_t _get_system_info(system_info *returned_info, size_t size)