mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 19:43:32 +00:00
2d80bbc802
blinkenlights now does a pretty good job emulating what happens when binaries boot from BIOS into long mode. So it's been much easier to debug the bare metal process and wrinkle out many issues.
63 lines
3.1 KiB
C
63 lines
3.1 KiB
C
#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_RDTSCP_H_
|
|
#define COSMOPOLITAN_LIBC_NEXGEN32E_RDTSCP_H_
|
|
#include "libc/bits/bits.h"
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
#define TSC_AUX_CORE(MSR) ((MSR)&0xfff)
|
|
#define TSC_AUX_NODE(MSR) (((MSR) >> 12) & 0xfff)
|
|
|
|
/**
|
|
* Reads CPU timestamp counter and IA32_TSC_AUX.
|
|
*
|
|
* This macro inhibits compiler magic.
|
|
* This macro does not inhibit CPU magic.
|
|
*
|
|
* @see X86_HAVE(RDTSCP)
|
|
*/
|
|
#define rdtscp(OPT_OUT_IA32_TSC_AUX) \
|
|
({ \
|
|
uint32_t Ecx, *EcxOut; \
|
|
uint64_t Rax, Rcx, Rdx; \
|
|
asm volatile("rdtscp" \
|
|
: "=a"(Rax), "=c"(Ecx), "=d"(Rdx) \
|
|
: /* no inputs */ \
|
|
: "memory"); \
|
|
EcxOut = (OPT_OUT_IA32_TSC_AUX); \
|
|
if (EcxOut) *EcxOut = Ecx; \
|
|
Rdx << 32 | Rax; \
|
|
})
|
|
|
|
/**
|
|
* Reads timestamp counter auxiliary model specific register value.
|
|
*/
|
|
#define rdpid() \
|
|
({ \
|
|
bool Ok; \
|
|
long Msr; \
|
|
Ok = false; \
|
|
if (X86_HAVE(RDPID)) { \
|
|
asm volatile("rdpid\t%0" : "=r"(Msr) : /* no inputs */ : "memory"); \
|
|
Ok = true; \
|
|
} else if (IsLinux()) { \
|
|
asm volatile(ZFLAG_ASM("lsl\t%2,%1") \
|
|
: ZFLAG_CONSTRAINT(Ok), "=r"(Msr) \
|
|
: "r"(0x7b) \
|
|
: "memory"); \
|
|
} \
|
|
if (!Ok && X86_HAVE(RDTSCP)) { \
|
|
asm volatile("rdtscp" \
|
|
: "=c"(Msr) \
|
|
: /* no inputs */ \
|
|
: "eax", "edx", "memory"); \
|
|
Ok = true; \
|
|
} \
|
|
if (!Ok) { \
|
|
Msr = -1; \
|
|
} \
|
|
Msr; \
|
|
})
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_RDTSCP_H_ */
|