/SPARTAN/trunk/arch/ia32/include/cpuid.h |
---|
39,8 → 39,20 |
} __attribute__ ((packed)); |
extern int has_cpuid(void); |
extern void cpuid(__u32 cmd, cpu_info_t *info); |
extern __u64 rdtsc(void); |
static inline void cpuid(__u32 cmd, struct cpu_info *info) |
{ |
__asm__ volatile ( |
"movl %4, %%eax\n" |
"cpuid\n" |
"movl %%eax,%0\n" |
"movl %%ebx,%1\n" |
"movl %%ecx,%2\n" |
"movl %%edx,%3\n" |
: "=m" (info->cpuid_eax), "=m" (info->cpuid_ebx), "=m" (info->cpuid_ecx), "=m" (info->cpuid_edx) |
: "m" (cmd) |
: "eax", "ebx", "ecx", "edx" |
); |
} |
#endif |
/SPARTAN/trunk/arch/ia32/include/asm.h |
---|
30,11 → 30,7 |
#define __ia32_ASM_H__ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
#include <synch/spinlock.h> |
#include <arch/boot/memmap.h> |
#include <config.h> |
extern __u32 interrupt_handler_size; |
61,8 → 57,8 |
* |
* Halt the current CPU until interrupt event. |
*/ |
static inline void cpu_halt(void) { __asm__("hlt"); }; |
static inline void cpu_sleep(void) { __asm__("hlt"); }; |
static inline void cpu_halt(void) { __asm__("hlt\n"); }; |
static inline void cpu_sleep(void) { __asm__("hlt\n"); }; |
/** Read CR2 |
* |
70,7 → 66,7 |
* |
* @return Value read. |
*/ |
static inline __u32 read_cr2(void) { __u32 v; __asm__ volatile ("movl %%cr2,%0" : "=r" (v)); return v; } |
static inline __u32 read_cr2(void) { __u32 v; __asm__ volatile ("movl %%cr2,%0\n" : "=r" (v)); return v; } |
/** Write CR3 |
* |
86,7 → 82,7 |
* |
* @return Value read. |
*/ |
static inline __u32 read_cr3(void) { __u32 v; __asm__ volatile ("movl %%cr3,%0" : "=r" (v)); return v; } |
static inline __u32 read_cr3(void) { __u32 v; __asm__ volatile ("movl %%cr3,%0\n" : "=r" (v)); return v; } |
/** Set priority level low |
* |
161,4 → 157,13 |
return v; |
} |
static inline __u64 rdtsc(void) |
{ |
__u64 v; |
__asm__ volatile("rdtsc\n" : "=A" (v)); |
return v; |
} |
#endif |
/SPARTAN/trunk/arch/ia32/src/delay.s |
---|
36,19 → 36,15 |
.global asm_fake_loop |
asm_delay_loop: |
pushl %ecx |
movl 8(%esp),%ecx # move argument to %ecx |
movl 4(%esp),%ecx # move argument to %ecx |
0: lahf |
dec %ecx |
jnz 0b |
popl %ecx |
ret |
asm_fake_loop: |
pushl %ecx |
movl 8(%esp),%ecx # move argument to %ecx |
movl 4(%esp),%ecx # move argument to %ecx |
0: lahf |
dec %ecx |
jz 0b |
popl %ecx |
ret |
/SPARTAN/trunk/arch/ia32/src/cpuid.s |
---|
26,68 → 26,25 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
# The code below just interfaces the CPUID instruction. |
# CPU recognition logic is contained in higher-level functions. |
.text |
.global has_cpuid |
.global cpuid |
.global rdtsc |
## Determine CPUID support |
# |
# Return 0 in EAX if CPUID is not support, 1 if supported. |
# Return 0 in EAX if CPUID is not supported, 1 if supported. |
# |
has_cpuid: |
push %ebx |
pushf # store flags |
popl %eax # read flags |
movl %eax,%ebx # copy flags |
btcl $21,%ebx # swap the ID bit |
pushl %ebx |
movl %eax,%edx # copy flags |
btcl $21,%edx # swap the ID bit |
pushl %edx |
popf # propagate the change into flags |
pushf |
popl %ebx # read flags |
popl %edx # read flags |
andl $(1<<21),%eax # interested only in ID bit |
andl $(1<<21),%ebx |
xorl %ebx,%eax # 0 if not supported, 1 if supported |
pop %ebx |
andl $(1<<21),%edx |
xorl %edx,%eax # 0 if not supported, 1 if supported |
ret |
## Get CPUID data |
# |
# This code is just an interfaces the CPUID instruction, CPU recognition |
# logic is contained in higher-level functions. |
# |
# The C prototype is: |
# void cpuid(__u32 cmd, struct cpu_info *info) |
# |
# @param cmd CPUID command. |
# @param info Buffer to store CPUID output. |
# |
cpuid: |
pushl %ebp |
movl %esp,%ebp |
pusha |
movl 8(%ebp),%eax # load the command into %eax |
movl 12(%ebp),%esi # laod the address of the info struct |
cpuid |
movl %eax,0(%esi) |
movl %ebx,4(%esi) |
movl %ecx,8(%esi) |
movl %edx,12(%esi) |
popa |
popl %ebp |
ret |
rdtsc: |
rdtsc |
ret |