SMP cleanup. provide support for multiple CPUs in DDB. (SMP itself

is still not working.)

cpu.h:
- add a pointer for DDB regs in SMP environment to struct cpu_info
- remove the #defines for mp_pause_cpus() and mp_resume_cpus()
cpuset.h:
- remove CPUSET_ALL() and rename CPUSET_ALL_BUT() to CPUSET_EXCEPT()
  from petrov.
db_machdep.h:
- rename the members of db_regs_t to be the same as sparc
- change "db_regs_t ddb_regs" to "db_regs_t *ddb_regp" and change
  all references to suit
- redo DDB_REGS to no longer be a pointer to a fixed data structure
  but to one allocated per-cpu when ddb is entered
- move a bunch of prototypes in here
intr.h:
- remove SPARC64_IPI_* macros, no longer used
db_interface.c:
- change "db_regs_t ddb_regs" to "db_regs_t *ddb_regp" and change
  all references to suit
- make "nil" a 64 bit entity
- change the ddb register access methods to work in multiprocessor
  environment, it is now very much like sparc does it
- in kdb_trap() avoid accessing ddb_regp when it is NULL
- update several messages to include the cpu number
- unpause other cpus much later when resuming from ddb
- rename db_lock() to db_lock_cmd(), as the sparc-like code has
  db_lock as a simple lock
- remove "mach cpus" command, and replace it with "mach cpu" (which
  does the same) and also implement "mach cpu N" to switch to
  another cpus saved trapframe
db_trace.c:
- update for the ddb_regs -> ddb_regp change
genassym.cf:
- add TF_KSTACK as offsetof(struct trapframe64, tf_kstack)
ipifuncs.c:
- overhaul extensively
- remove all normal interrupt handlers as IPI's, we now handle
  them all specially in locore.s:interrupt_vector
- add a simplelock around all ipi functions - it's not safe for
  multiple cpus to be sending IPI's to each other right now
- rename sparc64_ipi_pause() to sparc64_ipi_pause_thiscpu() and,
  if DDB is configured, enable it to save the passed-in trapframe
  to a db_regs_t for this cpu's saved DDB registers.
- remove the "ipimask" system (SPARC64_IPI_* macros) and instead
  pass functions directly
- in sparc64_send_ipi() always set the interrupt arguments to 0,
  the address and argument of the to be called function.  (the
  argument right now is the address of ipi_tlb_args variable, and
  part of the reason why only one CPU can send IPI's at a time.)
  don't wait forever for an IPI to complete.  some of this is
  from petrov.
- rename sparc64_ipi_{halt,pause,resume}_cpus() to
  mp_{halt,pause,resume}_cpus()
- new function mp_cpu_is_paused() used to avoid access missing
  saved DDB registers
- actually broadcast the flush in smp_tlb_flush_pte(),
  smp_tlb_flush_ctx() and smp_tlb_flush_all().  the other end may
  not do anything yet in the pte/ctx cases yet...
kgdb_machdep.c:
- rework for changed member names in db_regs_t.
locore.s:
- shave an instruction from syscall_setup() (set + ld -> sethi + ld)
- remove some old dead debug code
- add new sparc64_ipi_halt IPI entry point, it just calls the C
  vector to shutdown.
- add new sparc64_ipi_pause IPI entry point, which just traps into
  the debugger using the normal breakpoint trap.  these cpus usually
  lose the race in db_interface.c:db_suspend_others() and end up
  calling the C vector sparc64_ipi_pause_thiscpu().
- add #if 0'ed code to sparc64_ipi_flush_{pte,ctx}() IPI entry
  points to call the sp_ version of these functions.
- in rft_kernel (return from trap, kernel), check to see if the
  %tpc is at the sparc64_ipi_pause_trap_point and if so, call
  "done" not "retry"
- rework cpu_switch slightly:  save the passed-in lwp instead of
  using the one in curlwp
- in cpu_loadproc(), save the new lwp not the old lwp, to curlwp
- in cpu_initialize(), set %tl to zero as well.  from petrov.
- in cpu_exit(), fix a load register confusion.  from petrov.
- change some "set" in delay branch to "mov".
machdep.c:
- deal with function renames
pmap.c:
- remove a spurious space
trap.c:
- remove unused "trapstats" variable
- add cpu number to a couple of messages
This commit is contained in:
mrg 2006-09-13 11:35:53 +00:00
parent bada0c776a
commit 2102e18c4b
13 changed files with 554 additions and 355 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.54 2006/06/07 22:39:38 kardel Exp $ */
/* $NetBSD: cpu.h,v 1.55 2006/09/13 11:35:53 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@ -133,6 +133,8 @@ struct cpu_info {
int ci_want_resched;
struct cpu_data ci_data; /* MI per-cpu data */
volatile void *ci_ddb_regs; /* DDB regs */
};
#define CPUF_PRIMARY 1
@ -291,9 +293,6 @@ extern struct intrhand *intrlev[MAXINTNUM];
void intr_establish(int level, struct intrhand *);
#define mp_pause_cpus() sparc64_ipi_pause_cpus()
#define mp_resume_cpus() sparc64_ipi_resume_cpus()
/* disksubr.c */
struct dkbad;
int isbad(struct dkbad *bt, int, int, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuset.h,v 1.4 2005/12/24 20:07:37 perry Exp $ */
/* $NetBSD: cpuset.h,v 1.5 2006/09/13 11:35:53 mrg Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@ -45,8 +45,7 @@ extern volatile cpuset_t cpus_active;
#define CPUSET_DEL(set, cpu) ((set) &= ~CPUSET_SINGLE(cpu))
#define CPUSET_SUB(set1, set2) ((set1) &= ~(set2))
#define CPUSET_ALL(set) ((set) = (cpuset_t)-1)
#define CPUSET_ALL_BUT(set, cpu) ((set) = ~CPUSET_SINGLE(cpu))
#define CPUSET_EXCEPT(set, cpu) ((set) & ~CPUSET_SINGLE(cpu))
#define CPUSET_HAS(set, cpu) ((set) & CPUSET_SINGLE(cpu))
#define CPUSET_NEXT(set) (ffs(set) - 1)

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_machdep.h,v 1.19 2006/04/01 15:45:00 cherry Exp $ */
/* $NetBSD: db_machdep.h,v 1.20 2006/09/13 11:35:53 mrg Exp $ */
/*
* Mach Operating System
@ -52,28 +52,36 @@ struct trapstate {
};
typedef struct {
struct trapframe64 ddb_tf;
struct frame64 ddb_fr;
struct trapstate ddb_ts[5];
int ddb_tl;
struct fpstate64 ddb_fpstate;
struct trapframe64 db_tf;
struct frame64 db_fr;
struct trapstate db_ts[5];
int db_tl;
struct fpstate64 db_fpstate;
} db_regs_t;
extern db_regs_t ddb_regs;
#define DDB_REGS (&ddb_regs)
#define DDB_TF (&ddb_regs.ddb_tf)
#define DDB_FR (&ddb_regs.ddb_fr)
#define DDB_FP (&ddb_regs.ddb_fpstate)
/* Current CPU register state */
extern struct cpu_info *ddb_cpuinfo;
extern db_regs_t *ddb_regp;
#define DDB_REGS ddb_regp
#define DDB_TF (&ddb_regp->db_tf)
#define DDB_FP (&ddb_regp->db_fpstate)
/* DDB commands not in db_interface.c */
void db_dump_ts(db_expr_t, int, db_expr_t, const char *);
void db_dump_trap(db_expr_t, int, db_expr_t, const char *);
void db_dump_fpstate(db_expr_t, int, db_expr_t, const char *);
void db_dump_window(db_expr_t, int, db_expr_t, const char *);
void db_dump_stack(db_expr_t, int, db_expr_t, const char *);
#if defined(lint)
#define PC_REGS(regs) ((regs)->ddb_tf.tf_pc)
#define PC_REGS(regs) ((regs)->db_tf.tf_pc)
#else
#define PC_REGS(regs) ((db_addr_t)(regs)->ddb_tf.tf_pc)
#define PC_REGS(regs) ((db_addr_t)(regs)->db_tf.tf_pc)
#endif
#define PC_ADVANCE(regs) do { \
vaddr_t n = (regs)->ddb_tf.tf_npc; \
(regs)->ddb_tf.tf_pc = n; \
(regs)->ddb_tf.tf_npc = n + 4; \
vaddr_t n = (regs)->db_tf.tf_npc; \
(regs)->db_tf.tf_pc = n; \
(regs)->db_tf.tf_npc = n + 4; \
} while(0)
#define BKPT_ADDR(addr) (addr) /* breakpoint address */
@ -113,7 +121,7 @@ db_addr_t db_branch_taken(int inst, db_addr_t pc, db_regs_t *regs);
/* see note in db_interface.c about reversed breakpoint addrs */
#define next_instr_address(pc, bd) \
((bd) ? (pc) : ddb_regs.ddb_tf.tf_npc)
((bd) ? (pc) : ddb_regp->db_tf.tf_npc)
#define DB_MACHINE_COMMANDS

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.13 2006/05/04 12:18:54 yamt Exp $ */
/* $NetBSD: intr.h,v 1.14 2006/09/13 11:35:53 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -63,26 +63,14 @@
#define IPL_LPT PIL_LPT
#define IPL_IPI PIL_HIGH
/*
* Interprocessor interrupts. In order how we want them processed.
*/
#define SPARC64_IPI_HALT (1UL << 0)
#define SPARC64_IPI_PAUSE (1UL << 1)
#define SPARC64_IPI_FLUSH_PTE (1UL << 2)
#define SPARC64_IPI_FLUSH_CTX (1UL << 3)
#define SPARC64_IPI_FLUSH_ALL (1UL << 4)
#define SPARC64_IPI_SAVE_FP (1UL << 5)
#define SPARC64_NIPIS 6
#if defined(MULTIPROCESSOR)
void sparc64_ipi_init (void);
void sparc64_multicast_ipi (cpuset_t, u_long);
void sparc64_broadcast_ipi (u_long);
void sparc64_send_ipi (int, u_long);
void sparc64_ipi_halt_cpus (void);
void sparc64_ipi_pause_cpus (void);
void sparc64_ipi_resume_cpus (void);
int sparc64_ipi_halt_thiscpu (void *);
int sparc64_ipi_pause_thiscpu (void *);
void mp_halt_cpus (void);
void mp_pause_cpus (void);
void mp_resume_cpus (void);
int mp_cpu_is_paused (cpuset_t);
#endif
void *softintr_establish (int level, void (*fun)(void *), void *arg);

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_interface.c,v 1.87 2006/05/12 23:35:24 uwe Exp $ */
/* $NetBSD: db_interface.c,v 1.88 2006/09/13 11:35:53 mrg 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.87 2006/05/12 23:35:24 uwe Exp $");
__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.88 2006/09/13 11:35:53 mrg Exp $");
#include "opt_ddb.h"
@ -63,11 +63,13 @@ __KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.87 2006/05/12 23:35:24 uwe Exp $"
#include <machine/promlib.h>
#include <machine/ctlreg.h>
#include <machine/pmap.h>
#include <machine/intr.h>
#include "fb.h"
#include "esp_sbus.h"
db_regs_t ddb_regs;
/* pointer to the saved DDB registers */
db_regs_t *ddb_regp;
extern struct traptrace {
unsigned short tl:3, /* Trap level */
@ -80,22 +82,28 @@ extern struct traptrace {
u_int tfault; /* MMU tag access */
} trap_trace[], trap_trace_end[];
static int nil;
/*
* Helpers for ddb variables.
*/
static uint64_t nil;
static int
db__char_value(const struct db_variable *var, db_expr_t *expr, int mode)
db_sparc_charop(const struct db_variable *vp, db_expr_t *val, int opcode)
{
char *regaddr =
(char *)(((uint8_t *)DDB_REGS) + ((size_t)vp->valuep));
char *valaddr = (char *)val;
switch (mode) {
switch (opcode) {
case DB_VAR_SET:
*var->valuep = *(char *)expr;
*valaddr = *regaddr;
break;
case DB_VAR_GET:
*expr = *(char *)var->valuep;
*regaddr = *valaddr;
break;
#ifdef DIAGNOSTIC
default:
printf("db__char_value: mode %d\n", mode);
printf("db_sparc_charop: opcode %d\n", opcode);
break;
#endif
}
@ -103,21 +111,24 @@ db__char_value(const struct db_variable *var, db_expr_t *expr, int mode)
return 0;
}
#ifdef notdef_yet
#ifdef not_used
static int
db__short_value(const struct db_variable *var, db_expr_t *expr, int mode)
db_sparc_shortop(const struct db_variable *vp, db_expr_t *val, int opcode)
{
short *regaddr =
(short *)(((uint8_t *)DDB_REGS) + ((size_t)vp->valuep));
short *valaddr = (short *)val;
switch (mode) {
switch (opcode) {
case DB_VAR_SET:
*var->valuep = *(short *)expr;
*valaddr = *regaddr;
break;
case DB_VAR_GET:
*expr = *(short *)var->valuep;
*regaddr = *valaddr;
break;
#ifdef DIAGNOSTIC
default:
printf("db__short_value: mode %d\n", mode);
printf("sparc_shortop: opcode %d\n", opcode);
break;
#endif
}
@ -127,19 +138,22 @@ db__short_value(const struct db_variable *var, db_expr_t *expr, int mode)
#endif
static int
db__int_value(const struct db_variable *var, db_expr_t *expr, int mode)
db_sparc_intop(const struct db_variable *vp, db_expr_t *val, int opcode)
{
int *regaddr =
(int *)(((uint8_t *)DDB_REGS) + ((size_t)vp->valuep));
int *valaddr = (int *)val;
switch (mode) {
switch (opcode) {
case DB_VAR_SET:
*var->valuep = *(int *)expr;
*valaddr = *regaddr;
break;
case DB_VAR_GET:
*expr = *(int *)var->valuep;
*regaddr = *valaddr;
break;
#ifdef DIAGNOSTIC
default:
printf("db__int_value: mode %d\n", mode);
printf("db_sparc_intop: opcode %d\n", opcode);
break;
#endif
}
@ -147,79 +161,109 @@ db__int_value(const struct db_variable *var, db_expr_t *expr, int mode)
return 0;
}
static int
db_sparc_regop(const struct db_variable *vp, db_expr_t *val, int opcode)
{
db_expr_t *regaddr =
(db_expr_t *)(((uint8_t *)DDB_REGS) + ((size_t)vp->valuep));
switch (opcode) {
case DB_VAR_GET:
*val = *regaddr;
break;
case DB_VAR_SET:
*regaddr = *val;
break;
#ifdef DIAGNOSTIC
default:
printf("db_sparc_regop: unknown op %d\n", opcode);
break;
#endif
}
return 0;
}
/*
* Machine register set.
*/
#define dbreg(xx) (long *)offsetof(db_regs_t, db_tf.tf_ ## xx)
#define dbregfr(xx) (long *)offsetof(db_regs_t, db_fr.fr_ ## xx)
#define dbregfp(xx) (long *)offsetof(db_regs_t, db_fpstate.fs_ ## xx)
static int db_sparc_regop(const struct db_variable *, db_expr_t *, int);
const struct db_variable db_regs[] = {
{ "tstate", (long *)&DDB_TF->tf_tstate, FCN_NULL, },
{ "pc", (long *)&DDB_TF->tf_pc, FCN_NULL, },
{ "npc", (long *)&DDB_TF->tf_npc, FCN_NULL, },
{ "ipl", (long *)&DDB_TF->tf_oldpil, db__char_value, },
{ "y", (long *)&DDB_TF->tf_y, db__int_value, },
{ "tstate", dbreg(tstate), db_sparc_regop, },
{ "pc", dbreg(pc), db_sparc_regop, },
{ "npc", dbreg(npc), db_sparc_regop, },
{ "ipl", dbreg(oldpil), db_sparc_charop, },
{ "y", dbreg(y), db_sparc_intop, },
{ "g0", (void *)&nil, FCN_NULL, },
{ "g1", (long *)&DDB_TF->tf_global[1], FCN_NULL, },
{ "g2", (long *)&DDB_TF->tf_global[2], FCN_NULL, },
{ "g3", (long *)&DDB_TF->tf_global[3], FCN_NULL, },
{ "g4", (long *)&DDB_TF->tf_global[4], FCN_NULL, },
{ "g5", (long *)&DDB_TF->tf_global[5], FCN_NULL, },
{ "g6", (long *)&DDB_TF->tf_global[6], FCN_NULL, },
{ "g7", (long *)&DDB_TF->tf_global[7], FCN_NULL, },
{ "o0", (long *)&DDB_TF->tf_out[0], FCN_NULL, },
{ "o1", (long *)&DDB_TF->tf_out[1], FCN_NULL, },
{ "o2", (long *)&DDB_TF->tf_out[2], FCN_NULL, },
{ "o3", (long *)&DDB_TF->tf_out[3], FCN_NULL, },
{ "o4", (long *)&DDB_TF->tf_out[4], FCN_NULL, },
{ "o5", (long *)&DDB_TF->tf_out[5], FCN_NULL, },
{ "o6", (long *)&DDB_TF->tf_out[6], FCN_NULL, },
{ "o7", (long *)&DDB_TF->tf_out[7], FCN_NULL, },
{ "l0", (long *)&DDB_FR->fr_local[0], FCN_NULL, },
{ "l1", (long *)&DDB_FR->fr_local[1], FCN_NULL, },
{ "l2", (long *)&DDB_FR->fr_local[2], FCN_NULL, },
{ "l3", (long *)&DDB_FR->fr_local[3], FCN_NULL, },
{ "l4", (long *)&DDB_FR->fr_local[4], FCN_NULL, },
{ "l5", (long *)&DDB_FR->fr_local[5], FCN_NULL, },
{ "l6", (long *)&DDB_FR->fr_local[6], FCN_NULL, },
{ "l7", (long *)&DDB_FR->fr_local[7], FCN_NULL, },
{ "i0", (long *)&DDB_FR->fr_arg[0], FCN_NULL, },
{ "i1", (long *)&DDB_FR->fr_arg[1], FCN_NULL, },
{ "i2", (long *)&DDB_FR->fr_arg[2], FCN_NULL, },
{ "i3", (long *)&DDB_FR->fr_arg[3], FCN_NULL, },
{ "i4", (long *)&DDB_FR->fr_arg[4], FCN_NULL, },
{ "i5", (long *)&DDB_FR->fr_arg[5], FCN_NULL, },
{ "i6", (long *)&DDB_FR->fr_arg[6], FCN_NULL, },
{ "i7", (long *)&DDB_FR->fr_arg[7], FCN_NULL, },
{ "f0", (long *)&DDB_FP->fs_regs[0], FCN_NULL, },
{ "f2", (long *)&DDB_FP->fs_regs[2], FCN_NULL, },
{ "f4", (long *)&DDB_FP->fs_regs[4], FCN_NULL, },
{ "f6", (long *)&DDB_FP->fs_regs[6], FCN_NULL, },
{ "f8", (long *)&DDB_FP->fs_regs[8], FCN_NULL, },
{ "f10", (long *)&DDB_FP->fs_regs[10], FCN_NULL, },
{ "f12", (long *)&DDB_FP->fs_regs[12], FCN_NULL, },
{ "f14", (long *)&DDB_FP->fs_regs[14], FCN_NULL, },
{ "f16", (long *)&DDB_FP->fs_regs[16], FCN_NULL, },
{ "f18", (long *)&DDB_FP->fs_regs[18], FCN_NULL, },
{ "f20", (long *)&DDB_FP->fs_regs[20], FCN_NULL, },
{ "f22", (long *)&DDB_FP->fs_regs[22], FCN_NULL, },
{ "f24", (long *)&DDB_FP->fs_regs[24], FCN_NULL, },
{ "f26", (long *)&DDB_FP->fs_regs[26], FCN_NULL, },
{ "f28", (long *)&DDB_FP->fs_regs[28], FCN_NULL, },
{ "f30", (long *)&DDB_FP->fs_regs[30], FCN_NULL, },
{ "f32", (long *)&DDB_FP->fs_regs[32], FCN_NULL, },
{ "f34", (long *)&DDB_FP->fs_regs[34], FCN_NULL, },
{ "f36", (long *)&DDB_FP->fs_regs[36], FCN_NULL, },
{ "f38", (long *)&DDB_FP->fs_regs[38], FCN_NULL, },
{ "f40", (long *)&DDB_FP->fs_regs[40], FCN_NULL, },
{ "f42", (long *)&DDB_FP->fs_regs[42], FCN_NULL, },
{ "f44", (long *)&DDB_FP->fs_regs[44], FCN_NULL, },
{ "f46", (long *)&DDB_FP->fs_regs[46], FCN_NULL, },
{ "f48", (long *)&DDB_FP->fs_regs[48], FCN_NULL, },
{ "f50", (long *)&DDB_FP->fs_regs[50], FCN_NULL, },
{ "f52", (long *)&DDB_FP->fs_regs[52], FCN_NULL, },
{ "f54", (long *)&DDB_FP->fs_regs[54], FCN_NULL, },
{ "f56", (long *)&DDB_FP->fs_regs[56], FCN_NULL, },
{ "f58", (long *)&DDB_FP->fs_regs[58], FCN_NULL, },
{ "f60", (long *)&DDB_FP->fs_regs[60], FCN_NULL, },
{ "f62", (long *)&DDB_FP->fs_regs[62], FCN_NULL, },
{ "fsr", (long *)&DDB_FP->fs_fsr, FCN_NULL, },
{ "gsr", (long *)&DDB_FP->fs_gsr, FCN_NULL, },
{ "g1", dbreg(global[1]), db_sparc_regop, },
{ "g2", dbreg(global[2]), db_sparc_regop, },
{ "g3", dbreg(global[3]), db_sparc_regop, },
{ "g4", dbreg(global[4]), db_sparc_regop, },
{ "g5", dbreg(global[5]), db_sparc_regop, },
{ "g6", dbreg(global[6]), db_sparc_regop, },
{ "g7", dbreg(global[7]), db_sparc_regop, },
{ "o0", dbreg(out[0]), db_sparc_regop, },
{ "o1", dbreg(out[1]), db_sparc_regop, },
{ "o2", dbreg(out[2]), db_sparc_regop, },
{ "o3", dbreg(out[3]), db_sparc_regop, },
{ "o4", dbreg(out[4]), db_sparc_regop, },
{ "o5", dbreg(out[5]), db_sparc_regop, },
{ "o6", dbreg(out[6]), db_sparc_regop, },
{ "o7", dbreg(out[7]), db_sparc_regop, },
{ "l0", dbregfr(local[0]), db_sparc_regop, },
{ "l1", dbregfr(local[1]), db_sparc_regop, },
{ "l2", dbregfr(local[2]), db_sparc_regop, },
{ "l3", dbregfr(local[3]), db_sparc_regop, },
{ "l4", dbregfr(local[4]), db_sparc_regop, },
{ "l5", dbregfr(local[5]), db_sparc_regop, },
{ "l6", dbregfr(local[6]), db_sparc_regop, },
{ "l7", dbregfr(local[7]), db_sparc_regop, },
{ "i0", dbregfr(arg[0]), db_sparc_regop, },
{ "i1", dbregfr(arg[1]), db_sparc_regop, },
{ "i2", dbregfr(arg[2]), db_sparc_regop, },
{ "i3", dbregfr(arg[3]), db_sparc_regop, },
{ "i4", dbregfr(arg[4]), db_sparc_regop, },
{ "i5", dbregfr(arg[5]), db_sparc_regop, },
{ "i6", dbregfr(arg[6]), db_sparc_regop, },
{ "i7", dbregfr(arg[7]), db_sparc_regop, },
{ "f0", dbregfp(regs[0]), db_sparc_regop, },
{ "f2", dbregfp(regs[2]), db_sparc_regop, },
{ "f4", dbregfp(regs[4]), db_sparc_regop, },
{ "f6", dbregfp(regs[6]), db_sparc_regop, },
{ "f8", dbregfp(regs[8]), db_sparc_regop, },
{ "f10", dbregfp(regs[10]), db_sparc_regop, },
{ "f12", dbregfp(regs[12]), db_sparc_regop, },
{ "f14", dbregfp(regs[14]), db_sparc_regop, },
{ "f16", dbregfp(regs[16]), db_sparc_regop, },
{ "f18", dbregfp(regs[18]), db_sparc_regop, },
{ "f20", dbregfp(regs[20]), db_sparc_regop, },
{ "f22", dbregfp(regs[22]), db_sparc_regop, },
{ "f24", dbregfp(regs[24]), db_sparc_regop, },
{ "f26", dbregfp(regs[26]), db_sparc_regop, },
{ "f28", dbregfp(regs[28]), db_sparc_regop, },
{ "f30", dbregfp(regs[30]), db_sparc_regop, },
{ "f32", dbregfp(regs[32]), db_sparc_regop, },
{ "f34", dbregfp(regs[34]), db_sparc_regop, },
{ "f36", dbregfp(regs[36]), db_sparc_regop, },
{ "f38", dbregfp(regs[38]), db_sparc_regop, },
{ "f40", dbregfp(regs[40]), db_sparc_regop, },
{ "f42", dbregfp(regs[42]), db_sparc_regop, },
{ "f44", dbregfp(regs[44]), db_sparc_regop, },
{ "f46", dbregfp(regs[46]), db_sparc_regop, },
{ "f48", dbregfp(regs[48]), db_sparc_regop, },
{ "f50", dbregfp(regs[50]), db_sparc_regop, },
{ "f52", dbregfp(regs[52]), db_sparc_regop, },
{ "f54", dbregfp(regs[54]), db_sparc_regop, },
{ "f56", dbregfp(regs[56]), db_sparc_regop, },
{ "f58", dbregfp(regs[58]), db_sparc_regop, },
{ "f60", dbregfp(regs[60]), db_sparc_regop, },
{ "f62", dbregfp(regs[62]), db_sparc_regop, },
{ "fsr", dbregfp(fsr), db_sparc_regop, },
{ "gsr", dbregfp(gsr), db_sparc_regop, },
};
const struct db_variable * const db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
@ -232,11 +276,6 @@ void db_prom_cmd(db_expr_t, int, db_expr_t, const char *);
void db_lwp_cmd(db_expr_t, int, db_expr_t, const char *);
void db_proc_cmd(db_expr_t, int, db_expr_t, const char *);
void db_ctx_cmd(db_expr_t, int, db_expr_t, const char *);
void db_dump_window(db_expr_t, int, db_expr_t, const char *);
void db_dump_stack(db_expr_t, int, db_expr_t, const char *);
void db_dump_trap(db_expr_t, int, db_expr_t, const char *);
void db_dump_fpstate(db_expr_t, int, db_expr_t, const char *);
void db_dump_ts(db_expr_t, int, db_expr_t, const char *);
void db_dump_pcb(db_expr_t, int, db_expr_t, const char *);
void db_dump_pv(db_expr_t, int, db_expr_t, const char *);
void db_setpcb(db_expr_t, int, db_expr_t, const char *);
@ -247,16 +286,70 @@ void db_dump_itsb(db_expr_t, int, db_expr_t, const char *);
void db_pmap_kernel(db_expr_t, int, db_expr_t, const char *);
void db_pload_cmd(db_expr_t, int, db_expr_t, const char *);
void db_pmap_cmd(db_expr_t, int, db_expr_t, const char *);
void db_lock(db_expr_t, int, db_expr_t, const char *);
void db_lock_cmd(db_expr_t, int, db_expr_t, const char *);
void db_traptrace(db_expr_t, int, db_expr_t, const char *);
void db_watch(db_expr_t, int, db_expr_t, const char *);
void db_pm_extract(db_expr_t, int, db_expr_t, const char *);
void db_cpus_cmd(db_expr_t, int, db_expr_t, const char *);
void db_cpu_cmd(db_expr_t, int, db_expr_t, const char *);
#ifdef DDB
static void db_dump_pmap(struct pmap *);
static void db_print_trace_entry(struct traptrace *, int);
/* struct cpu_info of CPU being investigated */
struct cpu_info *ddb_cpuinfo;
#ifdef MULTIPROCESSOR
#define NOCPU -1
static int db_suspend_others(void);
static void db_resume_others(void);
static void ddb_suspend(struct trapframe *);
__cpu_simple_lock_t db_lock;
int ddb_cpu = NOCPU;
static int
db_suspend_others(void)
{
int cpu_me = cpu_number();
int 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);
if (win)
mp_pause_cpus();
return win;
}
static void
db_resume_others(void)
{
mp_resume_cpus();
__cpu_simple_lock(&db_lock);
ddb_cpu = NOCPU;
__cpu_simple_unlock(&db_lock);
}
static void
ddb_suspend(struct trapframe *tf)
{
sparc64_ipi_pause_thiscpu(tf);
}
#endif /* MULTIPROCESSOR */
/*
* Received keyboard interrupt sequence.
*/
@ -275,8 +368,9 @@ kdb_kbd_trap(struct trapframe64 *tf)
int
kdb_trap(int type, register struct trapframe64 *tf)
{
db_regs_t dbregs;
int s, tl;
struct trapstate *ts = &ddb_regs.ddb_ts[0];
struct trapstate *ts;
extern int savetstate(struct trapstate *);
extern void restoretstate(int, struct trapstate *);
extern int trap_trace_dis;
@ -289,7 +383,7 @@ kdb_trap(int type, register struct trapframe64 *tf)
#endif
switch (type) {
case T_BREAKPOINT: /* breakpoint */
printf("kdb breakpoint at %llx\n",
printf("cpu%d: kdb breakpoint at %llx\n", cpu_number(),
(unsigned long long)tf->tf_pc);
break;
case -1: /* keyboard interrupt */
@ -312,22 +406,39 @@ kdb_trap(int type, register struct trapframe64 *tf)
/* Should switch to kdb`s own stack here. */
write_all_windows();
ddb_regs.ddb_tf = *tf;
#if defined(MULTIPROCESSOR)
if (!db_suspend_others()) {
ddb_suspend(tf);
return 1;
}
#endif
/* Initialise local dbregs storage from trap frame */
dbregs.db_tf = *tf;
dbregs.db_fr = *(struct frame64 *)tf->tf_out[6];
/* Setup current CPU & reg pointers */
ddb_cpuinfo = curcpu();
curcpu()->ci_ddb_regs = ddb_regp = &dbregs;
ts = &ddb_regp->db_ts[0];
fplwp = NULL;
if (fplwp) {
savefpstate(fplwp->l_md.md_fpstate);
ddb_regs.ddb_fpstate = *fplwp->l_md.md_fpstate;
dbregs.db_fpstate = *fplwp->l_md.md_fpstate;
loadfpstate(fplwp->l_md.md_fpstate);
}
/* We should do a proper copyin and xlate 64-bit stack frames, but... */
/* if (tf->tf_tstate & TSTATE_PRIV) { */
/* if (tf->tf_tstate & TSTATE_PRIV) { .. } */
#if 0
/* make sure this is not causing ddb problems. */
if (tf->tf_out[6] & 1) {
if ((unsigned)(tf->tf_out[6] + BIAS) > (unsigned)KERNBASE)
ddb_regs.ddb_fr = *(struct frame64 *)(tf->tf_out[6] + BIAS);
dbregs.db_fr = *(struct frame64 *)(tf->tf_out[6] + BIAS);
else
copyin((caddr_t)(tf->tf_out[6] + BIAS), &ddb_regs.ddb_fr, sizeof(struct frame64));
copyin((caddr_t)(tf->tf_out[6] + BIAS), &dbregs.db_fr, sizeof(struct frame64));
} else {
struct frame32 tfr;
@ -338,44 +449,46 @@ kdb_trap(int type, register struct trapframe64 *tf)
copyin((caddr_t)(tf->tf_out[6]), &tfr, sizeof(struct frame32));
/* Now copy each field from the 32-bit value to the 64-bit value */
for (i=0; i<8; i++)
ddb_regs.ddb_fr.fr_local[i] = tfr.fr_local[i];
dbregs.db_fr.fr_local[i] = tfr.fr_local[i];
for (i=0; i<6; i++)
ddb_regs.ddb_fr.fr_arg[i] = tfr.fr_arg[i];
ddb_regs.ddb_fr.fr_fp = (long)tfr.fr_fp;
ddb_regs.ddb_fr.fr_pc = tfr.fr_pc;
dbregs.db_fr.fr_arg[i] = tfr.fr_arg[i];
dbregs.db_fr.fr_fp = (long)tfr.fr_fp;
dbregs.db_fr.fr_pc = tfr.fr_pc;
}
#endif
s = splhigh();
db_active++;
#if defined(MULTIPROCESSOR)
sparc64_ipi_pause_cpus();
#endif
cnpollc(TRUE);
/* Need to do spl stuff till cnpollc works */
tl = ddb_regs.ddb_tl = savetstate(ts);
tl = dbregs.db_tl = savetstate(ts);
db_dump_ts(0, 0, 0, 0);
db_trap(type, 0/*code*/);
restoretstate(tl,ts);
cnpollc(FALSE);
db_active--;
#if defined(MULTIPROCESSOR)
sparc64_ipi_resume_cpus();
#endif
splx(s);
if (fplwp) {
*fplwp->l_md.md_fpstate = ddb_regs.ddb_fpstate;
*fplwp->l_md.md_fpstate = dbregs.db_fpstate;
loadfpstate(fplwp->l_md.md_fpstate);
}
#if 0
/* We will not alter the machine's running state until we get everything else working */
*(struct frame *)tf->tf_out[6] = ddb_regs.ddb_fr;
*(struct frame *)tf->tf_out[6] = dbregs.db_fr;
#endif
*tf = ddb_regs.ddb_tf;
*tf = dbregs.db_tf;
curcpu()->ci_ddb_regs = ddb_regp = 0;
ddb_cpuinfo = NULL;
trap_trace_dis--;
doing_shutdown--;
#if defined(MULTIPROCESSOR)
db_resume_others();
#endif
return (1);
}
#endif /* DDB */
@ -676,7 +789,7 @@ db_pmap_cmd(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
void
db_lock(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
db_lock_cmd(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
{
#if 0
struct lock *l;
@ -1063,18 +1176,60 @@ db_watch(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
}
}
void
db_cpus_cmd(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
/* XXX this belongs in cpu.c */
static void cpu_debug_dump(void);
static void
cpu_debug_dump(void)
{
struct cpu_info *ci;
for (ci = cpus; ci; ci = ci->ci_next) {
db_printf("cpu%d: self 0x%08lx lwp 0x%08lx pcb 0x%08lx\n",
db_printf("cpu%d: self 0x%08lx lwp 0x%08lx pcb 0x%08lx idle 0x%08lx\n",
ci->ci_number, (u_long)ci->ci_self,
(u_long)ci->ci_curlwp, (u_long)ci->ci_cpcb);
(u_long)ci->ci_curlwp, (u_long)ci->ci_cpcb,
(u_long)ci->ci_idle_u);
}
}
void
db_cpu_cmd(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
{
#ifdef MULTIPROCESSOR
struct cpu_info *ci;
#endif
if (!have_addr) {
cpu_debug_dump();
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_number == addr)
break;
if (ci == NULL) {
db_printf("CPU %ld not configured\n", addr);
return;
}
if (ci != curcpu()) {
if (!mp_cpu_is_paused(ci->ci_number)) {
db_printf("CPU %ld not paused\n", addr);
return;
}
}
if (ci->ci_ddb_regs == 0) {
db_printf("CPU %ld has no saved regs\n", addr);
return;
}
db_printf("using CPU %ld", addr);
ddb_regp = __UNVOLATILE(ci->ci_ddb_regs);
ddb_cpuinfo = ci;
#endif
}
#include <uvm/uvm.h>
void db_uvmhistdump(db_expr_t, int, db_expr_t, const char *);
@ -1107,7 +1262,7 @@ const struct db_command db_machine_command_table[] = {
{ "extract", db_pm_extract, 0, 0 },
{ "fpstate", db_dump_fpstate,0, 0 },
{ "kmap", db_pmap_kernel, 0, 0 },
{ "lock", db_lock, 0, 0 },
{ "lock", db_lock_cmd, 0, 0 },
{ "lwp", db_lwp_cmd, 0, 0 },
{ "pcb", db_dump_pcb, 0, 0 },
{ "pctx", db_setpcb, 0, 0 },
@ -1124,7 +1279,7 @@ const struct db_command db_machine_command_table[] = {
{ "uvmdump", db_uvmhistdump, 0, 0 },
{ "watch", db_watch, 0, 0 },
{ "window", db_dump_window, 0, 0 },
{ "cpus", db_cpus_cmd, 0, 0 },
{ "cpu", db_cpu_cmd, 0, 0 },
{ NULL, }
};
@ -1145,7 +1300,10 @@ db_addr_t
db_branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
{
union instr insn;
db_addr_t npc = ddb_regs.ddb_tf.tf_npc;
db_addr_t npc;
KASSERT(ddb_regp); /* XXX */
npc = ddb_regp->db_tf.tf_npc;
insn.i_int = inst;

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_trace.c,v 1.33 2006/09/06 23:58:20 ad Exp $ */
/* $NetBSD: db_trace.c,v 1.34 2006/09/13 11:35:53 mrg Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.33 2006/09/06 23:58:20 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.34 2006/09/13 11:35:53 mrg Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@ -42,11 +42,6 @@ __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.33 2006/09/06 23:58:20 ad Exp $");
#include <ddb/db_interface.h>
#include <ddb/db_output.h>
void db_dump_fpstate(db_expr_t, int, db_expr_t, const char *);
void db_dump_window(db_expr_t, int, db_expr_t, const char *);
void db_dump_stack(db_expr_t, int, db_expr_t, const char *);
void db_dump_trap(db_expr_t, int, db_expr_t, const char *);
void db_dump_ts(db_expr_t, int, db_expr_t, const char *);
void db_print_window(uint64_t);
#if 0
@ -337,7 +332,7 @@ db_dump_trap(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
struct trapframe64 *tf;
/* Use our last trapframe? */
tf = &ddb_regs.ddb_tf;
tf = DDB_TF;
{
/* Or the user trapframe? */
register char c;
@ -418,7 +413,7 @@ db_dump_fpstate(db_expr_t addr, int have_addr, db_expr_t count, const char *modi
struct fpstate64 *fpstate;
/* Use our last trapframe? */
fpstate = &ddb_regs.ddb_fpstate;
fpstate = DDB_FP;
/* Or an arbitrary trapframe */
if (have_addr)
fpstate = (struct fpstate64 *)addr;
@ -507,8 +502,8 @@ db_dump_ts(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
int i, tl;
/* Use our last trapframe? */
ts = &ddb_regs.ddb_ts[0];
tl = ddb_regs.ddb_tl;
ts = &DDB_REGS->db_ts[0];
tl = DDB_REGS->db_tl;
for (i=0; i<tl; i++) {
printf("%d tt=%lx tstate=%lx tpc=%p tnpc=%p\n",
i+1, (long)ts[i].tt, (u_long)ts[i].tstate,
@ -516,5 +511,3 @@ db_dump_ts(db_expr_t addr, int have_addr, db_expr_t count, const char *modif)
}
}

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.40 2006/01/27 18:37:49 cdi Exp $
# $NetBSD: genassym.cf,v 1.41 2006/09/13 11:35:53 mrg Exp $
#
# Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -229,6 +229,7 @@ define TF_TSTATE offsetof(struct trapframe64, tf_tstate)
define TF_PC offsetof(struct trapframe64, tf_pc)
define TF_NPC offsetof(struct trapframe64, tf_npc)
define TF_FAULT offsetof(struct trapframe64, tf_fault)
define TF_KSTACK offsetof(struct trapframe64, tf_kstack)
define TF_Y offsetof(struct trapframe64, tf_y)
define TF_PIL offsetof(struct trapframe64, tf_pil)
define TF_OLDPIL offsetof(struct trapframe64, tf_oldpil)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipifuncs.c,v 1.4 2006/02/20 19:00:27 cdi Exp $ */
/* $NetBSD: ipifuncs.c,v 1.5 2006/09/13 11:35:53 mrg Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@ -34,23 +34,22 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.4 2006/02/20 19:00:27 cdi Exp $");
__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.5 2006/09/13 11:35:53 mrg Exp $");
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <machine/db_machdep.h>
#include <machine/cpu.h>
#include <machine/ctlreg.h>
#include <machine/pte.h>
#include <machine/sparc64.h>
#define IPI_TLB_SHOOTDOWN 0
#define SPARC64_IPI_HALT_NO 100
#define SPARC64_IPI_RESUME_NO 101
#define SPARC64_IPI_RETRIES 100
#define SPARC64_IPI_RETRIES 10000
#define sparc64_ipi_sleep() delay(1000)
@ -66,47 +65,41 @@ static volatile cpuset_t cpus_resumed;
volatile struct ipi_tlb_args ipi_tlb_args;
/* IPI handlers. */
static int sparc64_ipi_halt(void *);
static int sparc64_ipi_pause(void *);
static int sparc64_ipi_wait(cpuset_t volatile *, cpuset_t);
static void sparc64_ipi_error(const char *, cpuset_t, cpuset_t);
/*
* Call a function on other cpus:
* multicast - send to everyone in the cpuset_t
* broadcast - send to to all cpus but ourselves
* send - send to just this cpu
*/
static void sparc64_multicast_ipi (cpuset_t, ipifunc_t);
static void sparc64_broadcast_ipi (ipifunc_t);
static void sparc64_send_ipi (int, ipifunc_t);
/*
* This must be locked around all message transactions to ensure only
* one CPU is generating them.
* XXX this is from sparc, but it isn't necessary here, but we'll do
* XXX it anyway for now, just to keep some things known.
*/
static struct simplelock sparc64_ipi_lock = SIMPLELOCK_INITIALIZER;
/*
* These are the "function" entry points in locore.s to handle IPI's.
*/
void sparc64_ipi_halt(void *);
void sparc64_ipi_pause(void *);
void sparc64_ipi_flush_pte(void *);
void sparc64_ipi_flush_ctx(void *);
void sparc64_ipi_flush_all(void *);
/* IPI handlers working at SOFTINT level. */
static struct intrhand ipi_halt_intr = {
sparc64_ipi_halt, NULL, SPARC64_IPI_HALT_NO, IPL_HALT
};
static struct intrhand ipi_pause_intr = {
sparc64_ipi_pause, NULL, SPARC64_IPI_RESUME_NO, IPL_PAUSE
};
static struct intrhand *ipihand[] = {
&ipi_halt_intr,
&ipi_pause_intr
};
/*
* Fast IPI table. If function is null, the handler is looked up
* in 'ipihand' table.
*/
static ipifunc_t ipifuncs[SPARC64_NIPIS] = {
NULL, /* ipi_halt_intr */
NULL, /* ipi_pause_intr */
sparc64_ipi_flush_pte,
sparc64_ipi_flush_ctx,
sparc64_ipi_flush_all
};
/*
* Process cpu stop-self event.
*/
static int
sparc64_ipi_halt(void *arg)
int
sparc64_ipi_halt_thiscpu(void *arg)
{
printf("cpu%d: shutting down\n", cpu_number());
@ -117,13 +110,25 @@ sparc64_ipi_halt(void *arg)
}
/*
* Pause cpu.
* Pause cpu. This is called from locore.s after setting up a trapframe.
*/
static int
sparc64_ipi_pause(void *arg)
int
sparc64_ipi_pause_thiscpu(void *arg)
{
int s;
cpuid_t cpuid;
int s;
#if defined(DDB)
struct trapframe64 *tf = arg;
volatile db_regs_t dbregs;
if (tf) {
/* Initialise local dbregs storage from trap frame */
dbregs.db_tf = *tf;
dbregs.db_fr = *(struct frame64 *)tf->tf_out[6];
curcpu()->ci_ddb_regs = &dbregs;
}
#endif
cpuid = cpu_number();
printf("cpu%ld paused.\n", cpuid);
@ -138,6 +143,11 @@ sparc64_ipi_pause(void *arg)
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);
@ -154,17 +164,13 @@ sparc64_ipi_init()
CPUSET_CLEAR(cpus_halted);
CPUSET_CLEAR(cpus_paused);
CPUSET_CLEAR(cpus_resumed);
/* Install interrupt handlers. */
intr_establish(ipi_halt_intr.ih_pil, &ipi_halt_intr);
intr_establish(ipi_pause_intr.ih_pil, &ipi_pause_intr);
}
/*
* Send an IPI to all in the list but ourselves.
*/
void
sparc64_multicast_ipi(cpuset_t cpuset, u_long ipimask)
static void
sparc64_multicast_ipi(cpuset_t cpuset, ipifunc_t func)
{
struct cpu_info *ci;
@ -175,7 +181,7 @@ sparc64_multicast_ipi(cpuset_t cpuset, u_long ipimask)
for (ci = cpus; ci != NULL; ci = ci->ci_next) {
if (CPUSET_HAS(cpuset, ci->ci_number)) {
CPUSET_DEL(cpuset, ci->ci_number);
sparc64_send_ipi(ci->ci_upaid, ipimask);
sparc64_send_ipi(ci->ci_upaid, func);
}
}
}
@ -183,41 +189,30 @@ sparc64_multicast_ipi(cpuset_t cpuset, u_long ipimask)
/*
* Broadcast an IPI to all but ourselves.
*/
void
sparc64_broadcast_ipi(u_long ipimask)
static void
sparc64_broadcast_ipi(ipifunc_t func)
{
cpuset_t cpuset;
CPUSET_ALL_BUT(cpuset, cpu_number());
sparc64_multicast_ipi(cpuset, ipimask);
sparc64_multicast_ipi(CPUSET_EXCEPT(cpus_active, cpu_number()), func);
}
/*
* Send an interprocessor interrupt.
*/
void
sparc64_send_ipi(int upaid, u_long ipimask)
static void
sparc64_send_ipi(int upaid, ipifunc_t func)
{
int i;
int i, ik;
uint64_t intr_number, intr_func, intr_arg;
KASSERT(ipimask < (1UL << SPARC64_NIPIS));
KASSERT((ldxa(0, ASR_IDSR) & IDSR_BUSY) == 0);
if (ldxa(0, ASR_IDSR) & IDSR_BUSY) {
__asm __volatile("ta 1; nop");
}
/* Setup interrupt data. */
i = ffs(ipimask) - 1;
intr_func = (uint64_t)ipifuncs[i];
if (intr_func) {
/* fast trap */
intr_number = 0;
intr_arg = (uint64_t)&ipi_tlb_args;
} else {
/* softint trap */
struct intrhand *ih = ipihand[i];
intr_number = (uint64_t)ih->ih_number;
intr_func = (uint64_t)ih->ih_fun;
intr_arg = (uint64_t)ih->ih_arg;
}
intr_func = (uint64_t)(u_long)func;
intr_arg = (uint64_t)(u_long)&ipi_tlb_args;
/* Schedule an interrupt. */
for (i = 0; i < SPARC64_IPI_RETRIES; i++) {
@ -229,18 +224,29 @@ sparc64_send_ipi(int upaid, u_long ipimask)
stxa(IDCR(upaid), ASI_INTERRUPT_DISPATCH, 0);
membar_sync();
while (ldxa(0, ASR_IDSR) & IDSR_BUSY)
;
for (ik = 0; ik < 1000000; ik++) {
if (ldxa(0, ASR_IDSR) & IDSR_BUSY)
continue;
else
break;
}
intr_restore(s);
if (ik == 1000000)
break;
if ((ldxa(0, ASR_IDSR) & IDSR_NACK) == 0)
return;
}
#if 0
if (db_active || panicstr != NULL)
printf("ipi_send: couldn't send ipi to module %u\n", upaid);
else
panic("ipi_send: couldn't send ipi");
#else
__asm __volatile("ta 1; nop" : :);
#endif
}
/*
@ -264,7 +270,7 @@ sparc64_ipi_wait(cpuset_t volatile *cpus_watchset, cpuset_t cpus_mask)
* Halt all cpus but ourselves.
*/
void
sparc64_ipi_halt_cpus()
mp_halt_cpus()
{
cpuset_t cpumask, cpuset;
@ -276,16 +282,20 @@ sparc64_ipi_halt_cpus()
if (CPUSET_EMPTY(cpuset))
return;
sparc64_multicast_ipi(cpuset, SPARC64_IPI_HALT);
simple_lock(&sparc64_ipi_lock);
sparc64_multicast_ipi(cpuset, sparc64_ipi_halt);
if (sparc64_ipi_wait(&cpus_halted, cpumask))
sparc64_ipi_error("halt", cpumask, cpus_halted);
simple_unlock(&sparc64_ipi_lock);
}
/*
* Pause all cpus but ourselves.
*/
void
sparc64_ipi_pause_cpus()
mp_pause_cpus()
{
cpuset_t cpuset;
@ -295,16 +305,20 @@ sparc64_ipi_pause_cpus()
if (CPUSET_EMPTY(cpuset))
return;
sparc64_multicast_ipi(cpuset, SPARC64_IPI_PAUSE);
simple_lock(&sparc64_ipi_lock);
sparc64_multicast_ipi(cpuset, sparc64_ipi_pause);
if (sparc64_ipi_wait(&cpus_paused, cpuset))
sparc64_ipi_error("pause", cpus_paused, cpuset);
simple_unlock(&sparc64_ipi_lock);
}
/*
* Resume all paused cpus.
*/
void
sparc64_ipi_resume_cpus()
mp_resume_cpus()
{
cpuset_t cpuset;
@ -318,6 +332,13 @@ sparc64_ipi_resume_cpus()
sparc64_ipi_error("resume", cpus_resumed, cpuset);
}
int
mp_cpu_is_paused(cpuset_t cpunum)
{
return CPUSET_HAS(cpus_paused, cpunum);
}
/*
* Flush pte on all active processors.
*/
@ -327,13 +348,15 @@ smp_tlb_flush_pte(vaddr_t va, int ctx)
/* Flush our own TLB */
sp_tlb_flush_pte(va, ctx);
#if defined(IPI_TLB_SHOOTDOWN)
simple_lock(&sparc64_ipi_lock);
/* Flush others */
ipi_tlb_args.ita_vaddr = va;
ipi_tlb_args.ita_ctx = ctx;
sparc64_broadcast_ipi(SPARC64_IPI_FLUSH_PTE);
#endif
sparc64_broadcast_ipi(sparc64_ipi_flush_pte);
simple_unlock(&sparc64_ipi_lock);
}
/*
@ -345,13 +368,15 @@ smp_tlb_flush_ctx(int ctx)
/* Flush our own TLB */
sp_tlb_flush_ctx(ctx);
#if defined(IPI_TLB_SHOOTDOWN)
simple_lock(&sparc64_ipi_lock);
/* Flush others */
ipi_tlb_args.ita_vaddr = (vaddr_t)0;
ipi_tlb_args.ita_ctx = ctx;
sparc64_broadcast_ipi(SPARC64_IPI_FLUSH_CTX);
#endif
sparc64_broadcast_ipi(sparc64_ipi_flush_ctx);
simple_unlock(&sparc64_ipi_lock);
}
/*
@ -363,10 +388,12 @@ smp_tlb_flush_all()
/* Flush our own TLB */
sp_tlb_flush_all();
#if defined(IPI_TLB_SHOOTDOWN)
simple_lock(&sparc64_ipi_lock);
/* Flush others */
sparc64_broadcast_ipi(SPARC64_IPI_FLUSH_ALL);
#endif
sparc64_broadcast_ipi(sparc64_ipi_flush_all);
simple_unlock(&sparc64_ipi_lock);
}
/*
@ -379,11 +406,14 @@ sparc64_ipi_error(const char *s, cpuset_t cpus_succeeded,
int cpuid;
CPUSET_DEL(cpus_expected, cpus_succeeded);
if (!CPUSET_EMPTY(cpus_expected)) {
printf("Failed to %s:", s);
do {
cpuid = CPUSET_NEXT(cpus_expected);
CPUSET_DEL(cpus_expected, cpuid);
printf(" cpu%d", cpuid);
} while(!CPUSET_EMPTY(cpus_expected));
}
printf("\n");
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kgdb_machdep.c,v 1.7 2006/02/11 17:57:32 cdi Exp $ */
/* $NetBSD: kgdb_machdep.c,v 1.8 2006/09/13 11:35:53 mrg Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
@ -128,7 +128,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kgdb_machdep.c,v 1.7 2006/02/11 17:57:32 cdi Exp $");
__KERNEL_RCSID(0, "$NetBSD: kgdb_machdep.c,v 1.8 2006/09/13 11:35:53 mrg Exp $");
#include "opt_kgdb.h"
#include "opt_multiprocessor.h"
@ -226,7 +226,7 @@ kgdb_suspend()
while (cpuinfo.flags & CPUFLG_PAUSED)
cpuinfo.cache_flush((caddr_t)&cpuinfo.flags, sizeof(cpuinfo.flags));
}
#endif
#endif /* MULTIPROCESSOR */
/*
* Trap into kgdb to wait for debugger to connect,
@ -247,7 +247,7 @@ kgdb_connect(verbose)
if (!kgdb_suspend_others()) {
kgdb_suspend();
} else {
#endif
#endif /* MULTIPROCESSOR */
if (verbose)
printf("kgdb waiting...");
__asm("ta %0" :: "n" (T_KGDB_EXEC)); /* trap into kgdb */
@ -258,7 +258,7 @@ kgdb_connect(verbose)
/* Other CPUs can continue now */
kgdb_resume_others();
}
#endif
#endif /* MULTIPROCESSOR */
}
/*
@ -353,7 +353,7 @@ kgdb_getregs(regs, gdb_regs)
db_regs_t *regs;
kgdb_reg_t *gdb_regs;
{
struct trapframe64 *tf = &regs->ddb_tf;
struct trapframe64 *tf = &regs->db_tf;
/* %g0..%g7 and %o0..%o7: from trapframe */
gdb_regs[0] = 0;
@ -378,7 +378,7 @@ kgdb_setregs(regs, gdb_regs)
db_regs_t *regs;
kgdb_reg_t *gdb_regs;
{
struct trapframe64 *tf = &regs->ddb_tf;
struct trapframe64 *tf = &regs->db_tf;
kgdb_copy((caddr_t)&gdb_regs[1], (caddr_t)&tf->tf_global[1], 15 * 8);
kgdb_copy((caddr_t)&gdb_regs[GDB_L0], (caddr_t)(long)tf->tf_out[6], 16 * 8);

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.214 2006/09/09 22:47:12 mrg Exp $ */
/* $NetBSD: locore.s,v 1.215 2006/09/13 11:35:53 mrg Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath
@ -1548,15 +1548,11 @@ intr_setup_msg:
\
add %g6, %g7, %g6; \
rdpr %wstate, %g7; /* Find if we're from user mode */ \
\
\
\
\
sub %g7, WSTATE_KERN, %g7; /* Compare & leave in register */ \
\
movrz %g7, %sp, %g6; /* Select old (kernel) stack or base of kernel stack */ \
\
\
btst 1, %g6; /* Fixup 64-bit stack if necessary */ \
bnz,pt %icc, 1f; \
\
@ -3310,6 +3306,7 @@ breakpoint:
rdpr %cwp, %g7
inc 1, %g7 ! Equivalent of save
wrpr %g7, 0, %cwp ! Now we have some unused locals to fiddle with
XXX ddb_regs is now ddb-regp and is a pointer not a symbol.
set _C_LABEL(ddb_regs), %l0
stx %g1, [%l0+DBR_IG+(1*8)] ! Save IGs
stx %g2, [%l0+DBR_IG+(2*8)]
@ -3585,8 +3582,8 @@ syscall_setup:
clr %g4
wr %g0, ASI_PRIMARY_NOFAULT, %asi ! Restore default ASI
set CURLWP, %l1
LDPTR [%l1], %l1
sethi %hi(CURLWP), %l1
LDPTR [%l1 + %lo(CURLWP)], %l1
LDPTR [%l1 + L_PROC], %l1 ! now %l1 points to p
LDPTR [%l1 + P_MD_SYSCALL], %l1
call %l1
@ -3754,27 +3751,6 @@ setup_sparcintr:
bne,pn %xcc, 1b ! No, try again
nop
2:
#ifdef NOT_DEBUG
set _C_LABEL(intrdebug), %g7
ld [%g7], %g7
btst INTRDEBUG_VECTOR, %g7
bz,pt %icc, 97f
nop
STACKFRAME(-CC64FSZ) ! Get a clean register window
LOAD_ASCIZ(%o0,\
"interrupt_vector: number %lx softint mask %lx pil %lu slot %p\r\n")
mov %g2, %o1
rdpr %pil, %o3
mov %g1, %o4
GLOBTOLOC
clr %g4
call prom_printf
mov %g6, %o2
LOCTOGLOB
restore
97:
#endif
mov 1, %g7
sll %g7, %g6, %g6
wr %g6, 0, SET_SOFTINT ! Invoke a softint
@ -3791,7 +3767,6 @@ ret_from_intr_vector:
stx %g5, [%g3 + KTR_PARM3]
12:
#endif
CLRTT
retry
NOTREACHED
@ -3803,6 +3778,7 @@ ret_from_intr_vector:
bz,pt %icc, 97f
nop
#endif
#if 1
STACKFRAME(-CC64FSZ) ! Get a clean register window
LOAD_ASCIZ(%o0, "interrupt_vector: spurious vector %lx at pil %d\r\n")
mov %g2, %o1
@ -3813,10 +3789,34 @@ ret_from_intr_vector:
LOCTOGLOB
restore
97:
#endif
ba,a ret_from_intr_vector
nop ! XXX spitfire bug?
#if defined(MULTIPROCESSOR)
/*
* IPI handler to halt the CPU. Just calls the C vector.
* void sparc64_ipi_halt(void *);
*/
ENTRY(sparc64_ipi_halt)
call _C_LABEL(sparc64_ipi_halt_thiscpu)
clr %g4
ba,a ret_from_intr_vector
nop
/*
* IPI handler to pause the CPU. We just trap to the debugger if it
* is configured, otherwise just return.
*/
ENTRY(sparc64_ipi_pause)
#if defined(DDB)
sparc64_ipi_pause_trap_point:
ta 1
nop
#endif
ba,a ret_from_intr_vector
nop
/*
* IPI handler to flush single pte.
* void sparc64_ipi_flush_pte(void *);
@ -3826,13 +3826,20 @@ ret_from_intr_vector:
* %g2 - pointer to 'ipi_tlb_args' structure
*/
ENTRY(sparc64_ipi_flush_pte)
#if 0 & KTR_COMPILE & KTR_PMAP
#if KTR_COMPILE & KTR_PMAP
CATR(KTR_TRAP, "sparc64_ipi_flush_pte:",
%g1, %g3, %g4, 10, 11, 12)
12:
#endif
#if 0
STACKFRAME(-CC64FSZ)
LDPTR [%g2 + ITA_VADDR], %o0
call sp_tlb_flush_pte
ld [%g2 + ITA_CTX], %o1
#endif
ba,a ret_from_intr_vector
nop
restore
/*
* IPI handler to flush single context.
@ -3848,22 +3855,21 @@ ENTRY(sparc64_ipi_flush_ctx)
%g1, %g3, %g4, 10, 11, 12)
12:
#endif
#if 0
STACKFRAME(-CC64FSZ)
call sp_tlb_flush_ctx
ld [%g2 + ITA_CTX], %o0
#endif
ba,a ret_from_intr_vector
nop
restore
/*
* IPI handler to flush the whole TLB.
* void sparc64_ipi_flush_all(void *);
*
* On Entry:
*
* %g2 - pointer to 'ipi_tlb_args' structure
*/
ENTRY(sparc64_ipi_flush_all)
! rdpr %pstate, %g3
! andn %g3, PSTATE_IE, %g2 ! disable interrupts
! wrpr %g2, 0, %pstate
#if 0 & KTR_COMPILE & KTR_PMAP
#if KTR_COMPILE & KTR_PMAP
CATR(KTR_TRAP, "sparc64_ipi_flush_all: %p %p",
%g1, %g4, %g5, 10, 11, 12)
stx %g3, [%g1 + KTR_PARM1]
@ -4367,7 +4373,16 @@ rft_kernel:
#if 0
wrpr %g0, 0, %cleanwin ! DEBUG
#endif
retry ! We should allow some way to distinguish retry/done
#if defined(DDB) && defined(MULTIPROCESSOR)
set sparc64_ipi_pause_trap_point, %g1
rdpr %tpc, %g2
cmp %g1, %g2
bne,pt %icc, 0f
nop
done
0:
#endif
retry
NOTREACHED
/*
* Return from trap, to user. Checks for scheduling trap (`ast') first;
@ -5094,6 +5109,7 @@ _C_LABEL(cpu_initialize):
wrpr %g0, 0, %tpc
wrpr %g0, 0, %tnpc
wrpr %g0, 0, %tstate
wrpr %g0, 0, %tl
#endif
#ifdef DEBUG
@ -5262,6 +5278,8 @@ ENTRY(cpu_mp_startup)
sethi %hi(_C_LABEL(sched_whichqs)), %l2
sethi %hi(CURLWP), %l7
sethi %hi(CPCB), %l6
LDPTR [%l7 + %lo(CURLWP)], %l4
LDPTR [%l6 + %lo(CPCB)], %l5
set _C_LABEL(idle), %l1
jmpl %l1, %g0
@ -5272,7 +5290,7 @@ ENTRY(cpu_mp_startup)
.globl cpu_mp_startup_end
cpu_mp_startup_end:
#endif
#endif /* MULTIPROCESSOR */
.align 8
ENTRY(get_romtba)
@ -5613,7 +5631,7 @@ ENTRY(sp_tlb_flush_all)
ldxa [%o0] ASI_DMMU_TLB_TAG, %o2 ! fetch the TLB tag
andcc %o2, %o5, %o1 ! context 0?
bz,pt %xcc, 1f ! if so, skip
set CTX_SECONDARY, %o2
mov CTX_SECONDARY, %o2
stxa %o1, [%o2] ASI_DMMU ! set the context
set DEMAP_CTX_SECONDARY, %o2
@ -5636,7 +5654,7 @@ ENTRY(sp_tlb_flush_all)
ldxa [%o0] ASI_IMMU_TLB_TAG, %o2 ! fetch the TLB tag
andcc %o2, %o5, %o1 ! context 0?
bz,pt %xcc, 1f ! if so, skip
set CTX_SECONDARY, %o2
mov CTX_SECONDARY, %o2
stxa %o1, [%o2] ASI_DMMU ! set the context
set DEMAP_CTX_SECONDARY, %o2
@ -6732,7 +6750,7 @@ ENTRY(cpu_exit)
#ifdef DEBUG
flushw ! DEBUG
sethi %hi(IDLE_U), %l6
LDPTR [%l1 + %lo(IDLE_U)], %l6
LDPTR [%l6 + %lo(IDLE_U)], %l6
! set _C_LABEL(idle_u), %l6
SET_SP_REDZONE(%l6, %l5)
#endif
@ -6759,7 +6777,7 @@ ENTRY(cpu_exit)
* REGISTER USAGE AT THIS POINT:
* %l2 = %hi(_whichqs)
* %l4 = lastproc
* %l5 = oldpsr (excluding ipl bits)
* %l5 = cpcb
* %l6 = %hi(cpcb)
* %l7 = %hi(curlwp)
* %o0 = tmp 1
@ -6775,11 +6793,13 @@ ENTRY(cpu_exit)
sethi %hi(CPCB), %l6
sethi %hi(CURLWP), %l7
ldxa [%o0] ASI_DMMU, %l1 ! Don't demap the kernel
#if 0
LDPTR [%l6 + %lo(CPCB)], %l5
#endif
clr %l4 ! lastproc = NULL;
brz,pn %l1, 1f
#ifdef SPITFIRE
set DEMAP_CTX_SECONDARY, %l1 ! Demap secondary context
mov DEMAP_CTX_SECONDARY, %l1 ! Demap secondary context
stxa %g1, [%l1] ASI_DMMU_DEMAP
stxa %g1, [%l1] ASI_IMMU_DEMAP
membar #Sync
@ -6886,7 +6906,6 @@ idlemsg1: .asciz " %x %x %x\r\n"
*/
.globl _C_LABEL(time)
ENTRY(cpu_switch)
save %sp, -CC64FSZ, %sp
/*
* REGISTER USAGE AT THIS POINT:
* %l1 = tmp 0
@ -6903,6 +6922,8 @@ ENTRY(cpu_switch)
* %o4 = tmp 5, then at Lsw_scan, which
* %o5 = tmp 6, then at Lsw_scan, q
*/
save %sp, -CC64FSZ, %sp
mov %i0, %l4 ! save lwp
#ifdef NOTDEF_DEBUG
set _C_LABEL(intrdebug), %l1
mov INTRDEBUG_FUNC, %o1
@ -6915,13 +6936,15 @@ ENTRY(cpu_switch)
sethi %hi(CPCB), %l6
sethi %hi(_C_LABEL(sched_whichqs)), %l2 ! set up addr regs
LDPTR [%l6 + %lo(CPCB)], %l5
sethi %hi(CURLWP), %l7
stx %o7, [%l5 + PCB_PC] ! cpcb->pcb_pc = pc;
LDPTR [%l7 + %lo(CURLWP)], %l4 ! lastlwp = curlwp;
sth %o1, [%l5 + PCB_PSTATE] ! cpcb->pcb_pstate = oldpstate;
STPTR %g0, [%l7 + %lo(CURLWP)] ! curlwp = NULL;
stx %i7, [%l5 + PCB_PC] ! cpcb->pcb_pc = pc;
stx %i6, [%l5 + PCB_SP]
#if KTR_COMPILE & KTR_PROC
CATR(KTR_TRAP, "cpu_switch: %p",
%g2, %g3, %g1, 10, 11, 12)
@ -7055,7 +7078,7 @@ cpu_loadproc:
*/
call _C_LABEL(sched_unlock_idle)
#endif
STPTR %l4, [%l7 + %lo(CURLWP)] ! restore old lwp so we can save it
STPTR %l3, [%l7 + %lo(CURLWP)] ! store new lwp
#if KTR_COMPILE & KTR_PROC
CATR(KTR_TRAP, "cpu_switch: %p->%p",
@ -7332,6 +7355,7 @@ ENTRY(cpu_switchto)
LDPTR [%l6 + %lo(CPCB)], %l5
stx %o7, [%l5 + PCB_PC] ! cpcb->pcb_pc = pc;
stx %o6, [%l5 + PCB_SP] ! cpcb->pcb_sp = sp;
mov %i0, %l4 ! lastproc = curlwp; (hope he's right)
sth %o1, [%l5 + PCB_PSTATE] ! cpcb->pcb_pstate = oldpstate;

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.189 2006/09/03 22:27:45 gdamore Exp $ */
/* $NetBSD: machdep.c,v 1.190 2006/09/13 11:35:53 mrg Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.189 2006/09/03 22:27:45 gdamore Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.190 2006/09/13 11:35:53 mrg Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@ -634,7 +634,7 @@ cpu_reboot(register int howto, char *user_boot_string)
#if defined(MULTIPROCESSOR)
/* Stop all secondary cpus */
sparc64_ipi_halt_cpus();
mp_halt_cpus();
#endif
/* If rebooting and a dump is requested, do it. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.172 2006/06/10 06:47:43 rjs Exp $ */
/* $NetBSD: pmap.c,v 1.173 2006/09/13 11:35:53 mrg Exp $ */
/*
*
* Copyright (C) 1996-1999 Eduardo Horvath.
@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.172 2006/06/10 06:47:43 rjs Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.173 2006/09/13 11:35:53 mrg Exp $");
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
#define HWREF

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.133 2006/07/23 22:06:07 ad Exp $ */
/* $NetBSD: trap.c,v 1.134 2006/09/13 11:35:53 mrg Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.133 2006/07/23 22:06:07 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.134 2006/09/13 11:35:53 mrg Exp $");
#define NEW_FPSTATE
@ -113,7 +113,6 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.133 2006/07/23 22:06:07 ad Exp $");
#endif
/* trapstats */
int trapstats = 0;
int protfix = 0;
int udmiss = 0; /* Number of normal/nucleus data/text miss/protection faults */
int udhit = 0;
@ -371,7 +370,6 @@ const char *trap_type[] = {
#define N_TRAP_TYPES (sizeof trap_type / sizeof *trap_type)
void trap(struct trapframe64 *, unsigned int, vaddr_t, long);
void data_access_fault(struct trapframe64 *, unsigned int, vaddr_t, vaddr_t,
vaddr_t, u_long);
@ -384,6 +382,7 @@ void text_access_error(struct trapframe64 *, unsigned int, vaddr_t, u_long,
#ifdef DEBUG
void print_trapframe(struct trapframe64 *);
void
print_trapframe(struct trapframe64 *tf)
{
@ -571,8 +570,8 @@ dopanic:
{
char sbuf[sizeof(PSTATE_BITS) + 64];
printf("trap type 0x%x: pc=%lx",
type, pc);
printf("trap type 0x%x: cpu %ld, pc=%lx",
type, CPU_UPAID, pc);
bitmask_snprintf(pstate, PSTATE_BITS, sbuf,
sizeof(sbuf));
printf(" npc=%lx pstate=%s\n",
@ -1106,9 +1105,9 @@ data_access_fault(struct trapframe64 *tf, unsigned int type, vaddr_t pc,
* message.
*/
if (curlwp == NULL) {
panic("kernel data access fault accessing"
" 0x%lx at pc 0x%lx\n",
va, (long)tf->tf_pc);
panic("cpu%d: kernel data access fault "
"accessing 0x%lx at pc 0x%lx\n",
cpu_number(), va, (long)tf->tf_pc);
}
#endif
rv = uvm_fault(kernel_map, va, access_type);