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