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