Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/i386 Set up TSS gates per CPU for DDB IPI and ...



details:   https://anonhg.NetBSD.org/src/rev/20cabb5f4b41
branches:  trunk
changeset: 537787:20cabb5f4b41
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Sat Oct 05 21:18:44 2002 +0000

description:
Set up TSS gates per CPU for DDB IPI and double fault handlers.

diffstat:

 sys/arch/i386/i386/cpu.c |  70 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 69 insertions(+), 1 deletions(-)

diffs (109 lines):

diff -r 1b0b92876b8e -r 20cabb5f4b41 sys/arch/i386/i386/cpu.c
--- a/sys/arch/i386/i386/cpu.c  Sat Oct 05 21:17:35 2002 +0000
+++ b/sys/arch/i386/i386/cpu.c  Sat Oct 05 21:18:44 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.3 2002/10/02 05:47:09 thorpej Exp $ */
+/* $NetBSD: cpu.c,v 1.4 2002/10/05 21:18:44 fvdl Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -134,6 +134,9 @@
 
 struct cpu_info *cpu_info_list = &cpu_info_primary;
 
+static void    cpu_set_tss_gates(struct cpu_info *ci);
+static void    cpu_init_tss(struct i386tss *, void *, void *);
+
 #ifdef MULTIPROCESSOR
 /*
  * Array of CPU info structures.  Must be statically-allocated because
@@ -302,6 +305,7 @@
                ci->ci_flags |= CPUF_PRESENT | CPUF_SP | CPUF_PRIMARY;
                identifycpu(ci);
                cpu_init(ci);
+               cpu_set_tss_gates(ci);
                break;
 
        case CPU_ROLE_BP:
@@ -309,6 +313,7 @@
                ci->ci_flags |= CPUF_PRESENT | CPUF_BSP | CPUF_PRIMARY;
                identifycpu(ci);
                cpu_init(ci);
+               cpu_set_tss_gates(ci);
 
 #if NLAPIC > 0
                /*
@@ -330,6 +335,7 @@
 
 #if defined(MULTIPROCESSOR)
                gdt_alloc_cpu(ci);
+               cpu_set_tss_gates(ci);
                cpu_start_secondary(ci);
                if (ci->ci_flags & CPUF_PRESENT) {
                        identifycpu(ci);
@@ -627,3 +633,65 @@
 }
 
 #endif
+
+
+static void
+cpu_init_tss(struct i386tss *tss, void *stack, void *func)
+{
+       memset(tss, 0, sizeof *tss);
+       tss->tss_esp0 = tss->tss_esp = (int)((char *)stack + USPACE - 16);
+       tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
+       tss->__tss_cs = GSEL(GCODE_SEL, SEL_KPL);
+       tss->tss_fs = GSEL(GCPU_SEL, SEL_KPL);
+       tss->tss_gs = tss->__tss_es = tss->__tss_ds =
+           tss->__tss_ss = GSEL(GDATA_SEL, SEL_KPL);
+       tss->tss_cr3 = pmap_kernel()->pm_pdirpa;
+       tss->tss_esp = (int)((char *)stack + USPACE - 16);
+       tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
+       tss->__tss_eflags = PSL_MBO | PSL_NT;   /* XXX not needed? */
+       tss->__tss_eip = (int)func;
+}
+
+/* XXX */
+#define IDTVEC(name)   __CONCAT(X, name)
+typedef void (vector)(void);
+extern vector IDTVEC(tss_trap08);
+#ifdef DDB
+extern vector Xintr_tss_ddbipi;
+extern int ddb_vec;
+#endif
+
+static void
+cpu_set_tss_gates(struct cpu_info *ci)
+{
+       struct segment_descriptor sd;
+
+       ci->ci_doubleflt_stack = (char *)uvm_km_alloc(kernel_map, USPACE);
+       cpu_init_tss(&ci->ci_doubleflt_tss, ci->ci_doubleflt_stack,
+           IDTVEC(tss_trap08));
+       setsegment(&sd, &ci->ci_doubleflt_tss, sizeof(struct i386tss) - 1,
+           SDT_SYS386TSS, SEL_KPL, 0, 0);
+       ci->ci_gdt[GTRAPTSS_SEL].sd = sd;
+       setgate(&idt[8].gd, NULL, 0, SDT_SYSTASKGT, SEL_KPL,
+           GSEL(GTRAPTSS_SEL, SEL_KPL));
+
+#if defined(DDB) && defined(MULTIPROCESSOR)
+       /*
+        * Set up seperate handler for the DDB IPI, so that it doesn't
+        * stomp on a possibly corrupted stack.
+        *
+        * XXX overwriting the gate set in db_machine_init.
+        * Should rearrange the code so that it's set only once.
+        */
+       ci->ci_ddbipi_stack = (char *)uvm_km_alloc(kernel_map, USPACE);
+       cpu_init_tss(&ci->ci_ddbipi_tss, ci->ci_ddbipi_stack,
+           Xintr_tss_ddbipi);
+
+       setsegment(&sd, &ci->ci_ddbipi_tss, sizeof(struct i386tss) - 1,
+           SDT_SYS386TSS, SEL_KPL, 0, 0);
+       ci->ci_gdt[GIPITSS_SEL].sd = sd;
+
+       setgate(&idt[ddb_vec].gd, NULL, 0, SDT_SYSTASKGT, SEL_KPL,
+           GSEL(GIPITSS_SEL, SEL_KPL));
+#endif
+}



Home | Main Index | Thread Index | Old Index