mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
98 lines
3.2 KiB
C
98 lines
3.2 KiB
C
#ifndef __UHYVE_CPU_H__
|
|
#define __UHYVE_CPU_H__
|
|
|
|
#ifndef _BITUL
|
|
|
|
#ifdef __ASSEMBLY__
|
|
#define _AC(X,Y) X
|
|
#define _AT(T,X) X
|
|
#else
|
|
#define __AC(X,Y) (X##Y)
|
|
#define _AC(X,Y) __AC(X,Y)
|
|
#define _AT(T,X) ((T)(X))
|
|
#endif
|
|
|
|
#define _BITUL(x) (_AC(1,UL) << (x))
|
|
#define _BITULL(x) (_AC(1,ULL) << (x))
|
|
|
|
#endif
|
|
|
|
/*
|
|
* EFLAGS bits
|
|
*/
|
|
#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
|
|
|
|
/*
|
|
* Basic CPU control in CR0
|
|
*/
|
|
#define X86_CR0_PE_BIT 0 /* Protection Enable */
|
|
#define X86_CR0_PE _BITUL(X86_CR0_PE_BIT)
|
|
#define X86_CR0_PG_BIT 31 /* Paging */
|
|
#define X86_CR0_PG _BITUL(X86_CR0_PG_BIT)
|
|
|
|
/*
|
|
* Intel CPU features in CR4
|
|
*/
|
|
#define X86_CR4_PAE_BIT 5 /* enable physical address extensions */
|
|
#define X86_CR4_PAE _BITUL(X86_CR4_PAE_BIT)
|
|
|
|
/*
|
|
* Intel long mode page directory/table entries
|
|
*/
|
|
#define X86_PDPT_P_BIT 0 /* Present */
|
|
#define X86_PDPT_P _BITUL(X86_PDPT_P_BIT)
|
|
#define X86_PDPT_RW_BIT 1 /* Writable */
|
|
#define X86_PDPT_RW _BITUL(X86_PDPT_RW_BIT)
|
|
#define X86_PDPT_PS_BIT 7 /* Page size */
|
|
#define X86_PDPT_PS _BITUL(X86_PDPT_PS_BIT)
|
|
|
|
/*
|
|
* GDT and KVM segment manipulation
|
|
*/
|
|
|
|
#define GDT_DESC_OFFSET(n) ((n) * 0x8)
|
|
|
|
#define GDT_GET_BASE(x) ( \
|
|
(((x) & 0xFF00000000000000) >> 32) | \
|
|
(((x) & 0x000000FF00000000) >> 16) | \
|
|
(((x) & 0x00000000FFFF0000) >> 16))
|
|
|
|
#define GDT_GET_LIMIT(x) (__u32)( \
|
|
(((x) & 0x000F000000000000) >> 32) | \
|
|
(((x) & 0x000000000000FFFF)))
|
|
|
|
/* Constructor for a conventional segment GDT (or LDT) entry */
|
|
/* This is a macro so it can be used in initializers */
|
|
#define GDT_ENTRY(flags, base, limit) \
|
|
((((base) & _AC(0xff000000, ULL)) << (56-24)) | \
|
|
(((flags) & _AC(0x0000f0ff, ULL)) << 40) | \
|
|
(((limit) & _AC(0x000f0000, ULL)) << (48-16)) | \
|
|
(((base) & _AC(0x00ffffff, ULL)) << 16) | \
|
|
(((limit) & _AC(0x0000ffff, ULL))))
|
|
|
|
#define GDT_GET_G(x) (__u8)(((x) & 0x0080000000000000) >> 55)
|
|
#define GDT_GET_DB(x) (__u8)(((x) & 0x0040000000000000) >> 54)
|
|
#define GDT_GET_L(x) (__u8)(((x) & 0x0020000000000000) >> 53)
|
|
#define GDT_GET_AVL(x) (__u8)(((x) & 0x0010000000000000) >> 52)
|
|
#define GDT_GET_P(x) (__u8)(((x) & 0x0000800000000000) >> 47)
|
|
#define GDT_GET_DPL(x) (__u8)(((x) & 0x0000600000000000) >> 45)
|
|
#define GDT_GET_S(x) (__u8)(((x) & 0x0000100000000000) >> 44)
|
|
#define GDT_GET_TYPE(x)(__u8)(((x) & 0x00000F0000000000) >> 40)
|
|
|
|
#define GDT_TO_KVM_SEGMENT(seg, gdt_table, sel) \
|
|
do { \
|
|
__u64 gdt_ent = gdt_table[sel]; \
|
|
seg.base = GDT_GET_BASE(gdt_ent); \
|
|
seg.limit = GDT_GET_LIMIT(gdt_ent); \
|
|
seg.selector = sel * 8; \
|
|
seg.type = GDT_GET_TYPE(gdt_ent); \
|
|
seg.present = GDT_GET_P(gdt_ent); \
|
|
seg.dpl = GDT_GET_DPL(gdt_ent); \
|
|
seg.db = GDT_GET_DB(gdt_ent); \
|
|
seg.s = GDT_GET_S(gdt_ent); \
|
|
seg.l = GDT_GET_L(gdt_ent); \
|
|
seg.g = GDT_GET_G(gdt_ent); \
|
|
seg.avl = GDT_GET_AVL(gdt_ent); \
|
|
} while (0)
|
|
|
|
#endif
|