metal-cos/sys/amd64/include/cpuop.h
2024-09-26 04:07:50 +08:00

487 lines
7.4 KiB
C

/*
* Copyright (c) 2013-2018 Ali Mashtizadeh
* All rights reserved.
*/
#ifndef __AMD64OP_H__
#define __AMD64OP_H__
static INLINE void enable_interrupts()
{
__asm__ volatile("sti");
}
static INLINE void disable_interrupts()
{
__asm__ volatile("cli");
}
static INLINE void hlt()
{
__asm__ volatile("hlt");
}
static INLINE void pause()
{
__asm__ volatile("pause");
}
static INLINE void breakpoint()
{
__asm__ volatile("int3");
}
static INLINE void icebp()
{
__asm__ volatile(".byte 0xf1");
}
static INLINE uint64_t rdtsc()
{
uint32_t lo, hi;
__asm__ volatile("rdtsc"
: "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32) | (uint64_t)lo;
}
static INLINE uint64_t rdtscp(uint32_t *procno)
{
uint32_t lo, hi, proc;
__asm__ volatile("rdtsc"
: "=a" (lo), "=d" (hi), "=c" (proc));
if (procno)
*procno = proc;
return ((uint64_t)hi << 32) | (uint64_t)lo;
}
static INLINE void lidt(PseudoDescriptor *idt)
{
__asm__ volatile("lidt (%0)"
:
: "r" (idt)
: "memory");
}
static INLINE void lgdt(PseudoDescriptor *gdt)
{
__asm__ volatile("lgdt (%0)"
:
: "r" (gdt)
: "memory");
}
static INLINE void ltr(uint16_t tss)
{
__asm__ volatile("ltr %0"
:
: "r" (tss));
}
static INLINE void cpuid(uint32_t info, uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
uint32_t a, b, c, d;
__asm__ volatile("cpuid"
: "=a" (a), "=b" (b), "=c" (c), "=d" (d)
: "a" (info));
if (eax)
*eax = a;
if (ebx)
*ebx = b;
if (ecx)
*ecx = c;
if (edx)
*edx = d;
}
static INLINE void wrmsr(uint32_t addr, uint64_t val)
{
uint32_t eax = val & 0xFFFFFFFF;
uint32_t edx = val >> 32;
__asm__ volatile("wrmsr"
:
: "a" (eax), "c" (addr), "d" (edx));
}
static INLINE uint64_t rdmsr(uint32_t addr)
{
uint64_t eax, edx;
__asm__ volatile("rdmsr"
: "=a" (eax), "=d" (edx)
: "c" (addr));
return edx << 32 | eax;
}
/*
* Control Registers
*/
static INLINE uint64_t read_cr0()
{
uint64_t val;
__asm__ volatile("movq %%cr0, %0"
: "=r" (val));
return val;
}
static INLINE void write_cr0(uint64_t val)
{
__asm__ volatile("movq %0, %%cr0"
:
: "r" (val));
}
static INLINE uint64_t read_cr2()
{
uint64_t val;
__asm__ volatile("movq %%cr2, %0"
: "=r" (val));
return val;
}
static INLINE uint64_t read_cr3()
{
uint64_t val;
__asm__ volatile("movq %%cr3, %0"
: "=r" (val));
return val;
}
static INLINE void write_cr3(uint64_t val)
{
__asm__ volatile("movq %0, %%cr3"
:
: "r" (val));
}
static INLINE uint64_t read_cr4()
{
uint64_t val;
__asm__ volatile("movq %%cr4, %0"
: "=r" (val));
return val;
}
static INLINE void write_cr4(uint64_t val)
{
__asm__ volatile("movq %0, %%cr4"
:
: "r" (val));
}
/*
* Debug Registers
*/
static INLINE uint64_t read_dr0()
{
uint64_t val;
__asm__ volatile("movq %%dr0, %0"
: "=r" (val));
return val;
}
static INLINE void write_dr0(uint64_t val)
{
__asm__ volatile("movq %0, %%dr0"
:
: "r" (val));
}
static INLINE uint64_t read_dr1()
{
uint64_t val;
__asm__ volatile("movq %%dr1, %0"
: "=r" (val));
return val;
}
static INLINE void write_dr1(uint64_t val)
{
__asm__ volatile("movq %0, %%dr1"
:
: "r" (val));
}
static INLINE uint64_t read_dr2()
{
uint64_t val;
__asm__ volatile("movq %%dr2, %0"
: "=r" (val));
return val;
}
static INLINE void write_dr2(uint64_t val)
{
__asm__ volatile("movq %0, %%dr2"
:
: "r" (val));
}
static INLINE uint64_t read_dr3()
{
uint64_t val;
__asm__ volatile("movq %%dr3, %0"
: "=r" (val));
return val;
}
static INLINE void write_dr3(uint64_t val)
{
__asm__ volatile("movq %0, %%dr3"
:
: "r" (val));
}
static INLINE uint64_t read_dr6()
{
uint64_t val;
__asm__ volatile("movq %%dr6, %0"
: "=r" (val));
return val;
}
static INLINE void write_dr6(uint64_t val)
{
__asm__ volatile("movq %0, %%dr6"
:
: "r" (val));
}
static INLINE uint64_t read_dr7()
{
uint64_t val;
__asm__ volatile("movq %%dr7, %0"
: "=r" (val));
return val;
}
static INLINE void write_dr7(uint64_t val)
{
__asm__ volatile("movq %0, %%dr7"
:
: "r" (val));
}
/*
* Segment Registers
*/
static INLINE uint16_t read_ds()
{
uint16_t val;
__asm__ volatile("movw %%ds, %0"
: "=r" (val));
return val;
}
static INLINE void write_ds(uint16_t val)
{
__asm__ volatile("movw %0, %%ds"
:
: "r" (val));
}
static INLINE uint16_t read_es()
{
uint16_t val;
__asm__ volatile("movw %%es, %0"
: "=r" (val));
return val;
}
static INLINE void write_es(uint16_t val)
{
__asm__ volatile("movw %0, %%es"
:
: "r" (val));
}
static INLINE uint16_t read_fs()
{
uint16_t val;
__asm__ volatile("movw %%fs, %0"
: "=r" (val));
return val;
}
static INLINE void write_fs(uint16_t val)
{
__asm__ volatile("movw %0, %%fs"
:
: "r" (val));
}
static INLINE uint16_t read_gs()
{
uint16_t val;
__asm__ volatile("movw %%gs, %0"
: "=r" (val));
return val;
}
static INLINE void write_gs(uint16_t val)
{
__asm__ volatile("movw %0, %%gs"
:
: "r" (val));
}
/*
* Floating Point
*/
static INLINE void clts()
{
__asm__ volatile("clts");
}
static INLINE void fxsave(struct XSAVEArea *xsa)
{
__asm__ volatile("fxsave %0"
: "=m" (*xsa)
:
: "memory");
}
// XXX: Need to fix AMD Bug
static INLINE void fxrstor(struct XSAVEArea *xsa)
{
__asm__ volatile("fxrstor %0"
:
: "m" (*xsa)
: "memory");
}
static INLINE void xsave(struct XSAVEArea *xsa, uint64_t mask)
{
uint32_t lo = (uint32_t)mask;
uint32_t hi = (uint32_t)(mask >> 32);
__asm__ volatile("xsave %0"
: "=m" (*xsa)
: "a" (lo), "d" (hi)
: "memory");
}
static INLINE void xsaveopt(struct XSAVEArea *xsa, uint64_t mask)
{
uint32_t lo = (uint32_t)mask;
uint32_t hi = (uint32_t)(mask >> 32);
__asm__ volatile("xsaveopt %0"
: "=m" (*xsa)
: "a" (lo), "d" (hi)
: "memory");
}
static INLINE void xrstor(struct XSAVEArea *xsa, uint64_t mask)
{
uint32_t lo = (uint32_t)mask;
uint32_t hi = (uint32_t)(mask >> 32);
__asm__ volatile("xrstor %0"
:
: "m" (*xsa), "a" (lo), "d" (hi)
: "memory");
}
/*
* Port IO
*/
static INLINE void outb(uint16_t port, uint8_t data)
{
__asm__ volatile("outb %0, %1"
:
: "a" (data), "d" (port));
}
static INLINE void outw(uint16_t port, uint16_t data)
{
__asm__ volatile("outw %0, %1"
:
: "a" (data), "d" (port));
}
static INLINE void outl(uint16_t port, uint32_t data)
{
__asm__ volatile("outl %0, %1"
:
: "a" (data), "d" (port));
}
static INLINE uint8_t inb(uint16_t port)
{
uint8_t data;
__asm__ volatile("inb %1, %0"
: "=a" (data)
:"d" (port));
return data;
}
static INLINE uint16_t inw(uint16_t port)
{
uint16_t data;
__asm__ volatile("inw %1, %0"
: "=a" (data)
:"d" (port));
return data;
}
static INLINE uint32_t inl(uint16_t port)
{
uint32_t data;
__asm__ volatile("inl %1, %0"
: "=a" (data)
:"d" (port));
return data;
}
#endif /* __AMD64OP_H__ */