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 Deal with coming in via a TSS.



details:   https://anonhg.NetBSD.org/src/rev/661fe94246fa
branches:  trunk
changeset: 537788:661fe94246fa
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Sat Oct 05 21:19:16 2002 +0000

description:
Deal with coming in via a TSS.

diffstat:

 sys/arch/i386/i386/db_interface.c |  48 +++++++++++++++++++++++++++++++++-----
 sys/arch/i386/i386/db_trace.c     |  39 ++++++++++++++++++++++++++-----
 2 files changed, 73 insertions(+), 14 deletions(-)

diffs (228 lines):

diff -r 20cabb5f4b41 -r 661fe94246fa sys/arch/i386/i386/db_interface.c
--- a/sys/arch/i386/i386/db_interface.c Sat Oct 05 21:18:44 2002 +0000
+++ b/sys/arch/i386/i386/db_interface.c Sat Oct 05 21:19:16 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_interface.c,v 1.36 2002/10/01 12:56:49 fvdl Exp $   */
+/*     $NetBSD: db_interface.c,v 1.37 2002/10/05 21:19:16 fvdl Exp $   */
 
 /*
  * Mach Operating System
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.36 2002/10/01 12:56:49 fvdl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.37 2002/10/05 21:19:16 fvdl Exp $");
 
 #include "opt_ddb.h"
 
@@ -79,6 +79,7 @@
 void kdbprinttrap __P((int, int));
 #ifdef MULTIPROCESSOR
 extern void ddb_ipi(int, struct trapframe);
+extern void ddb_ipi_tss(struct i386tss *);
 static void ddb_suspend(struct trapframe *);
 int ddb_vec;
 #endif
@@ -99,7 +100,7 @@
 #ifdef MULTIPROCESSOR
        ddb_vec = idt_vec_alloc(0xf0, 0xff);
        setgate((struct gate_descriptor *)&idt[ddb_vec], &Xintrddbipi, 0,
-           SDT_SYS386IGT, SEL_KPL);
+           SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
 #endif
 }
 
@@ -171,9 +172,12 @@
        int type, code;
        db_regs_t *regs;
 {
-       int s;
+       int s, flags;
        db_regs_t dbreg;
 
+       flags = regs->tf_err & TC_FLAGMASK;
+       regs->tf_err &= ~TC_FLAGMASK;
+
        switch (type) {
        case T_BPTFLT:  /* breakpoint */
        case T_TRCTRAP: /* single_step */
@@ -200,7 +204,7 @@
 #endif
        /* XXX Should switch to kdb's own stack here. */
        ddb_regs = *regs;
-       if (KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
+       if (!(flags & TC_TSS) && KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
                /*
                 * Kernel mode - esp and ss not saved
                 */
@@ -241,7 +245,7 @@
        regs->tf_eip    = ddb_regs.tf_eip;
        regs->tf_cs     = ddb_regs.tf_cs;
        regs->tf_eflags = ddb_regs.tf_eflags;
-       if (!KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
+       if (!(flags & TC_TSS) && !KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
                /* ring transit - saved esp and ss valid */
                regs->tf_esp    = ddb_regs.tf_esp;
                regs->tf_ss     = ddb_regs.tf_ss;
@@ -276,14 +280,44 @@
        ddb_suspend(&frame);
 }
 
+void
+ddb_ipi_tss(struct i386tss *tss)
+{
+       struct trapframe tf;
+
+       tf.tf_gs = tss->tss_gs;
+       tf.tf_fs = tss->tss_fs;
+       tf.tf_es = tss->__tss_es;
+       tf.tf_ds = tss->__tss_ds;
+       tf.tf_edi = tss->__tss_edi;
+       tf.tf_esi = tss->__tss_esi;
+       tf.tf_ebp = tss->tss_ebp;
+       tf.tf_ebx = tss->__tss_ebx;
+       tf.tf_edx = tss->__tss_edx;
+       tf.tf_ecx = tss->__tss_ecx;
+       tf.tf_eax = tss->__tss_eax;
+       tf.tf_trapno = 0;
+       tf.tf_err = TC_TSS;
+       tf.tf_eip = tss->__tss_eip;
+       tf.tf_cs = tss->__tss_cs;
+       tf.tf_eflags = tss->__tss_eflags;
+       tf.tf_esp = tss->tss_esp;
+       tf.tf_ss = tss->__tss_ss;
+
+       ddb_suspend(&tf);
+}
+
 static void
 ddb_suspend(struct trapframe *frame)
 {
        volatile struct cpu_info *ci = curcpu();
        db_regs_t regs;
+       int flags;
 
        regs = *frame;
-       if (KERNELMODE(regs.tf_cs, regs.tf_eflags)) {
+       flags = regs.tf_err & TC_FLAGMASK;
+       regs.tf_err &= ~TC_FLAGMASK;
+       if (!(flags & TC_TSS) && KERNELMODE(regs.tf_cs, regs.tf_eflags)) {
                /*
                 * Kernel mode - esp and ss not saved
                 */
diff -r 20cabb5f4b41 -r 661fe94246fa sys/arch/i386/i386/db_trace.c
--- a/sys/arch/i386/i386/db_trace.c     Sat Oct 05 21:18:44 2002 +0000
+++ b/sys/arch/i386/i386/db_trace.c     Sat Oct 05 21:19:16 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_trace.c,v 1.33 2002/10/01 12:56:50 fvdl Exp $       */
+/*     $NetBSD: db_trace.c,v 1.34 2002/10/05 21:19:16 fvdl Exp $       */
 
 /* 
  * Mach Operating System
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.33 2002/10/01 12:56:50 fvdl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.34 2002/10/05 21:19:16 fvdl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -105,6 +105,8 @@
 #define        TRAP            1
 #define        SYSCALL         2
 #define        INTERRUPT       3
+#define INTERRUPT_TSS  4
+#define TRAP_TSS       5
 
 db_addr_t      db_trap_symbol_value = 0;
 db_addr_t      db_syscall_symbol_value = 0;
@@ -167,6 +169,7 @@
  *   It might be possible to dig out from the next frame up the name
  *   of the function that faulted, but that could get hairy.
  */
+
 void
 db_nextframe(fp, ip, argp, is_trap, pr)
        struct i386_frame **fp;         /* in/out */
@@ -175,6 +178,8 @@
        int is_trap;                    /* in */
        void (*pr) __P((const char *, ...)); /* in */
 {
+       struct trapframe *tf;
+       struct i386tss *tss;
 
        switch (is_trap) {
            case NONE:
@@ -184,8 +189,21 @@
                        db_get_value((int) &(*fp)->f_frame, 4, FALSE);
                break;
 
-           default: {
-               struct trapframe *tf;
+           case TRAP_TSS:
+           case INTERRUPT_TSS:
+               tss = (struct i386tss *)*argp;
+               *ip = tss->__tss_eip;
+               *fp = (struct i386_frame *)tss->tss_ebp;
+               if (is_trap == INTERRUPT_TSS)
+                       printf("--- interrupt via task gate ---\n");
+               else
+                       printf("--- trap via task gate ---\n");
+               break;
+
+           case TRAP:
+           case SYSCALL:
+           case INTERRUPT:
+           default:
 
                /* The only argument to trap() or syscall() is the trapframe. */
                tf = (struct trapframe *)argp;
@@ -203,7 +221,6 @@
                *fp = (struct i386_frame *)tf->tf_ebp;
                *ip = (db_addr_t)tf->tf_eip;
                break;
-           }
        }
 }
 
@@ -298,7 +315,9 @@
                         * (e.g., npxdna) don't go through trap()
                         */
 #ifdef __ELF__
-                       if (!strcmp(name, "trap")) {
+                       if (!strcmp(name, "trap_tss")) {
+                               is_trap = TRAP_TSS;
+                       } else if (!strcmp(name, "trap")) {
                                is_trap = TRAP;
                        } else if (!strcmp(name, "syscall")) {
                                is_trap = SYSCALL;
@@ -311,13 +330,17 @@
                                    !strcmp(name, "Xdoreti") ||
                                    !strncmp(name, "Xsoft", 5)) {
                                        is_trap = INTERRUPT;
+                               } else if (!strncmp(name, "Xtss_", 5)) {
+                                       is_trap = INTERRUPT_TSS;
                                } else
                                        goto normal;
                        } else
                                goto normal;
                        narg = 0;
 #else
-                       if (!strcmp(name, "_trap")) {
+                       if (!strcmp(name, "_trap_tss")) {
+                               is_trap = TRAP_TSS;
+                       } else if (!strcmp(name, "_trap")) {
                                is_trap = TRAP;
                        } else if (!strcmp(name, "_syscall")) {
                                is_trap = SYSCALL;
@@ -330,6 +353,8 @@
                                    !strcmp(name, "_Xdoreti") ||
                                    !strncmp(name, "_Xsoft", 6)) {
                                        is_trap = INTERRUPT;
+                               } else if (!strncmp(name, "_Xtss_", 6)) {
+                                       is_trap = INTERRUPT_TSS;
                                } else
                                        goto normal;
                        } else



Home | Main Index | Thread Index | Old Index