Add rudimentary multiprocessor support for DDB.

This commit is contained in:
ragge 2001-06-04 21:37:11 +00:00
parent cae5d5a796
commit f81f19e7b3
5 changed files with 167 additions and 65 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.59 2001/06/04 15:34:15 ragge Exp $ */
/* $NetBSD: cpu.h,v 1.60 2001/06/04 21:37:12 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden
@ -94,6 +94,7 @@ struct cpu_mp_dep {
#define IPI_SEND_CNCHAR 2 /* Write char to console, kernel printf */
#define IPI_RUNNING 3 /* This CPU just started to run */
#define IPI_TBIA 4 /* Flush the TLB */
#define IPI_DDB 5 /* Jump into the DDB loop */
#define IPI_DEST_MASTER -1 /* Destination is mastercpu */
#define IPI_DEST_ALL -2 /* Broadcast */
@ -133,10 +134,12 @@ struct cpu_info {
vaddr_t ci_istack; /* Interrupt stack location */
int ci_flags; /* See below */
long ci_ipimsgs; /* Sent IPI bits */
struct trapframe *ci_ddb_regs; /* Used by DDB */
#endif
};
#define CI_MASTERCPU 1 /* Set if master CPU */
#define CI_RUNNING 2 /* Set when a slave CPU is running */
#define CI_STOPPED 4 /* Stopped (in debugger) */
#if defined(MULTIPROCESSOR)
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_machdep.h,v 1.9 2001/05/02 15:59:38 matt Exp $ */
/* $NetBSD: db_machdep.h,v 1.10 2001/06/04 21:37:12 ragge Exp $ */
/*
* Mach Operating System
@ -71,6 +71,8 @@ db_regs_t ddb_regs; /* register state */
#define inst_load(ins) 0
#define inst_store(ins) 0
#define DB_MACHINE_COMMANDS
/* Prototypes */
void kdb_trap __P((struct trapframe *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: lock.h,v 1.7 2001/06/04 15:37:05 ragge Exp $ */
/* $NetBSD: lock.h,v 1.8 2001/06/04 21:37:12 ragge Exp $ */
/*
* Copyright (c) 2000 Ludd, University of Lule}, Sweden.
@ -70,6 +70,7 @@ __cpu_simple_lock_try(__cpu_simple_lock_t *alp)
return ret;
}
#define VAX_LOCK_CHECKS ((1 << IPI_SEND_CNCHAR) | (1 << IPI_DDB))
#define __cpu_simple_lock(alp) \
{ \
struct cpu_info *__ci = curcpu(); \
@ -77,7 +78,7 @@ __cpu_simple_lock_try(__cpu_simple_lock_t *alp)
while (__cpu_simple_lock_try(alp) == 0) { \
int __s; \
\
if (__ci->ci_ipimsgs & (1 << IPI_SEND_CNCHAR)) { \
if (__ci->ci_ipimsgs & VAX_LOCK_CHECKS) { \
__s = splipi(); \
cpu_handle_ipi(); \
splx(__s); \

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_machdep.c,v 1.28 2001/04/29 22:17:24 matt Exp $ */
/* $NetBSD: db_machdep.c,v 1.29 2001/06/04 21:37:11 ragge Exp $ */
/*
* :set tabs=4
@ -38,6 +38,7 @@
* Taken from i386 port and modified for vax.
*/
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/proc.h>
@ -49,11 +50,11 @@
#include <dev/cons.h>
#include <machine/cpu.h>
#include <machine/db_machdep.h>
#include <machine/trap.h>
#include <machine/frame.h>
#include <machine/pcb.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <vax/vax/gencons.h>
@ -65,15 +66,57 @@
#include <ddb/db_interface.h>
#include <ddb/db_variables.h>
#include "ioconf.h"
extern label_t *db_recover;
void kdbprinttrap __P((int, int));
void kdbprinttrap(int, int);
int db_active = 0;
extern int qdpolling;
static int splsave; /* IPL before entering debugger */
#ifdef MULTIPROCESSOR
static struct cpu_info *stopcpu;
/*
* Only the master CPU is allowed to enter DDB, but the correct frames
* must still be there. Keep the state-machine here.
*/
static int
pause_cpus(void)
{
volatile struct cpu_info *ci = curcpu();
if (stopcpu == NULL) {
stopcpu = curcpu();
cpu_send_ipi(IPI_DEST_ALL, IPI_DDB);
}
if ((ci->ci_flags & CI_MASTERCPU) == 0) {
ci->ci_flags |= CI_STOPPED;
while (ci->ci_flags & CI_STOPPED)
;
return 1;
} else
return 0;
}
static void
resume_cpus(void)
{
struct cpu_mp_softc *sc;
struct cpu_info *ci;
int i;
stopcpu = NULL;
for (i = 0; i < cpu_cd.cd_ndevs; i++) {
if ((sc = cpu_cd.cd_devs[i]) == NULL)
continue;
ci = &sc->sc_ci;
ci->ci_flags &= ~CI_STOPPED;
}
}
#endif
/*
* VAX Call frame on the stack, this from
* "Computer Programming and Architecture, The VAX-11"
@ -100,10 +143,12 @@ typedef struct __vax_frame {
* contain the registers when panic was called. (easy to debug).
*/
void
kdb_trap(frame)
struct trapframe *frame;
kdb_trap(struct trapframe *frame)
{
int s;
#ifdef MULTIPROCESSOR
struct cpu_info *ci = curcpu();
#endif
switch (frame->trap) {
case T_BPTFLT: /* breakpoint */
@ -112,6 +157,7 @@ kdb_trap(frame)
/* XXX todo: should be migrated to use VAX_CALLFRAME at some point */
case T_KDBTRAP:
#ifndef MULTIPROCESSOR /* No fancy panic stack conversion here */
if (panicstr) {
struct callsframe *pf, *df;
@ -126,6 +172,7 @@ kdb_trap(frame)
ddb_regs.psl |= pf->ca_maskpsw & 0xffe0;
ddb_regs.psl |= (splsave << 16);
}
#endif
break;
default:
@ -139,8 +186,18 @@ kdb_trap(frame)
}
}
#ifdef MULTIPROCESSOR
ci->ci_ddb_regs = frame;
if (pause_cpus())
return;
#endif
#ifndef MULTIPROCESSOR
if (!panicstr)
bcopy(frame, &ddb_regs, sizeof(struct trapframe));
#else
bcopy(stopcpu->ci_ddb_regs, &ddb_regs, sizeof(struct trapframe));
printf("stopped on cpu %d\n", stopcpu->ci_cpuid);
#endif
/* XXX Should switch to interrupt stack here, if needed. */
@ -152,11 +209,16 @@ kdb_trap(frame)
db_active--;
splx(s);
#ifndef MULTIPROCESSOR
if (!panicstr)
bcopy(&ddb_regs, frame, sizeof(struct trapframe));
#else
bcopy(&ddb_regs, stopcpu->ci_ddb_regs, sizeof(struct trapframe));
#endif
frame->sp = mfpr(PR_USP);
return;
#ifdef MULTIPROCESSOR
resume_cpus();
#endif
}
extern char *traptypes[];
@ -331,7 +393,7 @@ db_dump_stack(VAX_CALLFRAME *fp, u_int stackbase,
* Implement the trace command which has the form:
*
* trace <-- Trace panic (same as before)
* trace 0x88888 <-- Trace process whose address is 888888
* trace 0x88888 <-- Trace frame whose address is 888888
* trace/t <-- Trace current process (0 if no current proc)
* trace/t 0tnn <-- Trace process nn (0t for decimal)
*/
@ -366,7 +428,11 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
}
(*pr)("panic: %s\n", panicstr);
/* xxx ? where did we panic and whose stack are we using? */
#ifdef MULTIPROCESSOR
db_dump_stack((VAX_CALLFRAME *)(ddb_regs.fp), ddb_regs.ap, pr);
#else
db_dump_stack((VAX_CALLFRAME *)(ddb_regs.sp), ddb_regs.ap, pr);
#endif
return;
}
@ -398,12 +464,9 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
}
}
} else {
p = (struct proc *)(addr);
if (pfind(p->p_pid) != p) {
(*pr)(" This address does not point to a valid process.\n");
db_dump_stack((VAX_CALLFRAME *)addr, 0, pr);
return;
}
}
} else {
if (trace_proc) {
p = curproc;
@ -553,3 +616,31 @@ kdbrint(tkn)
return 0;
}
#ifdef MULTIPROCESSOR
static void
db_mach_cpu(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
{
struct cpu_mp_softc *sc;
struct cpu_info *ci;
if ((addr < 0) || (addr >= cpu_cd.cd_ndevs))
return db_printf("%ld: cpu out of range\n", addr);
if ((sc = cpu_cd.cd_devs[addr]) == NULL)
return db_printf("%ld: cpu not configured\n", addr);
ci = &sc->sc_ci;
if ((ci != curcpu()) && ((ci->ci_flags & CI_STOPPED) == 0))
return db_printf("cpu %ld not stopped???\n", addr);
bcopy(&ddb_regs, stopcpu->ci_ddb_regs, sizeof(struct trapframe));
stopcpu = ci;
bcopy(stopcpu->ci_ddb_regs, &ddb_regs, sizeof(struct trapframe));
db_printf("using cpu %ld", addr);
}
const struct db_command db_machine_command_table[] = {
{ "cpu", db_mach_cpu, 0, 0 },
{ (char *)0, },
};
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: multicpu.c,v 1.8 2001/06/04 15:34:16 ragge Exp $ */
/* $NetBSD: multicpu.c,v 1.9 2001/06/04 21:37:11 ragge Exp $ */
/*
* Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
@ -221,6 +221,11 @@ cpu_handle_ipi()
case IPI_TBIA:
mtpr(0, PR_TBIA);
break;
case IPI_DDB:
Debugger();
break;
default:
panic("cpu_handle_ipi: bad bit %x\n", bitno);
}
}
}