summaryrefslogtreecommitdiff
path: root/i386/i386/seg.h
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386/seg.h')
-rw-r--r--i386/i386/seg.h58
1 files changed, 58 insertions, 0 deletions
diff --git a/i386/i386/seg.h b/i386/i386/seg.h
index 6f3d5af9..b1a14fe4 100644
--- a/i386/i386/seg.h
+++ b/i386/i386/seg.h
@@ -59,12 +59,32 @@ struct real_descriptor {
base_high:8; /* base 24..31 */
};
+#ifdef __x86_64__
+struct real_descriptor64 {
+ unsigned int limit_low:16, /* limit 0..15 */
+ base_low:16, /* base 0..15 */
+ base_med:8, /* base 16..23 */
+ access:8, /* access byte */
+ limit_high:4, /* limit 16..19 */
+ granularity:4, /* granularity */
+ base_high:8, /* base 24..31 */
+ base_ext:32, /* base 32..63 */
+ reserved1:8,
+ zero:5,
+ reserved2:19;
+};
+#endif
+
struct real_gate {
unsigned int offset_low:16, /* offset 0..15 */
selector:16,
word_count:8,
access:8,
offset_high:16; /* offset 16..31 */
+#ifdef __x86_64__
+ unsigned int offset_ext:32, /* offset 32..63 */
+ reserved:32;
+#endif
};
#endif /* !__ASSEMBLER__ */
@@ -185,6 +205,40 @@ fill_descriptor(struct real_descriptor *_desc, unsigned base, unsigned limit,
#endif /* MACH_PV_DESCRIPTORS */
}
+#ifdef __x86_64__
+MACH_INLINE void
+fill_descriptor64(struct real_descriptor64 *_desc, unsigned long base, unsigned limit,
+ unsigned char access, unsigned char sizebits)
+{
+ /* TODO: when !MACH_PV_DESCRIPTORS, setting desc and just memcpy isn't simpler actually */
+#ifdef MACH_PV_DESCRIPTORS
+ struct real_descriptor64 __desc, *desc = &__desc;
+#else /* MACH_PV_DESCRIPTORS */
+ struct real_descriptor64 *desc = _desc;
+#endif /* MACH_PV_DESCRIPTORS */
+ if (limit > 0xfffff)
+ {
+ limit >>= 12;
+ sizebits |= SZ_G;
+ }
+ desc->limit_low = limit & 0xffff;
+ desc->base_low = base & 0xffff;
+ desc->base_med = (base >> 16) & 0xff;
+ desc->access = access | ACC_P;
+ desc->limit_high = limit >> 16;
+ desc->granularity = sizebits;
+ desc->base_high = base >> 24;
+ desc->base_ext = base >> 32;
+ desc->reserved1 = 0;
+ desc->zero = 0;
+ desc->reserved2 = 0;
+#ifdef MACH_PV_DESCRIPTORS
+ if (hyp_do_update_descriptor(kv_to_ma(_desc), *(uint64_t*)desc))
+ panic("couldn't update descriptor(%lu to %08lx%08lx)\n", (vm_offset_t) kv_to_ma(_desc), *(((unsigned long*)desc)+1), *(unsigned long *)desc);
+#endif /* MACH_PV_DESCRIPTORS */
+}
+#endif
+
/* Fill a gate with particular values. */
MACH_INLINE void
fill_gate(struct real_gate *gate, unsigned offset, unsigned short selector,
@@ -195,6 +249,10 @@ fill_gate(struct real_gate *gate, unsigned offset, unsigned short selector,
gate->word_count = word_count;
gate->access = access | ACC_P;
gate->offset_high = (offset >> 16) & 0xffff;
+#ifdef __x86_64__
+ gate->offset_ext = offset >> 32;
+ gate->reserved = 0;
+#endif
}
#endif /* !__ASSEMBLER__ */