From 3d22e292bc005be4d25f2e862f0d30ed3e1c34bf Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 8 Jan 2016 18:25:40 +0000 Subject: [PATCH] Split out symbolic constant support into a separate file While moving, rename _INIT_GDTE() to INIT_GDTE() and drop INIT_GDTE_RAW() entirely. Document the new INIT_GDTE() and implement INIT_GDTE_SYM() using it. Signed-off-by: Andrew Cooper --- arch/x86/desc.c | 1 + arch/x86/hvm/traps.c | 2 +- include/arch/x86/desc.h | 29 +++++------------ include/arch/x86/symbolic-const.h | 53 +++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 include/arch/x86/symbolic-const.h diff --git a/arch/x86/desc.c b/arch/x86/desc.c index 6058769..ec49b47 100644 --- a/arch/x86/desc.c +++ b/arch/x86/desc.c @@ -1,5 +1,6 @@ #include #include +#include user_desc gdt[NR_GDT_ENTRIES] = { diff --git a/arch/x86/hvm/traps.c b/arch/x86/hvm/traps.c index a860153..f2455bd 100644 --- a/arch/x86/hvm/traps.c +++ b/arch/x86/hvm/traps.c @@ -106,7 +106,7 @@ void arch_init_traps(void) asm volatile ("lidt idt_ptr"); - gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE_RAW((unsigned long)&tss, 0x67, 0x89); + gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long)&tss, 0x67, 0x89); asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8)); } diff --git a/include/arch/x86/desc.h b/include/arch/x86/desc.h index dc55726..f8e6235 100644 --- a/include/arch/x86/desc.h +++ b/include/arch/x86/desc.h @@ -9,7 +9,6 @@ #include #include -#include #include @@ -120,31 +119,19 @@ struct __packed seg_gate64 { #define SEG_ATTR_E 0x0004 /**< Expand-down? (0 = normal, 1 = expand-down) */ #define SEG_ATTR_W 0x0002 /**< Writable? (0 = RO seg, 1 = RW seg) */ -/* Macro magic to expand symbolic SEG_ATTR names into a constant */ -#define _GDTE_ATTR0() (0) -#define _GDTE_ATTR1(x) (SEG_ATTR_ ## x) -#define _GDTE_ATTR2(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR1(__VA_ARGS__)) -#define _GDTE_ATTR3(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR2(__VA_ARGS__)) -#define _GDTE_ATTR4(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR3(__VA_ARGS__)) -#define _GDTE_ATTR5(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR4(__VA_ARGS__)) -#define _GDTE_ATTR6(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR5(__VA_ARGS__)) -#define _GDTE_ATTR7(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR6(__VA_ARGS__)) -#define _GDTE_ATTR8(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR7(__VA_ARGS__)) - -#define GDTE_ATTR(...) VAR_MACRO(_GDTE_ATTR, __VA_ARGS__) - - -#define _INIT_GDTE(base, limit, attr) { { { \ +/** + * Initialise an LDT/GDT entry using a raw attribute number. + * + * @param base Segment base. + * @param limit Segment limit. + * @param attr Segment attributes. + */ +#define INIT_GDTE(base, limit, attr) { { { \ .lo = (((base) & 0xffff) << 16) | ((limit) & 0xffff), \ .hi = ((base) & 0xff000000) | ((limit) & 0xf0000) | \ (((attr) & 0xf0ff) << 8) | (((base) & 0xff0000) >> 16) \ } } } -/** Initialise an LDT/GDT entry using a raw attribute number. */ -#define INIT_GDTE_RAW(base, limit, attr) _INIT_GDTE(base, limit, attr) -/** Initialise an LDT/GDT entry using symbol attributes. */ -#define INIT_GDTE_SYM(base, limit, ...) _INIT_GDTE(base, limit, GDTE_ATTR(__VA_ARGS__)) - /** Long mode lgdt/lidt table pointer. */ struct __packed desc_ptr64 { uint16_t limit; diff --git a/include/arch/x86/symbolic-const.h b/include/arch/x86/symbolic-const.h new file mode 100644 index 0000000..26d2edf --- /dev/null +++ b/include/arch/x86/symbolic-const.h @@ -0,0 +1,53 @@ +/** + * @file include/arch/x86/symbolic-const.h + * + * Macros for creating constants using mnemonics. + */ +#ifndef XTF_X86_SYMBOLIC_CONST_H +#define XTF_X86_SYMBOLIC_CONST_H + +#include + +#include + +/* Macro magic to expand symbolic SEG_ATTR names into a constant */ +#define _GDTE_ATTR0() (0) +#define _GDTE_ATTR1(x) (SEG_ATTR_ ## x) +#define _GDTE_ATTR2(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR1(__VA_ARGS__)) +#define _GDTE_ATTR3(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR2(__VA_ARGS__)) +#define _GDTE_ATTR4(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR3(__VA_ARGS__)) +#define _GDTE_ATTR5(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR4(__VA_ARGS__)) +#define _GDTE_ATTR6(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR5(__VA_ARGS__)) +#define _GDTE_ATTR7(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR6(__VA_ARGS__)) +#define _GDTE_ATTR8(x, ...) (SEG_ATTR_ ## x | _GDTE_ATTR7(__VA_ARGS__)) + +#define _GDTE_ATTR(...) VAR_MACRO(_GDTE_ATTR, __VA_ARGS__) + +/** + * Initialise an LDT/GDT entry using SEG_ATTR_ mnemonics. + * + * @param base Segment base. + * @param limit Segment limit. + * @param ... Partial SEG_ATTR_ tokens for attributes. + * + * Example usage: + * - INIT_GDTE_SYM(0, 0xfffff, P) + * - uses @ref SEG_ATTR_P + * + * - INIT_GDTE_SYM(0, 0xfffff, CODE, L) + * - uses @ref SEG_ATTR_CODE and @ref SEG_ATTR_L + */ +#define INIT_GDTE_SYM(base, limit, ...) \ + INIT_GDTE(base, limit, _GDTE_ATTR(__VA_ARGS__)) + +#endif /* XTF_X86_SYMBOLIC_CONST_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 2.39.5