Add rudimentary multiprocessor support for DDB.
This commit is contained in:
parent
cae5d5a796
commit
f81f19e7b3
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.h,v 1.59 2001/06/04 15:34:15 ragge Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.60 2001/06/04 21:37:12 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden
|
||||
|
@ -94,6 +94,7 @@ struct cpu_mp_dep {
|
|||
#define IPI_SEND_CNCHAR 2 /* Write char to console, kernel printf */
|
||||
#define IPI_RUNNING 3 /* This CPU just started to run */
|
||||
#define IPI_TBIA 4 /* Flush the TLB */
|
||||
#define IPI_DDB 5 /* Jump into the DDB loop */
|
||||
|
||||
#define IPI_DEST_MASTER -1 /* Destination is mastercpu */
|
||||
#define IPI_DEST_ALL -2 /* Broadcast */
|
||||
|
@ -133,10 +134,12 @@ struct cpu_info {
|
|||
vaddr_t ci_istack; /* Interrupt stack location */
|
||||
int ci_flags; /* See below */
|
||||
long ci_ipimsgs; /* Sent IPI bits */
|
||||
struct trapframe *ci_ddb_regs; /* Used by DDB */
|
||||
#endif
|
||||
};
|
||||
#define CI_MASTERCPU 1 /* Set if master CPU */
|
||||
#define CI_RUNNING 2 /* Set when a slave CPU is running */
|
||||
#define CI_STOPPED 4 /* Stopped (in debugger) */
|
||||
|
||||
#if defined(MULTIPROCESSOR)
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: db_machdep.h,v 1.9 2001/05/02 15:59:38 matt Exp $ */
|
||||
/* $NetBSD: db_machdep.h,v 1.10 2001/06/04 21:37:12 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Mach Operating System
|
||||
|
@ -71,6 +71,8 @@ db_regs_t ddb_regs; /* register state */
|
|||
#define inst_load(ins) 0
|
||||
#define inst_store(ins) 0
|
||||
|
||||
#define DB_MACHINE_COMMANDS
|
||||
|
||||
/* Prototypes */
|
||||
void kdb_trap __P((struct trapframe *));
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lock.h,v 1.7 2001/06/04 15:37:05 ragge Exp $ */
|
||||
/* $NetBSD: lock.h,v 1.8 2001/06/04 21:37:12 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Ludd, University of Lule}, Sweden.
|
||||
|
@ -70,6 +70,7 @@ __cpu_simple_lock_try(__cpu_simple_lock_t *alp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define VAX_LOCK_CHECKS ((1 << IPI_SEND_CNCHAR) | (1 << IPI_DDB))
|
||||
#define __cpu_simple_lock(alp) \
|
||||
{ \
|
||||
struct cpu_info *__ci = curcpu(); \
|
||||
|
@ -77,7 +78,7 @@ __cpu_simple_lock_try(__cpu_simple_lock_t *alp)
|
|||
while (__cpu_simple_lock_try(alp) == 0) { \
|
||||
int __s; \
|
||||
\
|
||||
if (__ci->ci_ipimsgs & (1 << IPI_SEND_CNCHAR)) { \
|
||||
if (__ci->ci_ipimsgs & VAX_LOCK_CHECKS) { \
|
||||
__s = splipi(); \
|
||||
cpu_handle_ipi(); \
|
||||
splx(__s); \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: db_machdep.c,v 1.28 2001/04/29 22:17:24 matt Exp $ */
|
||||
/* $NetBSD: db_machdep.c,v 1.29 2001/06/04 21:37:11 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* :set tabs=4
|
||||
|
@ -38,6 +38,7 @@
|
|||
* Taken from i386 port and modified for vax.
|
||||
*/
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -49,11 +50,11 @@
|
|||
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/intr.h>
|
||||
#include <vax/vax/gencons.h>
|
||||
|
||||
|
@ -65,15 +66,57 @@
|
|||
#include <ddb/db_interface.h>
|
||||
#include <ddb/db_variables.h>
|
||||
|
||||
extern label_t *db_recover;
|
||||
#include "ioconf.h"
|
||||
|
||||
void kdbprinttrap __P((int, int));
|
||||
extern label_t *db_recover;
|
||||
|
||||
void kdbprinttrap(int, int);
|
||||
|
||||
int db_active = 0;
|
||||
|
||||
extern int qdpolling;
|
||||
static int splsave; /* IPL before entering debugger */
|
||||
|
||||
#ifdef MULTIPROCESSOR
|
||||
static struct cpu_info *stopcpu;
|
||||
/*
|
||||
* Only the master CPU is allowed to enter DDB, but the correct frames
|
||||
* must still be there. Keep the state-machine here.
|
||||
*/
|
||||
static int
|
||||
pause_cpus(void)
|
||||
{
|
||||
volatile struct cpu_info *ci = curcpu();
|
||||
|
||||
if (stopcpu == NULL) {
|
||||
stopcpu = curcpu();
|
||||
cpu_send_ipi(IPI_DEST_ALL, IPI_DDB);
|
||||
}
|
||||
if ((ci->ci_flags & CI_MASTERCPU) == 0) {
|
||||
ci->ci_flags |= CI_STOPPED;
|
||||
while (ci->ci_flags & CI_STOPPED)
|
||||
;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
resume_cpus(void)
|
||||
{
|
||||
struct cpu_mp_softc *sc;
|
||||
struct cpu_info *ci;
|
||||
int i;
|
||||
|
||||
stopcpu = NULL;
|
||||
for (i = 0; i < cpu_cd.cd_ndevs; i++) {
|
||||
if ((sc = cpu_cd.cd_devs[i]) == NULL)
|
||||
continue;
|
||||
ci = &sc->sc_ci;
|
||||
ci->ci_flags &= ~CI_STOPPED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* VAX Call frame on the stack, this from
|
||||
* "Computer Programming and Architecture, The VAX-11"
|
||||
|
@ -81,16 +124,16 @@ static int splsave; /* IPL before entering debugger */
|
|||
* ISBN 0-932376-07-X
|
||||
*/
|
||||
typedef struct __vax_frame {
|
||||
u_int vax_cond; /* condition handler */
|
||||
u_int vax_psw:16; /* 16 bit processor status word */
|
||||
u_int vax_regs:12; /* Register save mask. */
|
||||
u_int vax_zero:1; /* Always zero */
|
||||
u_int vax_cond; /* condition handler */
|
||||
u_int vax_psw:16; /* 16 bit processor status word */
|
||||
u_int vax_regs:12; /* Register save mask. */
|
||||
u_int vax_zero:1; /* Always zero */
|
||||
u_int vax_calls:1; /* True if CALLS, false if CALLG */
|
||||
u_int vax_spa:2; /* Stack pointer alignment */
|
||||
u_int *vax_ap; /* argument pointer */
|
||||
u_int vax_spa:2; /* Stack pointer alignment */
|
||||
u_int *vax_ap; /* argument pointer */
|
||||
struct __vax_frame *vax_fp; /* frame pointer of previous frame */
|
||||
u_int vax_pc; /* program counter */
|
||||
u_int vax_args[1]; /* 0 or more arguments */
|
||||
u_int vax_pc; /* program counter */
|
||||
u_int vax_args[1]; /* 0 or more arguments */
|
||||
} VAX_CALLFRAME;
|
||||
|
||||
/*
|
||||
|
@ -100,23 +143,26 @@ typedef struct __vax_frame {
|
|||
* contain the registers when panic was called. (easy to debug).
|
||||
*/
|
||||
void
|
||||
kdb_trap(frame)
|
||||
struct trapframe *frame;
|
||||
kdb_trap(struct trapframe *frame)
|
||||
{
|
||||
int s;
|
||||
#ifdef MULTIPROCESSOR
|
||||
struct cpu_info *ci = curcpu();
|
||||
#endif
|
||||
|
||||
switch (frame->trap) {
|
||||
case T_BPTFLT: /* breakpoint */
|
||||
case T_TRCTRAP: /* single_step */
|
||||
case T_TRCTRAP: /* single_step */
|
||||
break;
|
||||
|
||||
/* XXX todo: should be migrated to use VAX_CALLFRAME at some point */
|
||||
case T_KDBTRAP:
|
||||
#ifndef MULTIPROCESSOR /* No fancy panic stack conversion here */
|
||||
if (panicstr) {
|
||||
struct callsframe *pf, *df;
|
||||
|
||||
df = (void *)frame->fp; /* start of debug's calls */
|
||||
pf = (void *)df->ca_fp; /* start of panic's calls */
|
||||
pf = (void *)df->ca_fp; /* start of panic's calls */
|
||||
bcopy(&pf->ca_argno, &ddb_regs.r0, sizeof(int) * 12);
|
||||
ddb_regs.fp = pf->ca_fp;
|
||||
ddb_regs.pc = pf->ca_pc;
|
||||
|
@ -126,6 +172,7 @@ kdb_trap(frame)
|
|||
ddb_regs.psl |= pf->ca_maskpsw & 0xffe0;
|
||||
ddb_regs.psl |= (splsave << 16);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -139,8 +186,18 @@ kdb_trap(frame)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MULTIPROCESSOR
|
||||
ci->ci_ddb_regs = frame;
|
||||
if (pause_cpus())
|
||||
return;
|
||||
#endif
|
||||
#ifndef MULTIPROCESSOR
|
||||
if (!panicstr)
|
||||
bcopy(frame, &ddb_regs, sizeof(struct trapframe));
|
||||
#else
|
||||
bcopy(stopcpu->ci_ddb_regs, &ddb_regs, sizeof(struct trapframe));
|
||||
printf("stopped on cpu %d\n", stopcpu->ci_cpuid);
|
||||
#endif
|
||||
|
||||
/* XXX Should switch to interrupt stack here, if needed. */
|
||||
|
||||
|
@ -152,11 +209,16 @@ kdb_trap(frame)
|
|||
db_active--;
|
||||
splx(s);
|
||||
|
||||
#ifndef MULTIPROCESSOR
|
||||
if (!panicstr)
|
||||
bcopy(&ddb_regs, frame, sizeof(struct trapframe));
|
||||
#else
|
||||
bcopy(&ddb_regs, stopcpu->ci_ddb_regs, sizeof(struct trapframe));
|
||||
#endif
|
||||
frame->sp = mfpr(PR_USP);
|
||||
|
||||
return;
|
||||
#ifdef MULTIPROCESSOR
|
||||
resume_cpus();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern char *traptypes[];
|
||||
|
@ -182,8 +244,8 @@ kdbprinttrap(type, code)
|
|||
*/
|
||||
void
|
||||
db_read_bytes(addr, size, data)
|
||||
vaddr_t addr;
|
||||
register size_t size;
|
||||
vaddr_t addr;
|
||||
register size_t size;
|
||||
register char *data;
|
||||
{
|
||||
|
||||
|
@ -195,8 +257,8 @@ db_read_bytes(addr, size, data)
|
|||
*/
|
||||
void
|
||||
db_write_bytes(addr, size, data)
|
||||
vaddr_t addr;
|
||||
register size_t size;
|
||||
vaddr_t addr;
|
||||
register size_t size;
|
||||
register char *data;
|
||||
{
|
||||
|
||||
|
@ -225,13 +287,13 @@ const struct db_variable db_regs[] = {
|
|||
{"r7", &ddb_regs.r7, FCN_NULL},
|
||||
{"r8", &ddb_regs.r8, FCN_NULL},
|
||||
{"r9", &ddb_regs.r9, FCN_NULL},
|
||||
{"r10", &ddb_regs.r10, FCN_NULL},
|
||||
{"r11", &ddb_regs.r11, FCN_NULL},
|
||||
{"r10", &ddb_regs.r10, FCN_NULL},
|
||||
{"r11", &ddb_regs.r11, FCN_NULL},
|
||||
{"ap", &ddb_regs.ap, FCN_NULL},
|
||||
{"fp", &ddb_regs.fp, FCN_NULL},
|
||||
{"sp", &ddb_regs.sp, FCN_NULL},
|
||||
{"pc", &ddb_regs.pc, FCN_NULL},
|
||||
{"psl", &ddb_regs.psl, FCN_NULL},
|
||||
{"psl", &ddb_regs.psl, FCN_NULL},
|
||||
};
|
||||
const struct db_variable * const db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
|
||||
|
||||
|
@ -254,7 +316,7 @@ db_dump_stack(VAX_CALLFRAME *fp, u_int stackbase,
|
|||
|
||||
(*pr)("Stack traceback : \n");
|
||||
if (IN_USERLAND(fp)) {
|
||||
(*pr)(" Process is executing in user space.\n");
|
||||
(*pr)(" Process is executing in user space.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -330,20 +392,20 @@ db_dump_stack(VAX_CALLFRAME *fp, u_int stackbase,
|
|||
/*
|
||||
* Implement the trace command which has the form:
|
||||
*
|
||||
* trace <-- Trace panic (same as before)
|
||||
* trace 0x88888 <-- Trace process whose address is 888888
|
||||
* trace/t <-- Trace current process (0 if no current proc)
|
||||
* trace/t 0tnn <-- Trace process nn (0t for decimal)
|
||||
* trace <-- Trace panic (same as before)
|
||||
* trace 0x88888 <-- Trace frame whose address is 888888
|
||||
* trace/t <-- Trace current process (0 if no current proc)
|
||||
* trace/t 0tnn <-- Trace process nn (0t for decimal)
|
||||
*/
|
||||
void
|
||||
db_stack_trace_print(addr, have_addr, count, modif, pr)
|
||||
db_expr_t addr; /* Address parameter */
|
||||
boolean_t have_addr; /* True if addr is valid */
|
||||
db_expr_t count; /* Optional count */
|
||||
char *modif; /* pointer to flag modifier 't' */
|
||||
void (*pr) __P((const char *, ...)); /* Print function */
|
||||
db_expr_t addr; /* Address parameter */
|
||||
boolean_t have_addr; /* True if addr is valid */
|
||||
db_expr_t count; /* Optional count */
|
||||
char *modif; /* pointer to flag modifier 't' */
|
||||
void (*pr) __P((const char *, ...)); /* Print function */
|
||||
{
|
||||
extern vaddr_t proc0paddr;
|
||||
extern vaddr_t proc0paddr;
|
||||
struct proc *p = curproc;
|
||||
struct user *uarea;
|
||||
int trace_proc;
|
||||
|
@ -366,7 +428,11 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
|||
}
|
||||
(*pr)("panic: %s\n", panicstr);
|
||||
/* xxx ? where did we panic and whose stack are we using? */
|
||||
#ifdef MULTIPROCESSOR
|
||||
db_dump_stack((VAX_CALLFRAME *)(ddb_regs.fp), ddb_regs.ap, pr);
|
||||
#else
|
||||
db_dump_stack((VAX_CALLFRAME *)(ddb_regs.sp), ddb_regs.ap, pr);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -385,7 +451,7 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
|||
while (foo != 0) {
|
||||
int digit = (foo >> 28) & 0xf;
|
||||
if (digit > 9) {
|
||||
(*pr)(" No such process.\n");
|
||||
(*pr)(" No such process.\n");
|
||||
return;
|
||||
}
|
||||
tpid = tpid * 10 + digit;
|
||||
|
@ -393,16 +459,13 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
|||
}
|
||||
p = pfind(tpid);
|
||||
if (p == NULL) {
|
||||
(*pr)(" No such process.\n");
|
||||
(*pr)(" No such process.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p = (struct proc *)(addr);
|
||||
if (pfind(p->p_pid) != p) {
|
||||
(*pr)(" This address does not point to a valid process.\n");
|
||||
return;
|
||||
}
|
||||
db_dump_stack((VAX_CALLFRAME *)addr, 0, pr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (trace_proc) {
|
||||
|
@ -426,28 +489,28 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
|||
curpid = p->p_pid;
|
||||
}
|
||||
(*pr)("Process %d\n", curpid);
|
||||
(*pr)(" PCB contents:\n");
|
||||
(*pr)(" KSP = 0x%x\n", (unsigned int)(uarea->u_pcb.KSP));
|
||||
(*pr)(" ESP = 0x%x\n", (unsigned int)(uarea->u_pcb.ESP));
|
||||
(*pr)(" SSP = 0x%x\n", (unsigned int)(uarea->u_pcb.SSP));
|
||||
(*pr)(" USP = 0x%x\n", (unsigned int)(uarea->u_pcb.USP));
|
||||
(*pr)(" R[00] = 0x%08x R[06] = 0x%08x\n",
|
||||
(*pr)(" PCB contents:\n");
|
||||
(*pr)(" KSP = 0x%x\n", (unsigned int)(uarea->u_pcb.KSP));
|
||||
(*pr)(" ESP = 0x%x\n", (unsigned int)(uarea->u_pcb.ESP));
|
||||
(*pr)(" SSP = 0x%x\n", (unsigned int)(uarea->u_pcb.SSP));
|
||||
(*pr)(" USP = 0x%x\n", (unsigned int)(uarea->u_pcb.USP));
|
||||
(*pr)(" R[00] = 0x%08x R[06] = 0x%08x\n",
|
||||
(unsigned int)(uarea->u_pcb.R[0]), (unsigned int)(uarea->u_pcb.R[6]));
|
||||
(*pr)(" R[01] = 0x%08x R[07] = 0x%08x\n",
|
||||
(*pr)(" R[01] = 0x%08x R[07] = 0x%08x\n",
|
||||
(unsigned int)(uarea->u_pcb.R[1]), (unsigned int)(uarea->u_pcb.R[7]));
|
||||
(*pr)(" R[02] = 0x%08x R[08] = 0x%08x\n",
|
||||
(*pr)(" R[02] = 0x%08x R[08] = 0x%08x\n",
|
||||
(unsigned int)(uarea->u_pcb.R[2]), (unsigned int)(uarea->u_pcb.R[8]));
|
||||
(*pr)(" R[03] = 0x%08x R[09] = 0x%08x\n",
|
||||
(*pr)(" R[03] = 0x%08x R[09] = 0x%08x\n",
|
||||
(unsigned int)(uarea->u_pcb.R[3]), (unsigned int)(uarea->u_pcb.R[9]));
|
||||
(*pr)(" R[04] = 0x%08x R[10] = 0x%08x\n",
|
||||
(*pr)(" R[04] = 0x%08x R[10] = 0x%08x\n",
|
||||
(unsigned int)(uarea->u_pcb.R[4]), (unsigned int)(uarea->u_pcb.R[10]));
|
||||
(*pr)(" R[05] = 0x%08x R[11] = 0x%08x\n",
|
||||
(*pr)(" R[05] = 0x%08x R[11] = 0x%08x\n",
|
||||
(unsigned int)(uarea->u_pcb.R[5]), (unsigned int)(uarea->u_pcb.R[11]));
|
||||
(*pr)(" AP = 0x%x\n", (unsigned int)(uarea->u_pcb.AP));
|
||||
(*pr)(" FP = 0x%x\n", (unsigned int)(uarea->u_pcb.FP));
|
||||
(*pr)(" PC = 0x%x\n", (unsigned int)(uarea->u_pcb.PC));
|
||||
(*pr)(" PSL = 0x%x\n", (unsigned int)(uarea->u_pcb.PSL));
|
||||
(*pr)(" Trap frame pointer: 0x%x\n",
|
||||
(*pr)(" AP = 0x%x\n", (unsigned int)(uarea->u_pcb.AP));
|
||||
(*pr)(" FP = 0x%x\n", (unsigned int)(uarea->u_pcb.FP));
|
||||
(*pr)(" PC = 0x%x\n", (unsigned int)(uarea->u_pcb.PC));
|
||||
(*pr)(" PSL = 0x%x\n", (unsigned int)(uarea->u_pcb.PSL));
|
||||
(*pr)(" Trap frame pointer: 0x%x\n",
|
||||
(unsigned int)(uarea->u_pcb.framep));
|
||||
db_dump_stack((VAX_CALLFRAME *)(uarea->u_pcb.FP),
|
||||
(u_int) uarea->u_pcb.KSP, pr);
|
||||
|
@ -522,7 +585,7 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
|||
paddr = proc0paddr;
|
||||
|
||||
stackbase = (ddb_regs.psl & PSL_IS ? istack : paddr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -553,3 +616,31 @@ kdbrint(tkn)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MULTIPROCESSOR
|
||||
|
||||
static void
|
||||
db_mach_cpu(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
||||
{
|
||||
struct cpu_mp_softc *sc;
|
||||
struct cpu_info *ci;
|
||||
|
||||
if ((addr < 0) || (addr >= cpu_cd.cd_ndevs))
|
||||
return db_printf("%ld: cpu out of range\n", addr);
|
||||
if ((sc = cpu_cd.cd_devs[addr]) == NULL)
|
||||
return db_printf("%ld: cpu not configured\n", addr);
|
||||
|
||||
ci = &sc->sc_ci;
|
||||
if ((ci != curcpu()) && ((ci->ci_flags & CI_STOPPED) == 0))
|
||||
return db_printf("cpu %ld not stopped???\n", addr);
|
||||
|
||||
bcopy(&ddb_regs, stopcpu->ci_ddb_regs, sizeof(struct trapframe));
|
||||
stopcpu = ci;
|
||||
bcopy(stopcpu->ci_ddb_regs, &ddb_regs, sizeof(struct trapframe));
|
||||
db_printf("using cpu %ld", addr);
|
||||
}
|
||||
|
||||
const struct db_command db_machine_command_table[] = {
|
||||
{ "cpu", db_mach_cpu, 0, 0 },
|
||||
{ (char *)0, },
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: multicpu.c,v 1.8 2001/06/04 15:34:16 ragge Exp $ */
|
||||
/* $NetBSD: multicpu.c,v 1.9 2001/06/04 21:37:11 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
|
||||
|
@ -221,6 +221,11 @@ cpu_handle_ipi()
|
|||
case IPI_TBIA:
|
||||
mtpr(0, PR_TBIA);
|
||||
break;
|
||||
case IPI_DDB:
|
||||
Debugger();
|
||||
break;
|
||||
default:
|
||||
panic("cpu_handle_ipi: bad bit %x\n", bitno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue