Make ddb's "mach cpu" command do the right thing: run ddb on the requested
cpu. There is a tiny bit of cheating involved, but I assume we won't run parallel + recursive ddb scripts to play towers of hanoi. This fixes the wrong prompt, and (more importantly) makes things like "mach dtlb" display the registers of the right MMU.
This commit is contained in:
parent
1b00238d8c
commit
54c5277e8e
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: intr.h,v 1.20 2008/01/15 10:35:33 martin Exp $ */
|
||||
/* $NetBSD: intr.h,v 1.21 2008/03/02 22:01:38 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -60,6 +60,7 @@ void save_and_clear_fpstate(struct lwp *);
|
|||
void sparc64_ipi_init (void);
|
||||
int sparc64_ipi_halt_thiscpu (void *);
|
||||
int sparc64_ipi_pause_thiscpu (void *);
|
||||
void sparc64_do_pause(void);
|
||||
void sparc64_ipi_drop_fpstate (void *);
|
||||
void sparc64_ipi_save_fpstate (void *);
|
||||
void sparc64_ipi_nop (void *);
|
||||
|
@ -67,6 +68,7 @@ void mp_halt_cpus (void);
|
|||
void mp_pause_cpus (void);
|
||||
void mp_resume_cpus (void);
|
||||
int mp_cpu_is_paused (sparc64_cpuset_t);
|
||||
void mp_resume_cpu(int);
|
||||
#endif
|
||||
|
||||
#endif /* _SPARC64_INTR_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: db_interface.c,v 1.108 2008/02/29 20:27:07 martin Exp $ */
|
||||
/* $NetBSD: db_interface.c,v 1.109 2008/03/02 22:01:38 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.108 2008/02/29 20:27:07 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.109 2008/03/02 22:01:38 martin Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
|
@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.108 2008/02/29 20:27:07 martin Ex
|
|||
#include <sys/user.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/atomic.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
|
@ -89,8 +90,9 @@ static uint64_t nil;
|
|||
#define pmap_ctx(PM) ((PM)->pm_ctx)
|
||||
#endif
|
||||
|
||||
static void fill_ddb_regs_from_tf(struct trapframe64 *tf);
|
||||
static void ddb_restore_state(void);
|
||||
void fill_ddb_regs_from_tf(struct trapframe64 *tf);
|
||||
void ddb_restore_state(void);
|
||||
bool ddb_running_on_this_cpu(void);
|
||||
|
||||
static int
|
||||
db_sparc_charop(const struct db_variable *vp, db_expr_t *val, int opcode)
|
||||
|
@ -303,42 +305,40 @@ static void db_print_trace_entry(struct traptrace *, int);
|
|||
#define NOCPU -1
|
||||
|
||||
static int db_suspend_others(void);
|
||||
static void db_resume_others(void);
|
||||
static void ddb_suspend(struct trapframe64 *);
|
||||
void db_resume_others(void);
|
||||
|
||||
__cpu_simple_lock_t db_lock;
|
||||
int ddb_cpu = NOCPU;
|
||||
|
||||
bool
|
||||
ddb_running_on_this_cpu(void)
|
||||
{
|
||||
return ddb_cpu == cpu_number();
|
||||
}
|
||||
|
||||
static int
|
||||
db_suspend_others(void)
|
||||
{
|
||||
int cpu_me = cpu_number();
|
||||
int win;
|
||||
bool win;
|
||||
|
||||
if (cpus == NULL)
|
||||
return 1;
|
||||
|
||||
__cpu_simple_lock(&db_lock);
|
||||
if (ddb_cpu == NOCPU)
|
||||
ddb_cpu = cpu_me;
|
||||
win = (ddb_cpu == cpu_me);
|
||||
__cpu_simple_unlock(&db_lock);
|
||||
|
||||
win = atomic_cas_32(&ddb_cpu, NOCPU, cpu_me) == (uint32_t)NOCPU;
|
||||
if (win)
|
||||
mp_pause_cpus();
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
db_resume_others(void)
|
||||
{
|
||||
int cpu_me = cpu_number();
|
||||
|
||||
mp_resume_cpus();
|
||||
|
||||
__cpu_simple_lock(&db_lock);
|
||||
ddb_cpu = NOCPU;
|
||||
__cpu_simple_unlock(&db_lock);
|
||||
if (atomic_cas_32(&ddb_cpu, cpu_me, NOCPU) == cpu_me)
|
||||
mp_resume_cpus();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -361,7 +361,7 @@ kdb_kbd_trap(struct trapframe64 *tf)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
fill_ddb_regs_from_tf(struct trapframe64 *tf)
|
||||
{
|
||||
extern int savetstate(struct trapstate *);
|
||||
|
@ -416,7 +416,7 @@ fill_ddb_regs_from_tf(struct trapframe64 *tf)
|
|||
DDB_REGS->db_tl = savetstate(&DDB_REGS->db_ts[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
ddb_restore_state()
|
||||
{
|
||||
extern void restoretstate(int, struct trapstate *);
|
||||
|
@ -445,8 +445,6 @@ kdb_trap(int type, struct trapframe64 *tf)
|
|||
#endif
|
||||
switch (type) {
|
||||
case T_BREAKPOINT: /* breakpoint */
|
||||
printf("cpu%d: kdb breakpoint at %llx\n", cpu_number(),
|
||||
(unsigned long long)tf->tf_pc);
|
||||
break;
|
||||
case -1: /* keyboard interrupt */
|
||||
printf("kdb tf=%p\n", tf);
|
||||
|
@ -1154,10 +1152,6 @@ db_cpu_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
|
|||
return;
|
||||
}
|
||||
#ifdef MULTIPROCESSOR
|
||||
if ((addr < 0) || (addr >= sparc_ncpus)) {
|
||||
db_printf("%ld: CPU out of range\n", addr);
|
||||
return;
|
||||
}
|
||||
for (ci = cpus; ci != NULL; ci = ci->ci_next)
|
||||
if (ci->ci_index == addr)
|
||||
break;
|
||||
|
@ -1170,12 +1164,11 @@ db_cpu_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
|
|||
db_printf("CPU %ld not paused\n", addr);
|
||||
return;
|
||||
}
|
||||
/* no locking needed - all other cpus are paused */
|
||||
ddb_cpu = ci->ci_index;
|
||||
mp_resume_cpu(ddb_cpu);
|
||||
sparc64_do_pause();
|
||||
}
|
||||
if (ci->ci_ddb_regs == NULL) {
|
||||
db_printf("CPU %ld has no saved regs\n", addr);
|
||||
return;
|
||||
}
|
||||
db_printf("using CPU %ld", addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipifuncs.c,v 1.13 2008/02/22 10:55:00 martin Exp $ */
|
||||
/* $NetBSD: ipifuncs.c,v 1.14 2008/03/02 22:01:38 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.13 2008/02/22 10:55:00 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.14 2008/03/02 22:01:38 martin Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
|
@ -55,7 +55,10 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.13 2008/02/22 10:55:00 martin Exp $")
|
|||
#define sparc64_ipi_sleep() delay(1000)
|
||||
|
||||
#if defined(DDB) || defined(KGDB)
|
||||
extern int db_active;
|
||||
#ifdef DDB
|
||||
#include <ddb/db_command.h>
|
||||
#include <ddb/db_output.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* CPU sets containing halted, paused and resumed cpus */
|
||||
|
@ -91,47 +94,56 @@ sparc64_ipi_halt_thiscpu(void *arg)
|
|||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
sparc64_do_pause(void)
|
||||
{
|
||||
#if defined(DDB)
|
||||
extern bool ddb_running_on_this_cpu(void);
|
||||
extern void db_resume_others(void);
|
||||
#endif
|
||||
|
||||
CPUSET_ADD(cpus_paused, cpu_number());
|
||||
|
||||
do {
|
||||
membar_sync();
|
||||
} while(CPUSET_HAS(cpus_paused, cpu_number()));
|
||||
membar_sync();
|
||||
CPUSET_ADD(cpus_resumed, cpu_number());
|
||||
|
||||
#if defined(DDB)
|
||||
if (ddb_running_on_this_cpu()) {
|
||||
db_command_loop();
|
||||
db_resume_others();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Pause cpu. This is called from locore.s after setting up a trapframe.
|
||||
*/
|
||||
int
|
||||
sparc64_ipi_pause_thiscpu(void *arg)
|
||||
{
|
||||
cpuid_t cpuid;
|
||||
int s;
|
||||
#if defined(DDB)
|
||||
struct trapframe64 *tf = arg;
|
||||
volatile db_regs_t dbregs;
|
||||
extern void fill_ddb_regs_from_tf(struct trapframe64 *tf);
|
||||
extern void ddb_restore_state(void);
|
||||
|
||||
if (arg)
|
||||
fill_ddb_regs_from_tf(arg);
|
||||
#endif
|
||||
|
||||
if (tf) {
|
||||
/* Initialise local dbregs storage from trap frame */
|
||||
dbregs.db_tf = *tf;
|
||||
dbregs.db_fr = *(struct frame64 *)(u_long)tf->tf_out[6];
|
||||
s = intr_disable();
|
||||
sparc64_do_pause();
|
||||
|
||||
curcpu()->ci_ddb_regs = &dbregs;
|
||||
#if defined(DDB)
|
||||
if (arg) {
|
||||
ddb_restore_state();
|
||||
curcpu()->ci_ddb_regs = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
cpuid = cpu_number();
|
||||
printf("cpu%ld paused.\n", cpuid);
|
||||
|
||||
s = intr_disable();
|
||||
CPUSET_ADD(cpus_paused, cpuid);
|
||||
|
||||
do {
|
||||
membar_sync();
|
||||
} while(CPUSET_HAS(cpus_paused, cpuid));
|
||||
membar_sync();
|
||||
|
||||
CPUSET_ADD(cpus_resumed, cpuid);
|
||||
|
||||
#if defined(DDB)
|
||||
if (tf)
|
||||
curcpu()->ci_ddb_regs = NULL;
|
||||
#endif
|
||||
|
||||
intr_restore(s);
|
||||
printf("cpu%ld resumed.\n", cpuid);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -218,12 +230,9 @@ sparc64_send_ipi(int upaid, ipifunc_t func, uint64_t arg1)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!db_active && panicstr == NULL)
|
||||
if (panicstr == NULL)
|
||||
panic("cpu%d: ipi_send: couldn't send ipi to UPAID %u",
|
||||
cpu_number(), upaid);
|
||||
else
|
||||
printf("\noops, can't send IPI from cpu%d to UPAID %u\n",
|
||||
cpu_number(), upaid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -283,6 +292,16 @@ mp_pause_cpus()
|
|||
sparc64_ipi_error("pause", cpus_paused, cpuset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Resume a single cpu
|
||||
*/
|
||||
void
|
||||
mp_resume_cpu(int cno)
|
||||
{
|
||||
CPUSET_DEL(cpus_paused, cno);
|
||||
membar_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Resume all paused cpus.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue