diff options
Diffstat (limited to 'sys/amd64/amd64/machdep.c')
-rw-r--r-- | sys/amd64/amd64/machdep.c | 165 |
1 files changed, 87 insertions, 78 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 712996e4c179..ac02b7abdbab 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.330 1999/04/19 14:14:12 peter Exp $ + * $Id: machdep.c,v 1.331 1999/04/26 08:57:51 peter Exp $ */ #include "apm.h" @@ -114,6 +114,7 @@ #include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */ #ifdef SMP #include <machine/smp.h> +#include <machine/globaldata.h> #endif #ifdef PERFMON #include <machine/perfmon.h> @@ -552,6 +553,7 @@ sendsig(catcher, sig, mask, code) sf.sf_sc.sc_ds = regs->tf_ds; sf.sf_sc.sc_ss = regs->tf_ss; sf.sf_sc.sc_es = regs->tf_es; + sf.sf_sc.sc_fs = regs->tf_fs; sf.sf_sc.sc_isp = regs->tf_isp; /* @@ -616,6 +618,7 @@ sendsig(catcher, sig, mask, code) regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; } @@ -686,6 +689,7 @@ sigreturn(p, uap) tf->tf_vm86_gs = scp->sc_gs; tf->tf_ds = _udatasel; tf->tf_es = _udatasel; + tf->tf_fs = _udatasel; } else { #endif /* VM86 */ /* @@ -724,6 +728,7 @@ sigreturn(p, uap) } regs->tf_ds = scp->sc_ds; regs->tf_es = scp->sc_es; + regs->tf_fs = scp->sc_fs; #ifdef VM86 } #endif @@ -808,17 +813,16 @@ setregs(p, entry, stack, ps_strings) regs->tf_ss = _udatasel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_cs = _ucodesel; /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ regs->tf_ebx = ps_strings; - /* reset %fs and %gs as well */ - pcb->pcb_fs = _udatasel; + /* reset %gs as well */ pcb->pcb_gs = _udatasel; if (pcb == curpcb) { - __asm("movw %w0,%%fs" : : "r" (_udatasel)); - __asm("movw %w0,%%gs" : : "r" (_udatasel)); + load_gs(_udatasel); } /* @@ -887,7 +891,7 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, int _default_ldt; #ifdef SMP -union descriptor gdt[NGDT + NCPU]; /* global descriptor table */ +union descriptor gdt[NGDT * NCPU]; /* global descriptor table */ #else union descriptor gdt[NGDT]; /* global descriptor table */ #endif @@ -898,11 +902,11 @@ union descriptor ldt[NLDT]; /* local descriptor table */ struct region_descriptor r_gdt, r_idt; #endif -extern struct i386tss common_tss; /* One tss per cpu */ #ifdef VM86 +#ifndef SMP extern struct segment_descriptor common_tssd; -extern int private_tss; /* flag indicating private tss */ -extern u_int my_tr; /* which task register setting */ +#endif +int private_tss; /* flag indicating private tss */ #endif /* VM86 */ #if defined(I586_CPU) && !defined(NO_F00F_HACK) @@ -917,11 +921,7 @@ extern struct user *proc0paddr; /* software prototypes -- in more palatable form */ -struct soft_segment_descriptor gdt_segs[ -#ifdef SMP - NGDT + NCPU -#endif - ] = { +struct soft_segment_descriptor gdt_segs[] = { /* GNULL_SEL 0 Null Descriptor */ { 0x0, /* segment base address */ 0x0, /* length */ @@ -949,7 +949,26 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GLDT_SEL 3 LDT Descriptor */ +/* GPRIV_SEL 3 SMP Per-Processor Private Data Descriptor */ +{ 0x0, /* segment base address */ + 0xfffff, /* length - all address space */ + SDT_MEMRWA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GPROC0_SEL 4 Proc 0 Tss Descriptor */ +{ + 0x0, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ + SDT_SYS386TSS, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GLDT_SEL 5 LDT Descriptor */ { (int) ldt, /* segment base address */ sizeof(ldt)-1, /* length - all address space */ SDT_SYSLDT, /* segment type */ @@ -958,7 +977,16 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* unused - default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, -/* GTGATE_SEL 4 Null Descriptor - Placeholder */ +/* GUSERLDT_SEL 6 User LDT Descriptor per process */ +{ (int) ldt, /* segment base address */ + (512 * sizeof(union descriptor)-1), /* length */ + SDT_SYSLDT, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GTGATE_SEL 7 Null Descriptor - Placeholder */ { 0x0, /* segment base address */ 0x0, /* length - all address space */ 0, /* segment type */ @@ -967,7 +995,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, -/* GPANIC_SEL 5 Panic Tss Descriptor */ +/* GPANIC_SEL 8 Panic Tss Descriptor */ { (int) &dblfault_tss, /* segment base address */ sizeof(struct i386tss)-1,/* length - all address space */ SDT_SYS386TSS, /* segment type */ @@ -976,26 +1004,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* unused - default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, -/* GPROC0_SEL 6 Proc 0 Tss Descriptor */ -{ - (int) &common_tss, /* segment base address */ - sizeof(struct i386tss)-1,/* length - all address space */ - SDT_SYS386TSS, /* segment type */ - 0, /* segment descriptor priority level */ - 1, /* segment descriptor present */ - 0, 0, - 0, /* unused - default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GUSERLDT_SEL 7 User LDT Descriptor per process */ -{ (int) ldt, /* segment base address */ - (512 * sizeof(union descriptor)-1), /* length */ - SDT_SYSLDT, /* segment type */ - 0, /* segment descriptor priority level */ - 1, /* segment descriptor present */ - 0, 0, - 0, /* unused - default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GAPMCODE32_SEL 8 APM BIOS 32-bit interface (32bit Code) */ +/* GAPMCODE32_SEL 9 APM BIOS 32-bit interface (32bit Code) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMERA, /* segment type */ @@ -1004,7 +1013,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GAPMCODE16_SEL 9 APM BIOS 32-bit interface (16bit Code) */ +/* GAPMCODE16_SEL 10 APM BIOS 32-bit interface (16bit Code) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMERA, /* segment type */ @@ -1013,7 +1022,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GAPMDATA_SEL 10 APM BIOS 32-bit interface (Data) */ +/* GAPMDATA_SEL 11 APM BIOS 32-bit interface (Data) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMRWA, /* segment type */ @@ -1160,11 +1169,6 @@ init386(first) atdevbase = ISA_HOLE_START + KERNBASE; /* - * Initialize the console before we print anything out. - */ - cninit(); - - /* * make gdt memory segments, the code segment goes up to end of the * page with etext in it, the data segment goes to the end of * the address space @@ -1175,27 +1179,30 @@ init386(first) */ gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1; gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1; -#ifdef BDE_DEBUGGER -#define NGDT1 8 /* avoid overwriting db entries with APM ones */ +#ifdef SMP + gdt_segs[GPRIV_SEL].ssd_limit = + i386_btop(sizeof(struct privatespace)) - 1; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[0].globaldata.gd_common_tss; + SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0]; #else -#define NGDT1 (sizeof gdt_segs / sizeof gdt_segs[0]) + gdt_segs[GPRIV_SEL].ssd_limit = i386_btop(0) - 1; + gdt_segs[GPROC0_SEL].ssd_base = (int) &common_tss; #endif - for (x = 0; x < NGDT1; x++) - ssdtosd(&gdt_segs[x], &gdt[x].sd); -#ifdef VM86 - common_tssd = gdt[GPROC0_SEL].sd; -#endif /* VM86 */ -#ifdef SMP - /* - * Spin these up now. init_secondary() grabs them. We could use - * #for(x,y,z) / #endfor cpp directives if they existed. - */ - for (x = 0; x < NCPU; x++) { - gdt_segs[NGDT + x] = gdt_segs[GPROC0_SEL]; - ssdtosd(&gdt_segs[NGDT + x], &gdt[NGDT + x].sd); - } + for (x = 0; x < NGDT; x++) { +#ifdef BDE_DEBUGGER + /* avoid overwriting db entries with APM ones */ + if (x >= GAPMCODE32_SEL && x <= GAPMDATA_SEL) + continue; #endif + ssdtosd(&gdt_segs[x], &gdt[x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) gdt; + lgdt(&r_gdt); /* make ldt memory segments */ /* @@ -1221,6 +1228,12 @@ init386(first) for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++) ssdtosd(&ldt_segs[x], &ldt[x].sd); + _default_ldt = GSEL(GLDT_SEL, SEL_KPL); + lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif + /* exceptions */ for (x = 0; x < NIDT; x++) setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); @@ -1246,25 +1259,20 @@ init386(first) setidt(0x80, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); -#include "isa.h" -#if NISA >0 - isa_defaultirq(); -#endif - rand_initialize(); - - r_gdt.rd_limit = sizeof(gdt) - 1; - r_gdt.rd_base = (int) gdt; - lgdt(&r_gdt); - r_idt.rd_limit = sizeof(idt) - 1; r_idt.rd_base = (int) idt; lidt(&r_idt); - _default_ldt = GSEL(GLDT_SEL, SEL_KPL); - lldt(_default_ldt); -#ifdef USER_LDT - currentldt = _default_ldt; + /* + * Initialize the console before we print anything out. + */ + cninit(); + +#include "isa.h" +#if NISA >0 + isa_defaultirq(); #endif + rand_initialize(); #ifdef DDB kdb_init(); @@ -1289,7 +1297,7 @@ init386(first) ltr(gsel_tss); #ifdef VM86 private_tss = 0; - my_tr = GPROC0_SEL; + common_tssd = gdt[GPROC0_SEL].sd; #endif dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = @@ -1607,6 +1615,7 @@ init386(first) #ifdef VM86 proc0.p_addr->u_pcb.pcb_ext = 0; #endif + SET_CURPROC(&proc0); /* Sigh, relocate physical addresses left from bootstrap */ if (bootinfo.bi_modulep) { @@ -1732,6 +1741,7 @@ fill_regs(p, regs) struct trapframe *tp; tp = p->p_md.md_regs; + regs->r_fs = tp->tf_fs; regs->r_es = tp->tf_es; regs->r_ds = tp->tf_ds; regs->r_edi = tp->tf_edi; @@ -1747,7 +1757,6 @@ fill_regs(p, regs) regs->r_esp = tp->tf_esp; regs->r_ss = tp->tf_ss; pcb = &p->p_addr->u_pcb; - regs->r_fs = pcb->pcb_fs; regs->r_gs = pcb->pcb_gs; return (0); } @@ -1764,6 +1773,7 @@ set_regs(p, regs) if (!EFLAGS_SECURE(regs->r_eflags, tp->tf_eflags) || !CS_SECURE(regs->r_cs)) return (EINVAL); + tp->tf_fs = regs->r_fs; tp->tf_es = regs->r_es; tp->tf_ds = regs->r_ds; tp->tf_edi = regs->r_edi; @@ -1779,7 +1789,6 @@ set_regs(p, regs) tp->tf_esp = regs->r_esp; tp->tf_ss = regs->r_ss; pcb = &p->p_addr->u_pcb; - pcb->pcb_fs = regs->r_fs; pcb->pcb_gs = regs->r_gs; return (0); } |