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:
parent
bada0c776a
commit
2102e18c4b
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 = ®s->ddb_tf;
|
||||
struct trapframe64 *tf = ®s->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 = ®s->ddb_tf;
|
||||
struct trapframe64 *tf = ®s->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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue