2020-09-21 13:15:55 +03:00
|
|
|
#ifndef __SYS__CPU_H__
|
|
|
|
#define __SYS__CPU_H__
|
2019-05-30 16:59:25 +03:00
|
|
|
|
|
|
|
#include <stdint.h>
|
2020-08-27 01:44:16 +03:00
|
|
|
|
2020-09-18 15:39:29 +03:00
|
|
|
#define FLAT_PTR(PTR) (*((int(*)[])(PTR)))
|
|
|
|
|
|
|
|
#define BYTE_PTR(PTR) (*((uint8_t *)(PTR)))
|
|
|
|
#define WORD_PTR(PTR) (*((uint16_t *)(PTR)))
|
|
|
|
#define DWORD_PTR(PTR) (*((uint32_t *)(PTR)))
|
|
|
|
#define QWORD_PTR(PTR) (*((uint64_t *)(PTR)))
|
|
|
|
|
2020-10-12 22:49:17 +03:00
|
|
|
static inline int cpuid(uint32_t leaf, uint32_t subleaf,
|
|
|
|
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) {
|
|
|
|
uint32_t cpuid_max;
|
|
|
|
asm volatile ("cpuid"
|
|
|
|
: "=a" (cpuid_max)
|
|
|
|
: "a" (leaf & 0x80000000)
|
|
|
|
: "ebx", "ecx", "edx");
|
|
|
|
if (leaf > cpuid_max)
|
|
|
|
return 1;
|
|
|
|
asm volatile ("cpuid"
|
|
|
|
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
|
|
|
|
: "a" (leaf), "c" (subleaf));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-01 21:05:41 +03:00
|
|
|
static inline void outb(uint16_t port, uint8_t value) {
|
|
|
|
asm volatile ("out %1, al" : : "a" (value), "Nd" (port) : "memory");
|
2020-08-27 01:44:16 +03:00
|
|
|
}
|
|
|
|
|
2020-10-01 21:05:41 +03:00
|
|
|
static inline void outw(uint16_t port, uint16_t value) {
|
|
|
|
asm volatile ("out %1, ax" : : "a" (value), "Nd" (port) : "memory");
|
2020-08-27 01:44:16 +03:00
|
|
|
}
|
|
|
|
|
2020-10-01 21:05:41 +03:00
|
|
|
static inline void outd(uint16_t port, uint32_t value) {
|
|
|
|
asm volatile ("out %1, eax" : : "a" (value), "Nd" (port) : "memory");
|
2020-08-27 01:44:16 +03:00
|
|
|
}
|
|
|
|
|
2020-10-01 21:05:41 +03:00
|
|
|
static inline uint8_t inb(uint16_t port) {
|
2020-08-27 01:44:16 +03:00
|
|
|
uint8_t value;
|
2020-10-01 21:05:41 +03:00
|
|
|
asm volatile ("in al, %1" : "=a" (value) : "Nd" (port) : "memory");
|
2020-08-27 01:44:16 +03:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-10-01 21:05:41 +03:00
|
|
|
static inline uint16_t inw(uint16_t port) {
|
2020-08-27 01:44:16 +03:00
|
|
|
uint16_t value;
|
2020-10-01 21:05:41 +03:00
|
|
|
asm volatile ("in ax, %1" : "=a" (value) : "Nd" (port) : "memory");
|
2020-08-27 01:44:16 +03:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-10-01 21:05:41 +03:00
|
|
|
static inline uint32_t ind(uint16_t port) {
|
2020-08-27 01:44:16 +03:00
|
|
|
uint32_t value;
|
2020-10-01 21:05:41 +03:00
|
|
|
asm volatile ("in eax, %1" : "=a" (value) : "Nd" (port) : "memory");
|
2020-08-27 01:44:16 +03:00
|
|
|
return value;
|
|
|
|
}
|
2019-05-30 16:59:25 +03:00
|
|
|
|
2020-09-18 15:39:29 +03:00
|
|
|
static inline void mmoutb(void *addr, uint8_t value) {
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=m" (BYTE_PTR(addr))
|
|
|
|
: "g" (value)
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void mmoutw(void *addr, uint16_t value) {
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=m" (WORD_PTR(addr))
|
|
|
|
: "g" (value)
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void mmoutd(void *addr, uint32_t value) {
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=m" (DWORD_PTR(addr))
|
|
|
|
: "g" (value)
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void mmoutq(void *addr, uint64_t value) {
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=m" (QWORD_PTR(addr))
|
|
|
|
: "g" (value)
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint8_t mminb(void *addr) {
|
|
|
|
uint8_t ret;
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=r" (ret)
|
|
|
|
: "g" (BYTE_PTR(addr))
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t mminw(void *addr) {
|
|
|
|
uint16_t ret;
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=r" (ret)
|
|
|
|
: "g" (WORD_PTR(addr))
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32_t mmind(void *addr) {
|
|
|
|
uint32_t ret;
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=r" (ret)
|
|
|
|
: "g" (DWORD_PTR(addr))
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint64_t mminq(void *addr) {
|
|
|
|
uint64_t ret;
|
|
|
|
asm volatile (
|
2020-10-01 21:05:41 +03:00
|
|
|
"mov %0, %1"
|
|
|
|
: "=r" (ret)
|
|
|
|
: "g" (QWORD_PTR(addr))
|
2020-09-18 15:39:29 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint64_t rdmsr(uint32_t msr) {
|
|
|
|
uint32_t edx, eax;
|
|
|
|
asm volatile ("rdmsr"
|
|
|
|
: "=a" (eax), "=d" (edx)
|
|
|
|
: "c" (msr)
|
|
|
|
: "memory");
|
|
|
|
return ((uint64_t)edx << 32) | eax;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void wrmsr(uint32_t msr, uint64_t value) {
|
|
|
|
uint32_t edx = value >> 32;
|
|
|
|
uint32_t eax = (uint32_t)value;
|
|
|
|
asm volatile ("wrmsr"
|
|
|
|
:
|
|
|
|
: "a" (eax), "d" (edx), "c" (msr)
|
|
|
|
: "memory");
|
|
|
|
}
|
|
|
|
|
|
|
|
#define write_cr(reg, val) ({ \
|
2020-10-01 21:05:41 +03:00
|
|
|
asm volatile ("mov cr" reg ", %0" :: "r" (val) : "memory"); \
|
2020-09-18 15:39:29 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
#define read_cr(reg) ({ \
|
|
|
|
size_t cr; \
|
2020-10-01 21:05:41 +03:00
|
|
|
asm volatile ("mov %0, cr" reg : "=r" (cr) :: "memory"); \
|
2020-09-18 15:39:29 +03:00
|
|
|
cr; \
|
|
|
|
})
|
|
|
|
|
|
|
|
#define locked_read(var) ({ \
|
|
|
|
typeof(*var) ret = 0; \
|
|
|
|
asm volatile ( \
|
|
|
|
"lock xadd %1, %0;" \
|
|
|
|
: "+r" (ret) \
|
|
|
|
: "m" (*(var)) \
|
2020-10-01 21:05:41 +03:00
|
|
|
: "memory" \
|
2020-09-18 15:39:29 +03:00
|
|
|
); \
|
|
|
|
ret; \
|
|
|
|
})
|
|
|
|
|
|
|
|
#define locked_write(var, val) ({ \
|
|
|
|
typeof(*var) ret = val; \
|
|
|
|
asm volatile ( \
|
|
|
|
"lock xchg %1, %0;" \
|
|
|
|
: "+r" ((ret)) \
|
|
|
|
: "m" (*(var)) \
|
|
|
|
: "memory" \
|
|
|
|
); \
|
|
|
|
ret; \
|
|
|
|
})
|
|
|
|
|
2019-05-30 16:59:25 +03:00
|
|
|
#endif
|