diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-03-29 17:17:17 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-03-29 17:17:17 +0200 |
commit | 38149699cd27636b58d4b6539f7a6612783eb45c (patch) | |
tree | 94558d2e0d6910729b54f17961ed79e53f1ba1fe | |
parent | d3469ab5e83740fa9492bd3c87ebba3e242f06dd (diff) | |
parent | 4d79b40a53d855c41137fa44bcafa62f5ae9f55d (diff) |
Merge branch 'master' into master-x86_64
-rw-r--r-- | configfrag-first.ac | 29 | ||||
-rw-r--r-- | configfrag.ac | 13 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | i386/configfrag.ac | 19 | ||||
-rw-r--r-- | i386/i386/gdt.h | 59 | ||||
-rw-r--r-- | i386/i386/ktss.c | 10 | ||||
-rw-r--r-- | i386/i386/ldt.c | 12 | ||||
-rw-r--r-- | i386/i386/ldt.h | 9 | ||||
-rw-r--r-- | i386/i386/mp_desc.c | 7 | ||||
-rw-r--r-- | i386/i386/pcb.c | 3 | ||||
-rw-r--r-- | i386/i386/seg.h | 58 | ||||
-rw-r--r-- | x86_64/configfrag.ac | 15 |
12 files changed, 179 insertions, 58 deletions
diff --git a/configfrag-first.ac b/configfrag-first.ac new file mode 100644 index 00000000..5dc0db2c --- /dev/null +++ b/configfrag-first.ac @@ -0,0 +1,29 @@ +dnl Configure fragment for general options. + +dnl Copyright (C) 2020 Free Software Foundation, Inc. + +dnl Permission to use, copy, modify and distribute this software and its +dnl documentation is hereby granted, provided that both the copyright +dnl notice and this permission notice appear in all copies of the +dnl software, derivative works or modified versions, and any portions +dnl thereof, and that both notices appear in supporting documentation. +dnl +dnl THE FREE SOFTWARE FOUNDATION ALLOWS FREE USE OF THIS SOFTWARE IN ITS +dnl "AS IS" CONDITION. THE FREE SOFTWARE FOUNDATION DISCLAIMS ANY +dnl LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE +dnl USE OF THIS SOFTWARE. + +# +# Common options +# + +ncom=0 +nlpr=0 + +AC_ARG_ENABLE([pae], + AS_HELP_STRING([--enable-pae], [PAE support (ix86-only); on i386-at disabled + by default, otherwise enabled by default])) + +dnl Local Variables: +dnl mode: autoconf +dnl End: diff --git a/configfrag.ac b/configfrag.ac index 73c23ffb..91d737ef 100644 --- a/configfrag.ac +++ b/configfrag.ac @@ -26,6 +26,19 @@ AC_DEFINE([KERNEL], [1], [KERNEL]) # Formerly in `bogus/'. # +# i386/bogus/com.h +AC_DEFINE_UNQUOTED([NCOM], [$ncom], [NCOM]) + +# i386/bogus/lpr.h +AC_DEFINE_UNQUOTED([NLPR], [$nlpr], [NLPR]) + +[if [ x"$enable_pae" = xyes ]; then] + AC_DEFINE([PAE], [1], [PAE support]) + AM_CONDITIONAL([enable_pae], [true]) +[else] + AM_CONDITIONAL([enable_pae], [false]) +[fi] + # When set, the bootstrap task symbols are preserved by the kernel debugger. # Used in `kern/bootstrap.c'. AC_DEFINE([BOOTSTRAP_SYMBOLS], [0], [BOOTSTRAP_SYMBOLS]) diff --git a/configure.ac b/configure.ac index 49e16399..806a1da1 100644 --- a/configure.ac +++ b/configure.ac @@ -134,6 +134,9 @@ esac] # PC AT. # TODO. Currently handled in `i386/configfrag.ac'. +# General options. +m4_include([configfrag-first.ac]) + # Xen. m4_include([xen/configfrag.ac]) diff --git a/i386/configfrag.ac b/i386/configfrag.ac index 3c29bdf9..df5311e5 100644 --- a/i386/configfrag.ac +++ b/i386/configfrag.ac @@ -44,8 +44,6 @@ esac # Formerly in `i386/bogus/'. # -ncom=0 -nlpr=0 case $host_platform:$host_cpu in at:i?86) ncom=4 @@ -62,12 +60,6 @@ case $host_platform:$host_cpu in *) :;; esac] - -# i386/bogus/com.h -AC_DEFINE_UNQUOTED([NCOM], [$ncom], [NCOM]) - -# i386/bogus/lpr.h -AC_DEFINE_UNQUOTED([NLPR], [$nlpr], [NLPR]) # # Options. @@ -100,9 +92,6 @@ if [ x"$enable_lpr" = xyes ]; then] [fi] -AC_ARG_ENABLE([pae], - AS_HELP_STRING([--enable-pae], [PAE support (ix86-only); on ix86-at disabled - by default, on ix86-xen enabled by default])) [case $host_platform:$host_cpu in xen:i?86) enable_pae=${enable_pae-yes};; @@ -112,13 +101,7 @@ AC_ARG_ENABLE([pae], if [ x"$enable_pae" = xyes ]; then] AC_MSG_ERROR([can only enable the `PAE' feature on ix86.]) [fi;; -esac -if [ x"$enable_pae" = xyes ]; then] - AC_DEFINE([PAE], [1], [PAE support]) - AM_CONDITIONAL([enable_pae], [true]) -[else] - AM_CONDITIONAL([enable_pae], [false]) -[fi] +esac] AC_ARG_WITH([_START_MAP], AS_HELP_STRING([--with-_START_MAP=0x1000000], [specify kernel mapping start address]), diff --git a/i386/i386/gdt.h b/i386/i386/gdt.h index d865640b..9879ad3e 100644 --- a/i386/i386/gdt.h +++ b/i386/i386/gdt.h @@ -40,28 +40,79 @@ */ #define KERNEL_CS (0x08 | KERNEL_RING) /* kernel code */ #define KERNEL_DS (0x10 | KERNEL_RING) /* kernel data */ + + #ifndef MACH_PV_DESCRIPTORS #define KERNEL_LDT 0x18 /* master LDT */ #endif /* MACH_PV_DESCRIPTORS */ + +#ifdef __x86_64__ +/* LDT needs two entries */ +#define KERNEL_TSS 0x40 /* master TSS (uniprocessor) */ +#else #define KERNEL_TSS 0x20 /* master TSS (uniprocessor) */ +#endif + + #define USER_LDT 0x28 /* place for per-thread LDT */ + +#ifdef __x86_64__ +/* LDT needs two entries */ +#define USER_TSS 0x58 /* place for per-thread TSS + that holds IO bitmap */ +#else #define USER_TSS 0x30 /* place for per-thread TSS that holds IO bitmap */ +#endif + + #ifndef MACH_PV_DESCRIPTORS #define LINEAR_DS 0x38 /* linear mapping */ #endif /* MACH_PV_DESCRIPTORS */ -/* 0x40 was USER_FPREGS, now free */ -#define USER_GDT 0x48 /* user-defined GDT entries */ +/* 0x40 was USER_FPREGS, now used by TSS in 64bit mode */ + +#define USER_GDT 0x48 /* user-defined 32bit GDT entries */ #define USER_GDT_SLOTS 2 -#define GDTSZ (USER_GDT/8 + USER_GDT_SLOTS) +/* 0x58 used by user TSS in 64bit mode */ + +#ifdef __x86_64__ +#define GDTSZ sel_idx(0x60) +#else +#define GDTSZ sel_idx(0x58) +#endif extern struct real_descriptor gdt[GDTSZ]; /* Fill a segment descriptor in the GDT. */ +#define _fill_gdt_descriptor(_gdt, segment, base, limit, access, sizebits) \ + fill_descriptor(&_gdt[sel_idx(segment)], base, limit, access, sizebits) + #define fill_gdt_descriptor(segment, base, limit, access, sizebits) \ - fill_descriptor(&gdt[segment/8], base, limit, access, sizebits) + _fill_gdt_descriptor(gdt, segment, base, limit, access, sizebits) + +/* 64bit variant */ +#ifdef __x86_64__ +#define _fill_gdt_descriptor64(_gdt, segment, base, limit, access, sizebits) \ + fill_descriptor64((struct real_descriptor64 *) &_gdt[sel_idx(segment)], base, limit, access, sizebits) + +#define fill_gdt_descriptor64(segment, base, limit, access, sizebits) \ + _fill_gdt_descriptor64(gdt, segment, base, limit, access, sizebits) +#endif + +/* System descriptor variants */ +#ifdef __x86_64__ +#define _fill_gdt_sys_descriptor(_gdt, segment, base, limit, access, sizebits) \ + _fill_gdt_descriptor64(_gdt, segment, base, limit, access, sizebits) +#define fill_gdt_sys_descriptor(segment, base, limit, access, sizebits) \ + fill_gdt_descriptor64(segment, base, limit, access, sizebits) +#else +#define _fill_gdt_sys_descriptor(_gdt, segment, base, limit, access, sizebits) \ + _fill_gdt_descriptor(_gdt, segment, base, limit, access, sizebits) +#define fill_gdt_sys_descriptor(segment, base, limit, access, sizebits) \ + fill_gdt_descriptor(segment, base, limit, access, sizebits) +#endif extern void gdt_init(void); diff --git a/i386/i386/ktss.c b/i386/i386/ktss.c index 62de2a27..917e6305 100644 --- a/i386/i386/ktss.c +++ b/i386/i386/ktss.c @@ -51,14 +51,10 @@ ktss_init(void) if (hyp_stack_switch(KERNEL_DS, (unsigned long)(exception_stack+1024))) panic("couldn't register exception stack\n"); #else /* MACH_RING1 */ - -#ifdef __x86_64__ -#warning FIXME -#endif /* Initialize the master TSS descriptor. */ - fill_gdt_descriptor(KERNEL_TSS, - kvtolin(&ktss), sizeof(struct task_tss) - 1, - ACC_PL_K|ACC_TSS, 0); + fill_gdt_sys_descriptor(KERNEL_TSS, + kvtolin(&ktss), sizeof(struct task_tss) - 1, + ACC_PL_K|ACC_TSS, 0); /* Initialize the master TSS. */ ktss.tss.ss0 = KERNEL_DS; diff --git a/i386/i386/ldt.c b/i386/i386/ldt.c index 99d2f7fe..261df93a 100644 --- a/i386/i386/ldt.c +++ b/i386/i386/ldt.c @@ -47,22 +47,18 @@ struct real_descriptor ldt[LDTSZ]; void ldt_init(void) { -#ifdef __x86_64__ -#warning FIXME -#endif - #ifdef MACH_PV_DESCRIPTORS #ifdef MACH_PV_PAGETABLES pmap_set_page_readwrite(ldt); #endif /* MACH_PV_PAGETABLES */ #else /* MACH_PV_DESCRIPTORS */ /* Initialize the master LDT descriptor in the GDT. */ - fill_gdt_descriptor(KERNEL_LDT, - kvtolin(&ldt), sizeof(ldt)-1, - ACC_PL_K|ACC_LDT, 0); + fill_gdt_sys_descriptor(KERNEL_LDT, + kvtolin(&ldt), sizeof(ldt)-1, + ACC_PL_K|ACC_LDT, 0); #endif /* MACH_PV_DESCRIPTORS */ - /* Initialize the LDT descriptors. */ + /* Initialize the 32bit LDT descriptors. */ fill_ldt_gate(USER_SCALL, (vm_offset_t)&syscall, KERNEL_CS, ACC_PL_U|ACC_CALL_GATE, 0); diff --git a/i386/i386/ldt.h b/i386/i386/ldt.h index f196c74b..1f0d7014 100644 --- a/i386/i386/ldt.h +++ b/i386/i386/ldt.h @@ -43,6 +43,9 @@ * User descriptors for Mach - 32-bit flat address space */ #define USER_SCALL 0x07 /* system call gate */ +#ifdef __x86_64__ +/* Call gate needs two entries */ +#endif #define USER_CS 0x17 /* user code segment */ #define USER_DS 0x1f /* user data segment */ @@ -53,12 +56,12 @@ extern struct real_descriptor ldt[LDTSZ]; -/* Fill a segment descriptor in the LDT. */ +/* Fill a 32bit segment descriptor in the LDT. */ #define fill_ldt_descriptor(selector, base, limit, access, sizebits) \ - fill_descriptor(&ldt[selector/8], base, limit, access, sizebits) + fill_descriptor(&ldt[sel_idx(selector)], base, limit, access, sizebits) #define fill_ldt_gate(selector, offset, dest_selector, access, word_count) \ - fill_gate((struct real_gate*)&ldt[selector/8], \ + fill_gate((struct real_gate*)&ldt[sel_idx(selector)], \ offset, dest_selector, access, word_count) void ldt_init(void); diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c index d62d4958..07cc389a 100644 --- a/i386/i386/mp_desc.c +++ b/i386/i386/mp_desc.c @@ -146,14 +146,11 @@ mp_desc_init(int mycpu) #ifdef MACH_RING1 panic("TODO %s:%d\n",__FILE__,__LINE__); #else /* MACH_RING1 */ -#ifdef __x86_64__ -#warning FIXME -#endif - fill_descriptor(&mpt->gdt[sel_idx(KERNEL_LDT)], + _fill_gdt_sys_descriptor(mpt->gdt, KERNEL_LDT, (unsigned)&mpt->ldt, LDTSZ * sizeof(struct real_descriptor) - 1, ACC_P|ACC_PL_K|ACC_LDT, 0); - fill_descriptor(&mpt->gdt[sel_idx(KERNEL_TSS)], + _fill_gdt_sys_descriptor(mpt->gdt, KERNEL_TSS, (unsigned)&mpt->ktss, sizeof(struct task_tss) - 1, ACC_P|ACC_PL_K|ACC_TSS, 0); diff --git a/i386/i386/pcb.c b/i386/i386/pcb.c index 743108db..23585323 100644 --- a/i386/i386/pcb.c +++ b/i386/i386/pcb.c @@ -169,7 +169,8 @@ void switch_ktss(pcb_t pcb) #ifdef MACH_PV_DESCRIPTORS hyp_set_ldt(&ldt, LDTSZ); #else /* MACH_PV_DESCRIPTORS */ - set_ldt(KERNEL_LDT); + if (get_ldt() != KERNEL_LDT) + set_ldt(KERNEL_LDT); #endif /* MACH_PV_DESCRIPTORS */ } else { 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__ */ diff --git a/x86_64/configfrag.ac b/x86_64/configfrag.ac index 480028c8..817eff3d 100644 --- a/x86_64/configfrag.ac +++ b/x86_64/configfrag.ac @@ -28,7 +28,9 @@ dnl USE OF THIS SOFTWARE. AC_DEFINE([CPU_L1_SHIFT], [6], [CPU_L1_SHIFT]) [# Does the architecture provide machine-specific interfaces? - mach_machine_routines=1;; + mach_machine_routines=1 + + enable_pae=yes;; *)] AM_CONDITIONAL([HOST_x86_64], [false])[;; esac @@ -40,8 +42,6 @@ case $host_platform in AM_CONDITIONAL([PLATFORM_at], [false])[;; esac] -ncom=0 -nlpr=0 [case $host_platform:$host_cpu in at:x86_64)] ncom=4 @@ -52,15 +52,6 @@ nlpr=0 *) :;; esac] - -# i386/bogus/com.h -AC_DEFINE_UNQUOTED([NCOM], [$ncom], [NCOM]) - -# i386/bogus/lpr.h -AC_DEFINE_UNQUOTED([NLPR], [$nlpr], [NLPR]) - -AC_DEFINE([PAE], [1], [PAE support]) -AM_CONDITIONAL([enable_pae], [true]) dnl Local Variables: dnl mode: autoconf |