DDB for mips.
Add DDB interface to /sys/arch/mips/mips.. Rework heuristic stack traceback to work with DDB. Add hooks to print exception log from DDB. Add hooks from pmax console drivers: call Debugger() after break from serial console, or 'DO' key from LK-xxx.
This commit is contained in:
parent
d65e85e261
commit
d1ec048977
|
@ -0,0 +1,71 @@
|
|||
/* $NetBSD */
|
||||
|
||||
#ifndef _MIPS_DB_MACHDEP_H_
|
||||
#define _MIPS_DB_MACHDEP_H_
|
||||
|
||||
#include <vm/vm_param.h> /* XXX boolean_t */
|
||||
#include <mips/trap.h> /* T_BREAK */
|
||||
#include <mips/reg.h> /* register names */
|
||||
#include <mips/proc.h> /* register state */
|
||||
|
||||
|
||||
typedef vm_offset_t db_addr_t; /* address - unsigned */
|
||||
typedef long db_expr_t; /* expression - signed */
|
||||
|
||||
typedef struct frame db_regs_t;
|
||||
|
||||
db_regs_t ddb_regs; /* register state */
|
||||
#define DDB_REGS (&ddb_regs)
|
||||
|
||||
#define PC_REGS(regs) ((db_addr_t)(regs)->f_regs[PC])
|
||||
|
||||
#define BKPT_INST 0x0001000D /* XXX endianness? */
|
||||
#define BKPT_SIZE (4) /* size of breakpoint inst */
|
||||
#define BKPT_SET(inst) (BKPT_INST)
|
||||
|
||||
#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BREAK)
|
||||
#define IS_WATCHPOINT_TRAP(type, code) (0) /* XXX mips3 watchpoint */
|
||||
|
||||
#define inst_trap_return(ins) ((ins)&0)
|
||||
#define inst_return(ins) ((ins)&0)
|
||||
#define inst_load(ins) 0
|
||||
#define inst_store(ins) 0
|
||||
|
||||
/*
|
||||
* Interface to disassembly (shared with mdb)
|
||||
*/
|
||||
db_addr_t db_disasm_insn __P((int insn, db_addr_t loc, boolean_t altfmt));
|
||||
|
||||
|
||||
/*
|
||||
* Entrypoints to DDB for kernel, keyboard drivers, init hook
|
||||
*/
|
||||
void kdb_kbd_trap __P((db_regs_t *));
|
||||
int kdb_trap __P((int type, db_regs_t *));
|
||||
void db_machine_init __P((void));
|
||||
|
||||
|
||||
/*
|
||||
* We use ELF symbols in DDB.
|
||||
*
|
||||
*/
|
||||
/* #define DB_ELF_SYMBOLS */
|
||||
#define DB_AOUT_SYMBOLS */
|
||||
|
||||
/*
|
||||
* MIPS cpus have no hardware single-step.
|
||||
*/
|
||||
#define SOFTWARE_SSTEP
|
||||
|
||||
boolean_t inst_branch __P((int inst));
|
||||
boolean_t inst_call __P((int inst));
|
||||
boolean_t inst_unconditional_flow_transfer __P((int inst));
|
||||
db_addr_t branch_taken __P((int inst, db_addr_t pc, db_regs_t *regs));
|
||||
db_addr_t next_instr_address __P((db_addr_t pc, boolean_t bd));
|
||||
|
||||
/*
|
||||
* We have machine-dependent commands.
|
||||
*/
|
||||
#define DB_MACHINE_COMMANDS
|
||||
|
||||
#endif /* _MIPS_DB_MACHDEP_H_ */
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mips_param.h,v 1.4 1997/06/16 03:52:08 jonathan Exp $ */
|
||||
/* $NetBSD: mips_param.h,v 1.5 1997/07/07 03:54:30 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Architecture name.
|
||||
|
@ -6,6 +6,19 @@
|
|||
#define _MACHINE_ARCH mips
|
||||
#define MACHINE_ARCH "mips"
|
||||
|
||||
/*
|
||||
* NOTE: SSIZE, SINCR and UPAGES must be multiples of CLSIZE.
|
||||
* On mips, UPAGES is fixed by sys/arch/mips/mips/locore code
|
||||
* to be the number of per-process-wired kernel-stack pages/PTES.
|
||||
*/
|
||||
|
||||
#define UPAGES 2 /* pages of u-area */
|
||||
#define UADDR 0xffffc000 /* address of u */
|
||||
#define USPACE (UPAGES*NBPG) /* size of u-area in bytes */
|
||||
#define UVPN (UADDR>>PGSHIFT)/* virtual page number of u */
|
||||
#define KERNELSTACK (UADDR+UPAGES*NBPG) /* top of kernel stack */
|
||||
|
||||
|
||||
/*
|
||||
* Round p (pointer or byte index) up to a correctly-aligned value for all
|
||||
* data types (int, long, ...). The result is u_int and must be cast to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: proc.h,v 1.7 1997/06/15 17:36:25 mhitch Exp $ */
|
||||
/* $NetBSD: proc.h,v 1.8 1997/07/07 03:54:29 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -38,6 +38,8 @@
|
|||
* @(#)proc.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_PROC_H_
|
||||
#define _MIPS_PROC_H_
|
||||
/*
|
||||
* Machine-dependent part of the proc structure for MIPS
|
||||
*/
|
||||
|
@ -63,3 +65,5 @@ struct frame {
|
|||
/* kernel single-step emulation */
|
||||
extern int mips_singlestep __P((struct proc *p));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _MIPS_PROC_H_ */
|
||||
|
|
|
@ -0,0 +1,427 @@
|
|||
/* $NetBSD: db_disasm.c,v 1.1 1997/07/07 03:54:37 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)kadb.c 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
|
||||
#include <machine/reg.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <mips/mips_opcode.h>
|
||||
#include <machine/param.h>
|
||||
#include <mips/db_machdep.h>
|
||||
|
||||
#include <ddb/db_interface.h>
|
||||
#include <ddb/db_output.h>
|
||||
|
||||
static char *op_name[64] = {
|
||||
/* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz",
|
||||
/* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui",
|
||||
/*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
|
||||
/*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37",
|
||||
/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu",
|
||||
/*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache",
|
||||
/*48 */ "ll", "lwc1", "lwc2", "lwc3", "lld", "ldc1", "ldc2", "ld",
|
||||
/*56 */ "sc", "swc1", "swc2", "swc3", "scd", "sdc1", "sdc2", "sd"
|
||||
};
|
||||
|
||||
static char *spec_name[64] = {
|
||||
/* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav",
|
||||
/* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","sync",
|
||||
/*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
|
||||
/*24 */ "mult", "multu","div", "divu", "dmult","dmultu","ddiv","ddivu",
|
||||
/*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor",
|
||||
/*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu",
|
||||
/*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
|
||||
/*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
|
||||
};
|
||||
|
||||
static char *bcond_name[32] = {
|
||||
/* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?",
|
||||
/* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
|
||||
/*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
|
||||
/*24 */ "?", "?", "?", "?", "?", "?", "?", "?",
|
||||
};
|
||||
|
||||
static char *cop1_name[64] = {
|
||||
/* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
|
||||
/* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
|
||||
/*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
|
||||
/*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
|
||||
/*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
|
||||
/*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
|
||||
/*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
|
||||
"fcmp.ole","fcmp.ule",
|
||||
/*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
|
||||
"fcmp.le","fcmp.ngt"
|
||||
};
|
||||
|
||||
static char *fmt_name[16] = {
|
||||
"s", "d", "e", "fmt3",
|
||||
"w", "fmt5", "fmt6", "fmt7",
|
||||
"fmt8", "fmt9", "fmta", "fmtb",
|
||||
"fmtc", "fmtd", "fmte", "fmtf"
|
||||
};
|
||||
|
||||
static char *reg_name[32] = {
|
||||
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
|
||||
};
|
||||
|
||||
static char *c0_opname[64] = {
|
||||
"c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
|
||||
"tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
|
||||
"rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
|
||||
"eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
|
||||
"c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
|
||||
"c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
|
||||
"c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
|
||||
"c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
|
||||
};
|
||||
|
||||
static char *c0_reg[32] = {
|
||||
"index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7",
|
||||
"badvaddr","count","tlbhi","c0r11","sr","cause","epc", "prid",
|
||||
"config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23",
|
||||
"c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31"
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Disassemble instruction at 'loc'. 'altfmt' specifies an
|
||||
* (optional) alternate format (altfmt for vax: don't assume
|
||||
* that each external label is a procedure entry mask).
|
||||
* Return address of start of next instruction.
|
||||
* Since this function is used by 'examine' and by 'step'
|
||||
* "next instruction" does NOT mean the next instruction to
|
||||
* be executed but the 'linear' next instruction.
|
||||
*/
|
||||
db_addr_t
|
||||
db_disasm(loc, altfmt)
|
||||
db_addr_t loc;
|
||||
boolean_t altfmt;
|
||||
|
||||
{
|
||||
return (db_disasm_insn(*(int*)loc, loc, altfmt));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disassemble instruction 'insn' nominally at 'loc'.
|
||||
* 'loc' may in fact contain a breakpoint instruction.
|
||||
*/
|
||||
db_addr_t
|
||||
db_disasm_insn(insn, loc, altfmt)
|
||||
int insn;
|
||||
db_addr_t loc;
|
||||
boolean_t altfmt;
|
||||
{
|
||||
InstFmt i;
|
||||
|
||||
i.word = insn;
|
||||
|
||||
switch (i.JType.op) {
|
||||
case OP_SPECIAL:
|
||||
if (i.word == 0) {
|
||||
db_printf("nop");
|
||||
break;
|
||||
}
|
||||
if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
|
||||
db_printf("move\t%s,%s",
|
||||
reg_name[i.RType.rd],
|
||||
reg_name[i.RType.rs]);
|
||||
break;
|
||||
}
|
||||
db_printf("%s", spec_name[i.RType.func]);
|
||||
switch (i.RType.func) {
|
||||
case OP_SLL:
|
||||
case OP_SRL:
|
||||
case OP_SRA:
|
||||
case OP_DSLL:
|
||||
|
||||
case OP_DSRL:
|
||||
case OP_DSRA:
|
||||
case OP_DSLL32:
|
||||
case OP_DSRL32:
|
||||
case OP_DSRA32:
|
||||
db_printf("\t%s,%s,%d",
|
||||
reg_name[i.RType.rd],
|
||||
reg_name[i.RType.rt],
|
||||
i.RType.shamt);
|
||||
break;
|
||||
|
||||
case OP_SLLV:
|
||||
case OP_SRLV:
|
||||
case OP_SRAV:
|
||||
case OP_DSLLV:
|
||||
case OP_DSRLV:
|
||||
case OP_DSRAV:
|
||||
db_printf("\t%s,%s,%s",
|
||||
reg_name[i.RType.rd],
|
||||
reg_name[i.RType.rt],
|
||||
reg_name[i.RType.rs]);
|
||||
break;
|
||||
|
||||
case OP_MFHI:
|
||||
case OP_MFLO:
|
||||
db_printf("\t%s", reg_name[i.RType.rd]);
|
||||
break;
|
||||
|
||||
case OP_JR:
|
||||
case OP_JALR:
|
||||
/* FALLTHROUGH */
|
||||
case OP_MTLO:
|
||||
case OP_MTHI:
|
||||
db_printf("\t%s", reg_name[i.RType.rs]);
|
||||
break;
|
||||
|
||||
case OP_MULT:
|
||||
case OP_MULTU:
|
||||
case OP_DMULT:
|
||||
case OP_DMULTU:
|
||||
case OP_DIV:
|
||||
case OP_DIVU:
|
||||
case OP_DDIV:
|
||||
case OP_DDIVU:
|
||||
db_printf("\t%s,%s",
|
||||
reg_name[i.RType.rs],
|
||||
reg_name[i.RType.rt]);
|
||||
break;
|
||||
|
||||
|
||||
case OP_SYSCALL:
|
||||
case OP_SYNC:
|
||||
break;
|
||||
|
||||
case OP_BREAK:
|
||||
db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
|
||||
break;
|
||||
|
||||
default:
|
||||
db_printf("\t%s,%s,%s",
|
||||
reg_name[i.RType.rd],
|
||||
reg_name[i.RType.rs],
|
||||
reg_name[i.RType.rt]);
|
||||
};
|
||||
break;
|
||||
|
||||
case OP_BCOND:
|
||||
db_printf("%s\t%s,", bcond_name[i.IType.rt],
|
||||
reg_name[i.IType.rs]);
|
||||
goto pr_displ;
|
||||
|
||||
case OP_BLEZ:
|
||||
case OP_BLEZL:
|
||||
case OP_BGTZ:
|
||||
case OP_BGTZL:
|
||||
db_printf("%s\t%s,", op_name[i.IType.op],
|
||||
reg_name[i.IType.rs]);
|
||||
goto pr_displ;
|
||||
|
||||
case OP_BEQ:
|
||||
case OP_BEQL:
|
||||
if (i.IType.rs == 0 && i.IType.rt == 0) {
|
||||
db_printf("b\t");
|
||||
goto pr_displ;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case OP_BNE:
|
||||
case OP_BNEL:
|
||||
db_printf("%s\t%s,%s,", op_name[i.IType.op],
|
||||
reg_name[i.IType.rs],
|
||||
reg_name[i.IType.rt]);
|
||||
pr_displ:
|
||||
db_printf("0x%08lx", loc + 4 + ((short)i.IType.imm << 2));
|
||||
break;
|
||||
|
||||
case OP_COP0:
|
||||
switch (i.RType.rs) {
|
||||
case OP_BCx:
|
||||
case OP_BCy:
|
||||
|
||||
db_printf("bc0%c\t",
|
||||
"ft"[i.RType.rt & COPz_BC_TF_MASK]);
|
||||
goto pr_displ;
|
||||
|
||||
case OP_MT:
|
||||
db_printf("mtc0\t%s,%s",
|
||||
reg_name[i.RType.rt],
|
||||
c0_reg[i.RType.rd]);
|
||||
break;
|
||||
|
||||
case OP_DMT:
|
||||
db_printf("dmtc0\t%s,%s",
|
||||
reg_name[i.RType.rt],
|
||||
c0_reg[i.RType.rd]);
|
||||
break;
|
||||
|
||||
case OP_MF:
|
||||
db_printf("mfc0\t%s,%s",
|
||||
reg_name[i.RType.rt],
|
||||
c0_reg[i.RType.rd]);
|
||||
break;
|
||||
|
||||
case OP_DMF:
|
||||
db_printf("dmfc0\t%s,%s",
|
||||
reg_name[i.RType.rt],
|
||||
c0_reg[i.RType.rd]);
|
||||
break;
|
||||
|
||||
default:
|
||||
db_printf("%s", c0_opname[i.FRType.func]);
|
||||
};
|
||||
break;
|
||||
|
||||
case OP_COP1:
|
||||
switch (i.RType.rs) {
|
||||
case OP_BCx:
|
||||
case OP_BCy:
|
||||
db_printf("bc1%c\t",
|
||||
"ft"[i.RType.rt & COPz_BC_TF_MASK]);
|
||||
goto pr_displ;
|
||||
|
||||
case OP_MT:
|
||||
db_printf("mtc1\t%s,f%d",
|
||||
reg_name[i.RType.rt],
|
||||
i.RType.rd);
|
||||
break;
|
||||
|
||||
case OP_MF:
|
||||
db_printf("mfc1\t%s,f%d",
|
||||
|
||||
reg_name[i.RType.rt],
|
||||
i.RType.rd);
|
||||
break;
|
||||
|
||||
case OP_CT:
|
||||
db_printf("ctc1\t%s,f%d",
|
||||
reg_name[i.RType.rt],
|
||||
i.RType.rd);
|
||||
break;
|
||||
|
||||
case OP_CF:
|
||||
db_printf("cfc1\t%s,f%d",
|
||||
reg_name[i.RType.rt],
|
||||
i.RType.rd);
|
||||
break;
|
||||
|
||||
default:
|
||||
db_printf("%s.%s\tf%d,f%d,f%d",
|
||||
cop1_name[i.FRType.func],
|
||||
fmt_name[i.FRType.fmt],
|
||||
i.FRType.fd, i.FRType.fs, i.FRType.ft);
|
||||
};
|
||||
break;
|
||||
|
||||
case OP_J:
|
||||
case OP_JAL:
|
||||
db_printf("%s\t", op_name[i.JType.op]);
|
||||
db_printf("0x%8lx",(loc & 0xF0000000) | (i.JType.target << 2));
|
||||
break;
|
||||
|
||||
case OP_LWC1:
|
||||
case OP_SWC1:
|
||||
db_printf("%s\tf%d,", op_name[i.IType.op],
|
||||
i.IType.rt);
|
||||
goto loadstore;
|
||||
|
||||
case OP_LB:
|
||||
case OP_LH:
|
||||
case OP_LW:
|
||||
case OP_LD:
|
||||
case OP_LBU:
|
||||
case OP_LHU:
|
||||
case OP_LWU:
|
||||
case OP_SB:
|
||||
case OP_SH:
|
||||
case OP_SW:
|
||||
case OP_SD:
|
||||
db_printf("%s\t%s,", op_name[i.IType.op],
|
||||
reg_name[i.IType.rt]);
|
||||
loadstore:
|
||||
db_printf("%d(%s)", (short)i.IType.imm,
|
||||
reg_name[i.IType.rs]);
|
||||
break;
|
||||
|
||||
case OP_ORI:
|
||||
case OP_XORI:
|
||||
if (i.IType.rs == 0) {
|
||||
db_printf("li\t%s,0x%x",
|
||||
reg_name[i.IType.rt],
|
||||
i.IType.imm);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case OP_ANDI:
|
||||
db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
|
||||
reg_name[i.IType.rt],
|
||||
reg_name[i.IType.rs],
|
||||
i.IType.imm);
|
||||
break;
|
||||
|
||||
case OP_LUI:
|
||||
db_printf("%s\t%s,0x%x", op_name[i.IType.op],
|
||||
reg_name[i.IType.rt],
|
||||
i.IType.imm);
|
||||
break;
|
||||
|
||||
case OP_ADDI:
|
||||
case OP_DADDI:
|
||||
case OP_ADDIU:
|
||||
case OP_DADDIU:
|
||||
if (i.IType.rs == 0) {
|
||||
db_printf("li\t%s,%d",
|
||||
reg_name[i.IType.rt],
|
||||
(short)i.IType.imm);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
|
||||
reg_name[i.IType.rt],
|
||||
reg_name[i.IType.rs],
|
||||
(short)i.IType.imm);
|
||||
}
|
||||
return (loc + 4);
|
||||
}
|
|
@ -0,0 +1,439 @@
|
|||
/* $NetBSD: db_interface.c,v 1.1 1997/07/07 03:54:37 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <mips/cpu.h>
|
||||
#include <mips/cpuregs.h>
|
||||
#include <mips/locore.h>
|
||||
#include <mips/mips_opcode.h>
|
||||
|
||||
#include <mips/db_machdep.h>
|
||||
#include <ddb/db_access.h>
|
||||
#include <ddb/db_command.h>
|
||||
#include <ddb/db_output.h>
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_extern.h>
|
||||
|
||||
#include <dev/cons.h>
|
||||
|
||||
|
||||
/*
|
||||
* forward declarations
|
||||
*/
|
||||
int db_active = 0;
|
||||
|
||||
|
||||
void db_halt_cmd __P((db_expr_t addr, int have_addr, db_expr_t count,
|
||||
char *modif));
|
||||
|
||||
void db_trapdump_cmd __P((db_expr_t addr, int have_addr, db_expr_t count,
|
||||
char *modif));
|
||||
|
||||
void db_tlbdump_cmd __P((db_expr_t addr, int have_addr, db_expr_t count,
|
||||
char *modif));
|
||||
|
||||
extern int kdbpeek __P((vm_offset_t addr));
|
||||
extern void kdbpoke __P((vm_offset_t addr, int newval));
|
||||
extern unsigned MachEmulateBranch __P((unsigned *regsPtr,
|
||||
unsigned instPC, unsigned fpcCSR, int allowNonBranch));
|
||||
extern void mips1_dump_tlb __P((int, int));
|
||||
extern void mips3_dump_tlb __P((int, int));
|
||||
|
||||
|
||||
/*
|
||||
* kdbpoke -- write a value to a kernel virtual address.
|
||||
* XXX should handle KSEG2 addresses and check for unmapped pages.
|
||||
* XXX user-space addresess?
|
||||
* Really belongs wherever kdbpeek() is defined.
|
||||
*/
|
||||
void
|
||||
kdbpoke(vm_offset_t addr, int newval)
|
||||
{
|
||||
*(int*) addr = newval;
|
||||
wbflush();
|
||||
if (CPUISMIPS3) {
|
||||
#ifdef MIPS3
|
||||
mips3_FlushICache((vm_offset_t) addr, sizeof(int));
|
||||
#endif
|
||||
} else {
|
||||
#ifdef MIPS1
|
||||
mips1_FlushICache(MIPS_KSEG0_TO_PHYS(addr), sizeof(int));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Received keyboard interrupt sequence.
|
||||
*/
|
||||
void
|
||||
kdb_kbd_trap(tf)
|
||||
db_regs_t *tf;
|
||||
{
|
||||
if (db_active == 0 && (boothowto & RB_KDB)) {
|
||||
printf("\n\nkernel: keyboard interrupt\n");
|
||||
kdb_trap(-1, tf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* kdb_trap - field a TRACE or BPT trap
|
||||
*/
|
||||
int
|
||||
kdb_trap(type, tf)
|
||||
int type;
|
||||
register db_regs_t *tf;
|
||||
{
|
||||
|
||||
/* fb_unblank(); */
|
||||
|
||||
switch (type) {
|
||||
case T_BREAK: /* breakpoint */
|
||||
case -1: /* keyboard interrupt */
|
||||
break;
|
||||
default:
|
||||
#ifdef notyet
|
||||
printf("kernel: %s trap", trap_type[type & 0xff]);
|
||||
if (db_recover != 0) {
|
||||
db_error("Faulted in DDB; continuing...\n");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
/* Should switch to kdb`s own stack here. */
|
||||
|
||||
/* XXX copy trapframe to ddb_regs */
|
||||
ddb_regs = *tf;
|
||||
|
||||
db_active++;
|
||||
cnpollc(1);
|
||||
db_trap(type, 0 /*code*/);
|
||||
cnpollc(0);
|
||||
db_active--;
|
||||
|
||||
/* write ddb_regs back to trapframe */
|
||||
*tf = ddb_regs;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
Debugger()
|
||||
{
|
||||
asm("break ");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read bytes from kernel address space for debugger.
|
||||
*/
|
||||
void
|
||||
db_read_bytes(addr, size, data)
|
||||
register vm_offset_t addr;
|
||||
register size_t size;
|
||||
register char *data;
|
||||
{
|
||||
while (size >= 4)
|
||||
*((int*)data)++ = kdbpeek(addr), addr += 4, size -= 4;
|
||||
|
||||
if (size) {
|
||||
unsigned tmp;
|
||||
register char *dst = (char*)data;
|
||||
|
||||
tmp = kdbpeek(addr);
|
||||
while (size--) {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
int shift = 24;
|
||||
|
||||
/* want highest -> lowest byte */
|
||||
*dst++ = (tmp >> shift) & 0xFF;
|
||||
shift -= 8;
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
*dst++ = tmp & 0xFF;
|
||||
tmp >>= 8;
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write bytes to kernel address space for debugger.
|
||||
*/
|
||||
void
|
||||
db_write_bytes(addr, size, data)
|
||||
register vm_offset_t addr;
|
||||
register size_t size;
|
||||
register char *data;
|
||||
{
|
||||
/*XXX*/ printf("db_write_bytes(%lx, %d, %p, val %x)\n", addr, size, data,
|
||||
(addr &3 ) == 0? *(u_int*)addr: -1);
|
||||
|
||||
|
||||
while (size >= 4)
|
||||
kdbpoke(addr++, *(int*)data), addr += 4, size -= 4;
|
||||
if (size) {
|
||||
unsigned tmp = kdbpeek(addr), tmp1 = 0;
|
||||
register char *src = (char*)data;
|
||||
|
||||
tmp >>= (size << 3);
|
||||
tmp <<= (size << 3);
|
||||
while (size--) {
|
||||
tmp1 <<= 8;
|
||||
tmp1 |= src[size] & 0xff;
|
||||
}
|
||||
kdbpoke(addr, tmp|tmp1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
db_halt_cmd(addr, have_addr, count, modif)
|
||||
db_expr_t addr;
|
||||
int have_addr;
|
||||
db_expr_t count;
|
||||
char *modif;
|
||||
{
|
||||
/*
|
||||
* Force a halt. Don't sync disks in case we panicked
|
||||
* trying to do just that.
|
||||
*/
|
||||
cpu_reboot(RB_HALT|RB_NOSYNC, 0);
|
||||
}
|
||||
|
||||
void
|
||||
db_tlbdump_cmd(addr, have_addr, count, modif)
|
||||
db_expr_t addr;
|
||||
int have_addr;
|
||||
db_expr_t count;
|
||||
char *modif;
|
||||
{
|
||||
if (CPUISMIPS3) {
|
||||
#ifdef MIPS3
|
||||
mips3_dump_tlb(0, 23);
|
||||
(void)cngetc();
|
||||
mips3_dump_tlb(24, 47);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef MIPS1
|
||||
mips1_dump_tlb(0, 22);
|
||||
(void)cngetc();
|
||||
mips1_dump_tlb(23, 45);
|
||||
(void)cngetc();
|
||||
mips1_dump_tlb(46, 63);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
db_trapdump_cmd(addr, have_addr, count, modif)
|
||||
db_expr_t addr;
|
||||
int have_addr;
|
||||
db_expr_t count;
|
||||
char *modif;
|
||||
{
|
||||
#ifdef DEBUG
|
||||
extern void trapDump __P((char*));
|
||||
trapDump("CPU exception log:");
|
||||
#else
|
||||
db_printf("trap log only available with options DEBUG.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
struct db_command mips_db_command_table[] = {
|
||||
{ "halt", db_halt_cmd, 0, 0 },
|
||||
{ "trapdump", db_trapdump_cmd, 0, 0 },
|
||||
{ "tlb", db_tlbdump_cmd, 0, 0 },
|
||||
{ (char *)0, }
|
||||
};
|
||||
|
||||
void
|
||||
db_machine_init()
|
||||
{
|
||||
db_machine_commands_install(mips_db_command_table);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MD functions for software single-step.
|
||||
* see db_ for a description.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* inst_branch()
|
||||
* returns TRUE iff the instruction might branch.
|
||||
*/
|
||||
boolean_t
|
||||
inst_branch(int inst)
|
||||
{
|
||||
InstFmt i;
|
||||
int delay;
|
||||
|
||||
i.word = inst;
|
||||
delay = 0;
|
||||
|
||||
switch (i.JType.op) {
|
||||
case OP_BCOND:
|
||||
|
||||
case OP_BLEZ:
|
||||
case OP_BLEZL:
|
||||
case OP_BGTZ:
|
||||
case OP_BGTZL:
|
||||
case OP_BEQ:
|
||||
case OP_BEQL:
|
||||
case OP_BNE:
|
||||
case OP_BNEL:
|
||||
delay = 1;
|
||||
break;
|
||||
|
||||
case OP_COP0:
|
||||
switch (i.RType.rs) {
|
||||
case OP_BCx:
|
||||
case OP_BCy:
|
||||
delay = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_COP1:
|
||||
switch (i.RType.rs) {
|
||||
case OP_BCx:
|
||||
case OP_BCy:
|
||||
delay = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
break;
|
||||
|
||||
case OP_J:
|
||||
case OP_JAL:
|
||||
delay = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
#ifdef DEBUG_DDB
|
||||
printf(" inst_branch(0x%x) returns %d\n",
|
||||
inst, delay);
|
||||
#endif
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
boolean_t
|
||||
inst_call(inst)
|
||||
int inst;
|
||||
{
|
||||
register int rv = 0;
|
||||
InstFmt i;
|
||||
i.word = inst;
|
||||
|
||||
if (i.JType.op == OP_SPECIAL)
|
||||
if (i.RType.func == OP_JR || i.RType.func == OP_JAL)
|
||||
rv = 1;
|
||||
else if (i.JType.op == OP_JAL)
|
||||
rv = 1;
|
||||
|
||||
#ifdef DEBUG_DDB
|
||||
printf(" inst_call(0x%x) returns 0x%d\n",
|
||||
inst, rv);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* inst_unctiondional_flow_transfer()
|
||||
* return TRUE if the instruction is an unconditional
|
||||
* transter of flow (i.e. unconditional branch)
|
||||
*/
|
||||
boolean_t
|
||||
inst_unconditional_flow_transfer(int inst)
|
||||
{
|
||||
InstFmt i;
|
||||
int rv = 0;
|
||||
|
||||
if (i.JType.op == OP_J) rv = 1;
|
||||
|
||||
#ifdef DEBUG_DDB
|
||||
printf(" insn_unconditional_flow_transfer(0x%x) returns %d\n",
|
||||
inst, rv);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
db_addr_t
|
||||
branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
|
||||
{
|
||||
vm_offset_t ra;
|
||||
|
||||
ra = (vm_offset_t)MachEmulateBranch(regs->f_regs, pc,
|
||||
(curproc) ? curproc->p_addr->u_pcb.pcb_fpregs.r_regs[32]: 0, 0);
|
||||
#ifdef DEBUG_DDB
|
||||
printf(" branch_taken(0x%lx) returns 0x%lx\n", pc, ra);
|
||||
#endif
|
||||
return (ra);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the address of the first instruction following the
|
||||
* one at "pc", which is either in the taken path of the branch
|
||||
* (bd == TRUE) or not. This is for machines (e.g. mips) with
|
||||
* branch delays.
|
||||
*
|
||||
* XXX (jrs) The above comment makes no sense. Maybe Jason is thinking
|
||||
* of mips3 squashed branches?
|
||||
* In any case, the kernel support can already find the address of the
|
||||
* next instruction. We could just return that and put a single breakpoint
|
||||
* at that address. All the cruft above can go.
|
||||
*/
|
||||
db_addr_t
|
||||
next_instr_address(db_addr_t pc, boolean_t bd)
|
||||
{
|
||||
|
||||
vm_offset_t ra;
|
||||
ra = (vm_offset_t)MachEmulateBranch(ddb_regs.f_regs, pc,
|
||||
(curproc)? curproc->p_addr->u_pcb.pcb_fpregs.r_regs[32]: 0, 1);
|
||||
#ifdef DEBUG_DDB
|
||||
printf(" next_instr_addr(0x%lx, %d) returns 0x%lx\n", pc, bd, ra);
|
||||
#endif
|
||||
return ((db_addr_t) ra);
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1993-1987 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <vm/vm_param.h> /* XXX boolean_t */
|
||||
|
||||
#include <machine/param.h>
|
||||
#include <mips/db_machdep.h>
|
||||
#include <ddb/db_interface.h>
|
||||
#include <ddb/db_output.h>
|
||||
#include <ddb/db_variables.h>
|
||||
#include <ddb/db_sym.h>
|
||||
|
||||
extern int __start __P((void)); /* lowest kernel code address */
|
||||
extern vm_offset_t db_maxoff;
|
||||
extern vm_offset_t getreg_val __P((db_expr_t regno));
|
||||
|
||||
#define REG_ARG(i) (4+i)
|
||||
#define SAVES_RA(x) isa_spill((x),31)
|
||||
|
||||
#define KERN_SAVE_REG_IDX(vp) ( \
|
||||
((vp)->valuep >= (int *)(&((struct mips_saved_state *)0)->s0) && \
|
||||
(vp)->valuep <= (int *)(&((struct mips_saved_state *)0)->s7))? \
|
||||
vp->valuep - (int *)(&((struct mips_saved_state *)0)->s0): \
|
||||
((vp)->valuep >= (int *)(&((struct mips_saved_state *)0)->sp) && \
|
||||
(vp)->valuep <= (int *)(&((struct mips_saved_state *)0)->ra))? \
|
||||
((vp)->valuep-(int *)(&((struct mips_saved_state *)0)->sp)) + \
|
||||
((int *)(&((struct mips_kernel_state *)0)->sp) - (int *)0): \
|
||||
-1)
|
||||
|
||||
extern db_sym_t localsym __P((db_sym_t sym, boolean_t isreg, int *lex_level));
|
||||
|
||||
/*
|
||||
* Machine register set.
|
||||
*/
|
||||
struct mips_saved_state *db_cur_exc_frame = 0;
|
||||
|
||||
/*
|
||||
* forward declarations
|
||||
*/
|
||||
int print_exception_frame __P((register struct mips_saved_state *fp,
|
||||
unsigned epc));
|
||||
|
||||
/*XXX*/
|
||||
extern void stacktrace_subr __P((int a0, int a1, int a2, int a3,
|
||||
u_int pc, u_int sp, u_int fp, u_int ra,
|
||||
void (*)(const char*, ...)));
|
||||
|
||||
/*
|
||||
* Stack trace helper.
|
||||
*/
|
||||
void db_mips_stack_trace __P((int count, vm_offset_t stackp,
|
||||
vm_offset_t the_pc, vm_offset_t the_ra, int flags, vm_offset_t kstackp));
|
||||
|
||||
|
||||
#define DB_SETF_REGS FCN_NULL
|
||||
#define DBREGS_REG()
|
||||
|
||||
struct db_variable db_regs[] = {
|
||||
{ "at", (long *)&ddb_regs.f_regs[AST], DB_SETF_REGS },
|
||||
{ "v0", (long *)&ddb_regs.f_regs[V0], DB_SETF_REGS },
|
||||
{ "v1", (long *)&ddb_regs.f_regs[V1], DB_SETF_REGS },
|
||||
{ "a0", (long *)&ddb_regs.f_regs[A0], DB_SETF_REGS },
|
||||
{ "a1", (long *)&ddb_regs.f_regs[A1], DB_SETF_REGS },
|
||||
{ "a2", (long *)&ddb_regs.f_regs[A2], DB_SETF_REGS },
|
||||
{ "a3", (long *)&ddb_regs.f_regs[A3], DB_SETF_REGS },
|
||||
{ "t0", (long *)&ddb_regs.f_regs[T0], DB_SETF_REGS },
|
||||
{ "t1", (long *)&ddb_regs.f_regs[T1], DB_SETF_REGS },
|
||||
{ "t2", (long *)&ddb_regs.f_regs[T2], DB_SETF_REGS },
|
||||
{ "t3", (long *)&ddb_regs.f_regs[T3], DB_SETF_REGS },
|
||||
{ "t4", (long *)&ddb_regs.f_regs[T4], DB_SETF_REGS },
|
||||
{ "t5", (long *)&ddb_regs.f_regs[T5], DB_SETF_REGS },
|
||||
{ "t6", (long *)&ddb_regs.f_regs[T6], DB_SETF_REGS },
|
||||
{ "t7", (long *)&ddb_regs.f_regs[T7], DB_SETF_REGS },
|
||||
{ "s0", (long *)&ddb_regs.f_regs[S0], DB_SETF_REGS },
|
||||
{ "s1", (long *)&ddb_regs.f_regs[S1], DB_SETF_REGS },
|
||||
{ "s2", (long *)&ddb_regs.f_regs[S2], DB_SETF_REGS },
|
||||
{ "s3", (long *)&ddb_regs.f_regs[S3], DB_SETF_REGS },
|
||||
{ "s4", (long *)&ddb_regs.f_regs[S4], DB_SETF_REGS },
|
||||
{ "s5", (long *)&ddb_regs.f_regs[S5], DB_SETF_REGS },
|
||||
{ "s6", (long *)&ddb_regs.f_regs[S6], DB_SETF_REGS },
|
||||
{ "s7", (long *)&ddb_regs.f_regs[S7], DB_SETF_REGS },
|
||||
{ "t8", (long *)&ddb_regs.f_regs[T8], DB_SETF_REGS },
|
||||
{ "t9", (long *)&ddb_regs.f_regs[T9], DB_SETF_REGS },
|
||||
{ "k0", (long *)&ddb_regs.f_regs[K0], DB_SETF_REGS },
|
||||
{ "k1", (long *)&ddb_regs.f_regs[K1], DB_SETF_REGS },
|
||||
{ "gp", (long *)&ddb_regs.f_regs[GP], DB_SETF_REGS },
|
||||
{ "sp", (long *)&ddb_regs.f_regs[SP], DB_SETF_REGS },
|
||||
{ "fp", (long *)&ddb_regs.f_regs[S8], DB_SETF_REGS }, /* frame ptr */
|
||||
{ "ra", (long *)&ddb_regs.f_regs[RA], DB_SETF_REGS },
|
||||
{ "sr", (long *)&ddb_regs.f_regs[SR], DB_SETF_REGS },
|
||||
{ "mdlo",(long *)&ddb_regs.f_regs[MULLO], DB_SETF_REGS },
|
||||
{ "mdhi",(long *)&ddb_regs.f_regs[MULHI], DB_SETF_REGS },
|
||||
{ "bad", (long *)&ddb_regs.f_regs[BADVADDR], DB_SETF_REGS },
|
||||
{ "cs", (long *)&ddb_regs.f_regs[CAUSE], DB_SETF_REGS },
|
||||
{ "pc", (long *)&ddb_regs.f_regs[PC], DB_SETF_REGS },
|
||||
};
|
||||
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
|
||||
|
||||
|
||||
|
||||
void
|
||||
db_stack_trace_cmd(addr, have_addr, count, modif)
|
||||
db_expr_t addr;
|
||||
boolean_t have_addr;
|
||||
db_expr_t count;
|
||||
char *modif;
|
||||
{
|
||||
stacktrace_subr(ddb_regs.f_regs[A0], ddb_regs.f_regs[A1],
|
||||
ddb_regs.f_regs[A2], ddb_regs.f_regs[A3],
|
||||
ddb_regs.f_regs[PC],
|
||||
ddb_regs.f_regs[SP],
|
||||
ddb_regs.f_regs[S8], /* non-virtual fame pointer */
|
||||
ddb_regs.f_regs[RA],
|
||||
db_printf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
db_mips_stack_trace(count, stackp, the_pc, the_ra, flags, kstackp)
|
||||
int count;
|
||||
vm_offset_t stackp, the_pc, the_ra;
|
||||
int flags;
|
||||
vm_offset_t kstackp;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore.S,v 1.38 1997/06/30 14:42:32 jonathan Exp $ */
|
||||
/* $NetBSD: locore.S,v 1.39 1997/07/07 03:54:31 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -1773,7 +1773,7 @@ END(mdbpanic)
|
|||
|
||||
#endif /* MDB */
|
||||
|
||||
#if defined(DEBUG) || defined(MDB)
|
||||
#if defined(DEBUG) || defined(MDB) || defined(DDB)
|
||||
/*
|
||||
* Stacktrace support hooks which use type punnign to access
|
||||
* the caller's registers.
|
||||
|
@ -1784,42 +1784,62 @@ END(mdbpanic)
|
|||
* stacktrace() -- print a stack backtrace to the console.
|
||||
* implicitly accesses caller's a0-a3.
|
||||
*/
|
||||
NON_LEAF(stacktrace, 32, ra)
|
||||
subu sp,sp,32
|
||||
NON_LEAF(stacktrace, STAND_FRAME_SIZE+20, ra)
|
||||
|
||||
subu sp, sp, STAND_FRAME_SIZE+20 # four arg-passing slots
|
||||
|
||||
move t0, ra # save caller's PC
|
||||
addu t1, sp, STAND_FRAME_SIZE+20 # compute caller's SP
|
||||
move t2, s8 # non-virtual frame pointer
|
||||
|
||||
la v0, _C_LABEL(printf)
|
||||
sw ra,24(sp)
|
||||
|
||||
jal stacktrace_subr
|
||||
sw v0,16(sp)
|
||||
sw ra, 36(sp) # save return address
|
||||
|
||||
lw ra,24(sp)
|
||||
addu sp,sp,32
|
||||
/* a0-a3 are still caller's a0-a3, pass in-place as given. */
|
||||
sw t0, 16(sp) # push caller's PC
|
||||
sw t1, 20(sp) # push caller's SP
|
||||
sw t2, 24(sp) # push caller's FP, in case
|
||||
sw zero, 28(sp) # caller's RA on stack
|
||||
jal _C_LABEL(stacktrace_subr)
|
||||
sw v0, 32(sp) # push printf
|
||||
|
||||
lw ra, 36(sp)
|
||||
addu sp, sp, STAND_FRAME_SIZE+20
|
||||
j ra
|
||||
nop
|
||||
END(stacktrace)
|
||||
|
||||
|
||||
/*
|
||||
* logstacktrace() -- log a stack traceback to msgbuf.
|
||||
* implicitly accesses caller's a0-a3.
|
||||
*/
|
||||
NON_LEAF(logstacktrace, 32, ra)
|
||||
subu sp,sp,32
|
||||
la v0, _C_LABEL(addlog)
|
||||
sw ra,24(sp)
|
||||
NON_LEAF(logstacktrace, STAND_FRAME_SIZE+20, ra)
|
||||
|
||||
jal stacktrace_subr
|
||||
sw v0,16(sp)
|
||||
subu sp, sp, STAND_FRAME_SIZE+20 # four arg-passing slots
|
||||
|
||||
lw ra,24(sp)
|
||||
addu sp,sp,32
|
||||
move t0, ra # save caller's PC
|
||||
addu t1, sp, STAND_FRAME_SIZE+20 # compute caller's SP
|
||||
move t2, s8 # non-virtual frame pointer
|
||||
|
||||
la v0, _C_LABEL(printf)
|
||||
|
||||
sw ra, 36(sp) # save return address
|
||||
|
||||
/* a0-a3 are still caller's a0-a3, pass in-place as given. */
|
||||
sw t0, 16(sp) # push caller's PC
|
||||
sw t1, 20(sp) # push caller's SP
|
||||
sw t2, 24(sp) # push caller's FP, in case
|
||||
sw zero, 28(sp) # RA on stack
|
||||
jal _C_LABEL(stacktrace_subr)
|
||||
sw v0, 32(sp) # push printf
|
||||
|
||||
lw ra, 36(sp)
|
||||
addu sp, sp, STAND_FRAME_SIZE+20
|
||||
j ra
|
||||
END(stacktrace)
|
||||
|
||||
LEAF(cpu_getregs)
|
||||
sw sp, 0(a0)
|
||||
sw ra, 4(a0)
|
||||
j ra
|
||||
sw s8, 8(a0)
|
||||
END(cpu_getregs)
|
||||
nop
|
||||
END(logstacktrace)
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
@ -1830,6 +1850,10 @@ END(cpu_getregs)
|
|||
* XXX will need reworking for SMP.
|
||||
*/
|
||||
.data
|
||||
.globl _C_LABEL(esym)
|
||||
_C_LABEL(esym):
|
||||
.word 0
|
||||
|
||||
.globl _C_LABEL(cpu_id)
|
||||
.globl _C_LABEL(fpu_id)
|
||||
.globl _C_LABEL(cpu_arch)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore_r2000.S,v 1.37 1997/06/25 05:06:01 mhitch Exp $ */
|
||||
/* $NetBSD: locore_r2000.S,v 1.38 1997/07/07 03:54:33 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -222,7 +222,10 @@ NNON_LEAF(mips1_KernGenException, TRAP_FRAME_SIZE, ra)
|
|||
mfc0 a3, MIPS_COP_0_EXC_PC # 4th arg is PC
|
||||
sw v1, TRAP_FRAME_OFFSET+(MULHI * 4)(sp)
|
||||
sw a3, TRAP_FRAME_OFFSET+(PC * 4)(sp)
|
||||
|
||||
#ifdef DDB
|
||||
addu v0, sp, TRAP_FRAME_SIZE # SP at trap for debugging
|
||||
sw v0, TRAP_FRAME_OFFSET+(SP * 4)(sp)
|
||||
#endif DDB
|
||||
jal _C_LABEL(trap)
|
||||
sw a3, TRAP_RA_OFFSET(sp) # for debugging
|
||||
|
||||
|
@ -834,6 +837,8 @@ NLEAF(mips1_TLBMissException)
|
|||
.asciiz "ktlbmiss: PC %x RA %x ADR %x\nSR %x CR %x SP %x\n"
|
||||
.text
|
||||
|
||||
/* Call mips1_dump_tlb(0, 2, printf) to show the bad kstack TLB */
|
||||
la a2, _C_LABEL(printf)
|
||||
li a0,0
|
||||
jal _C_LABEL(mips1_dump_tlb)
|
||||
li a1,3 # BDslot
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore_r4000.S,v 1.38 1997/06/25 05:06:05 mhitch Exp $ */
|
||||
/* $NetBSD: locore_r4000.S,v 1.39 1997/07/07 03:54:35 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author)
|
||||
|
@ -306,7 +306,12 @@ NNON_LEAF(mips3_KernGenException, TRAP_FRAME_SIZE, ra)
|
|||
mfc0 a3, MIPS_COP_0_EXC_PC # Fourth arg is the pc.
|
||||
sw a0, TRAP_FRAME_OFFSET + (SR * 4)(sp)
|
||||
|
||||
#ifdef DDB
|
||||
addu v0, sp, TRAP_FRAME_SIZE # SP at trap for debugging
|
||||
sw v0, TRAP_FRAME_OFFSET+(SP * 4)(sp)
|
||||
#else
|
||||
nop
|
||||
#endif DDB
|
||||
sw a3, TRAP_FRAME_OFFSET + (PC * 4)(sp)
|
||||
mtc0 zero,MIPS_COP_0_STATUS_REG # Set kernel no error level
|
||||
/*
|
||||
|
@ -1093,6 +1098,8 @@ sys_stk_chk:
|
|||
.asciiz "ktlbmiss: PC %x RA %x ADR %x\nSR %x CR %x SP %x\n"
|
||||
.text
|
||||
|
||||
/* Call mips3_dump_tlb(0, 2, printf) to show the bad kstack TLB */
|
||||
la a2, _C_LABEL(printf)
|
||||
li a0, 0
|
||||
jal mips3_dump_tlb
|
||||
li a1, 2 # BDslot
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: trap.c,v 1.68 1997/06/30 14:42:35 jonathan Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.69 1997/07/07 03:54:38 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -76,6 +76,10 @@
|
|||
#include <sys/syslog.h>
|
||||
#include <miscfs/procfs/procfs.h>
|
||||
|
||||
#ifdef DDB
|
||||
#include <mips/db_machdep.h>
|
||||
#endif
|
||||
|
||||
/* all this to get prototypes for ipintr() and arpintr() */
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
|
@ -332,8 +336,8 @@ void trapDump __P((char * msg));
|
|||
#endif /* DEBUG */
|
||||
|
||||
|
||||
void mips1_dump_tlb __P((int, int));
|
||||
void mips3_dump_tlb __P((int, int));
|
||||
void mips1_dump_tlb __P((int, int, void (*printfn)(const char*, ...)));
|
||||
void mips3_dump_tlb __P((int, int, void (*printfn)(const char*, ...)));
|
||||
void mips_dump_tlb __P((int, int));
|
||||
|
||||
/*
|
||||
|
@ -366,9 +370,8 @@ extern void ast __P((unsigned pc));
|
|||
/*
|
||||
* stack trace code, also useful to DDB one day
|
||||
*/
|
||||
#if defined(DEBUG) || defined(MDB)
|
||||
#if defined(DEBUG) || defined(MDB) || defined(DDB)
|
||||
int kdbpeek __P((vm_offset_t addr));
|
||||
extern void cpu_getregs __P((int *));
|
||||
extern void stacktrace __P((void)); /*XXX*/
|
||||
extern void logstacktrace __P((void)); /*XXX*/
|
||||
|
||||
|
@ -666,16 +669,10 @@ trap(status, cause, vaddr, opc, frame)
|
|||
printf("pid=%d cmd=%s\n", p->p_pid, p->p_comm);
|
||||
else
|
||||
printf("curproc == NULL\n");
|
||||
#ifdef MDB
|
||||
frame.f_regs[CAUSE] = cause;
|
||||
frame.f_regs[BADVADDR] = vaddr;
|
||||
mdb(type, (struct frame *)&frame.f_regs);
|
||||
#else
|
||||
#ifdef DEBUG
|
||||
stacktrace();
|
||||
trapDump("trap");
|
||||
#endif /* DEBUG */
|
||||
#endif /* MDB */
|
||||
panic("trap");
|
||||
/*NOTREACHED*/
|
||||
case T_TLB_MOD:
|
||||
|
@ -687,9 +684,6 @@ trap(status, cause, vaddr, opc, frame)
|
|||
pte = kvtopte(vaddr);
|
||||
entry = pte->pt_entry;
|
||||
if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
|
||||
#ifdef MDB
|
||||
mdb(type, (struct frame *)&frame.f_regs);
|
||||
#endif
|
||||
panic("ktlbmod: invalid pte");
|
||||
}
|
||||
/*XXX MIPS3? */ if (entry & mips_pg_ro_bit()) {
|
||||
|
@ -843,6 +837,14 @@ trap(status, cause, vaddr, opc, frame)
|
|||
sig = SIGSEGV;
|
||||
ucode = vaddr;
|
||||
break; /* SIGNAL */
|
||||
|
||||
case T_BREAK:
|
||||
#ifdef DDB
|
||||
kdb_trap(type, (struct frame *)&frame.f_regs);
|
||||
return; /* KERN */
|
||||
#else
|
||||
goto dopanic;
|
||||
#endif
|
||||
case T_BREAK+T_USER:
|
||||
{
|
||||
unsigned va, instr;
|
||||
|
@ -853,6 +855,9 @@ trap(status, cause, vaddr, opc, frame)
|
|||
|
||||
/* read break instruction */
|
||||
instr = fuiword((caddr_t)va);
|
||||
#ifdef DEBUG
|
||||
/*XXX*/ printf("break insn 0x%x\n", instr);
|
||||
#endif
|
||||
|
||||
if (p->p_md.md_ss_addr != va || instr != MIPS_BREAK_SSTEP) {
|
||||
sig = SIGTRAP;
|
||||
|
@ -889,9 +894,10 @@ trap(status, cause, vaddr, opc, frame)
|
|||
uio.uio_rw = UIO_WRITE;
|
||||
uio.uio_procp = curproc;
|
||||
rv = procfs_domem(p, p, NULL, &uio);
|
||||
MachFlushCache();
|
||||
}
|
||||
#endif
|
||||
MachFlushCache();
|
||||
|
||||
if (rv < 0)
|
||||
printf("Warning: can't restore instruction at 0x%x: 0x%x\n",
|
||||
p->p_md.md_ss_addr, p->p_md.md_ss_instr);
|
||||
|
@ -1054,8 +1060,10 @@ trapDump(msg)
|
|||
trp->vadr, trp->pc, trp->cause, trp->status);
|
||||
printf(" RA %x SP %x code %d\n", trp->ra, trp->sp, trp->code);
|
||||
}
|
||||
#ifndef DDB
|
||||
bzero(trapdebug, sizeof(trapdebug));
|
||||
trp = trapdebug;
|
||||
#endif
|
||||
splx(s);
|
||||
}
|
||||
#endif
|
||||
|
@ -1326,13 +1334,15 @@ mips_singlestep(p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined(MDB)
|
||||
#if defined(DEBUG) || defined(MDB) || defined(DDB)
|
||||
int
|
||||
kdbpeek(addr)
|
||||
vm_offset_t addr;
|
||||
{
|
||||
if (addr & 3) {
|
||||
printf("kdbpeek: unaligned address %lx\n", addr);
|
||||
/* We might have been called from DDB, so don\'t go there. */
|
||||
stacktrace();
|
||||
return (-1);
|
||||
}
|
||||
return (*(int *)addr);
|
||||
|
@ -1342,7 +1352,9 @@ kdbpeek(addr)
|
|||
|
||||
/* forward */
|
||||
char *fn_name(unsigned addr);
|
||||
void stacktrace_subr __P((int, int, int, int, void (*)(const char*, ...)));
|
||||
void stacktrace_subr __P((int a0, int a1, int a2, int a3,
|
||||
u_int pc, u_int sp, u_int fp, u_int ra,
|
||||
void (*)(const char*, ...)));
|
||||
|
||||
/*
|
||||
* Do a stack backtrace.
|
||||
|
@ -1350,30 +1362,20 @@ void stacktrace_subr __P((int, int, int, int, void (*)(const char*, ...)));
|
|||
* the console, or both.
|
||||
*/
|
||||
void
|
||||
stacktrace_subr(a0, a1, a2, a3, printfn)
|
||||
stacktrace_subr(a0, a1, a2, a3, pc, sp, fp, ra, printfn)
|
||||
int a0, a1, a2, a3;
|
||||
u_int pc, sp, fp, ra;
|
||||
void (*printfn) __P((const char*, ...));
|
||||
{
|
||||
unsigned pc, sp, fp, ra, va, subr;
|
||||
unsigned va, subr;
|
||||
unsigned instr, mask;
|
||||
InstFmt i;
|
||||
int more, stksize;
|
||||
int regs[3];
|
||||
extern char start[], edata[];
|
||||
unsigned int frames = 0;
|
||||
|
||||
cpu_getregs(regs);
|
||||
|
||||
/* get initial values from the exception frame */
|
||||
sp = regs[0];
|
||||
pc = regs[1];
|
||||
ra = 0;
|
||||
fp = regs[2];
|
||||
|
||||
/* Jump here when done with a frame, to start a new one */
|
||||
loop:
|
||||
ra = 0;
|
||||
|
||||
/* Jump here after a nonstandard (interrupt handler) frame */
|
||||
specialframe:
|
||||
stksize = 0;
|
||||
|
@ -1706,9 +1708,10 @@ fn_name(unsigned addr)
|
|||
* called by mips3 locore after in-kernel TLB miss.
|
||||
*/
|
||||
void
|
||||
mips3_dump_tlb(first, last)
|
||||
mips3_dump_tlb(first, last, printfn)
|
||||
int first;
|
||||
int last;
|
||||
void (*printfn) __P((const char*, ...));
|
||||
{
|
||||
int tlbno;
|
||||
struct tlb tlb;
|
||||
|
@ -1719,20 +1722,20 @@ mips3_dump_tlb(first, last)
|
|||
while(tlbno <= last) {
|
||||
mips3_TLBRead(tlbno, &tlb);
|
||||
if (mips_pg_v(tlb.tlb_lo0) || mips_pg_v(tlb.tlb_lo1)) {
|
||||
printf("TLB %2d vad 0x%08x ", tlbno, tlb.tlb_hi);
|
||||
(*printfn)("TLB %2d vad 0x%08x ", tlbno, tlb.tlb_hi);
|
||||
}
|
||||
else {
|
||||
printf("TLB*%2d vad 0x%08x ", tlbno, tlb.tlb_hi);
|
||||
(*printfn)("TLB*%2d vad 0x%08x ", tlbno, tlb.tlb_hi);
|
||||
}
|
||||
printf("0=0x%08lx ", pfn_to_vad(tlb.tlb_lo0));
|
||||
printf("%c", tlb.tlb_lo0 & mips_pg_m_bit() ? 'M' : ' ');
|
||||
printf("%c", tlb.tlb_lo0 & mips_pg_global_bit() ? 'G' : ' ');
|
||||
printf(" atr %x ", (tlb.tlb_lo0 >> 3) & 7);
|
||||
printf("1=0x%08lx ", pfn_to_vad(tlb.tlb_lo1));
|
||||
printf("%c", tlb.tlb_lo1 & mips_pg_m_bit() ? 'M' : ' ');
|
||||
printf("%c", tlb.tlb_lo1 & mips_pg_global_bit() ? 'G' : ' ');
|
||||
printf(" atr %x ", (tlb.tlb_lo1 >> 3) & 7);
|
||||
printf(" sz=%x\n", tlb.tlb_mask);
|
||||
(*printfn)("0=0x%08lx ", pfn_to_vad(tlb.tlb_lo0));
|
||||
(*printfn)("%c", tlb.tlb_lo0 & mips_pg_m_bit() ? 'M' : ' ');
|
||||
(*printfn)("%c", tlb.tlb_lo0 & mips_pg_global_bit() ? 'G' : ' ');
|
||||
(*printfn)(" atr %x ", (tlb.tlb_lo0 >> 3) & 7);
|
||||
(*printfn)("1=0x%08lx ", pfn_to_vad(tlb.tlb_lo1));
|
||||
(*printfn)("%c", tlb.tlb_lo1 & mips_pg_m_bit() ? 'M' : ' ');
|
||||
(*printfn)("%c", tlb.tlb_lo1 & mips_pg_global_bit() ? 'G' : ' ');
|
||||
(*printfn)(" atr %x ", (tlb.tlb_lo1 >> 3) & 7);
|
||||
(*printfn)(" sz=%x\n", tlb.tlb_mask);
|
||||
|
||||
tlbno++;
|
||||
}
|
||||
|
@ -1744,9 +1747,10 @@ mips3_dump_tlb(first, last)
|
|||
* called by mips3 locore after in-kernel TLB miss.
|
||||
*/
|
||||
void
|
||||
mips1_dump_tlb(first, last)
|
||||
mips1_dump_tlb(first, last, printfn)
|
||||
int first;
|
||||
int last;
|
||||
void (*printfn) __P((const char*, ...));
|
||||
{
|
||||
int tlbno;
|
||||
extern u_int tlbhi, tlblo;
|
||||
|
@ -1757,21 +1761,24 @@ mips1_dump_tlb(first, last)
|
|||
while(tlbno <= last) {
|
||||
mips1_TLBRead(tlbno);
|
||||
if (mips_pg_v(tlblo)) {
|
||||
printf("TLB %2d vad 0x%08x ", tlbno, tlbhi);
|
||||
(*printfn)("TLB %2d vad 0x%08x ", tlbno, tlbhi);
|
||||
}
|
||||
else {
|
||||
printf("TLB*%2d vad 0x%08x ", tlbno, tlbhi);
|
||||
(*printfn)("TLB*%2d vad 0x%08x ", tlbno, tlbhi);
|
||||
}
|
||||
printf("0x%08x ", tlblo & MIPS1_PG_FRAME);
|
||||
printf("%c", tlblo & mips_pg_m_bit() ? 'M' : ' ');
|
||||
printf("%c", tlblo & mips_pg_global_bit() ? 'G' : ' ');
|
||||
printf("%c\n", tlblo & MIPS1_PG_N ? 'N' : ' ');
|
||||
(*printfn)("0x%08x ", tlblo & MIPS1_PG_FRAME);
|
||||
(*printfn)("%c", tlblo & mips_pg_m_bit() ? 'M' : ' ');
|
||||
(*printfn)("%c", tlblo & mips_pg_global_bit() ? 'G' : ' ');
|
||||
(*printfn)("%c\n", tlblo & MIPS1_PG_N ? 'N' : ' ');
|
||||
|
||||
tlbno++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Dump TLB after panic.
|
||||
*/
|
||||
void
|
||||
mips_dump_tlb(first, last)
|
||||
int first;
|
||||
|
@ -1779,11 +1786,11 @@ mips_dump_tlb(first, last)
|
|||
{
|
||||
if (CPUISMIPS3) {
|
||||
#ifdef MIPS3
|
||||
mips3_dump_tlb(first,last);
|
||||
mips3_dump_tlb(first,last, printf);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef MIPS1
|
||||
mips1_dump_tlb(first,last);
|
||||
mips1_dump_tlb(first,last, printf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dc.c,v 1.32 1997/06/16 02:53:38 jonathan Exp $ */
|
||||
/* $NetBSD: dc.c,v 1.33 1997/07/07 03:54:42 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -727,13 +727,14 @@ dcrint(sc)
|
|||
}
|
||||
/* the keyboard requires special translation */
|
||||
if (raster_console() && tp == dc_tty[DCKBD_PORT]) {
|
||||
#ifdef MDB
|
||||
if (cc == LK_DO) {
|
||||
#ifdef DDB
|
||||
spl0();
|
||||
mdbpanic();
|
||||
Debugger();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
debugChar = cc;
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
/* $NetBSD: db_machdep.h,v 1.1 1997/07/07 03:54:24 jonathan Exp $ */
|
||||
|
||||
#include <mips/db_machdep.h>
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: param.h,v 1.20 1997/06/15 18:02:20 mhitch Exp $ */
|
||||
/* $NetBSD: param.h,v 1.21 1997/07/07 03:54:25 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -68,15 +68,13 @@
|
|||
#define CLSIZE 1
|
||||
#define CLSIZELOG2 0
|
||||
|
||||
/* NOTE: SSIZE, SINCR and UPAGES must be multiples of CLSIZE */
|
||||
/*
|
||||
* NOTE: SSIZE, SINCR and UPAGES must be multiples of CLSIZE.
|
||||
* UPAGES, UADDR, USPACE defined in mips_param.h.
|
||||
*/
|
||||
#define SSIZE 1 /* initial stack size/NBPG */
|
||||
#define SINCR 1 /* increment of stack/NBPG */
|
||||
|
||||
#define UPAGES 2 /* pages of u-area */
|
||||
#define UADDR 0xffffc000 /* address of u */
|
||||
#define USPACE (UPAGES*NBPG) /* size of u-area in bytes */
|
||||
#define UVPN (UADDR>>PGSHIFT)/* virtual page number of u */
|
||||
#define KERNELSTACK (UADDR+UPAGES*NBPG) /* top of kernel stack */
|
||||
|
||||
/*
|
||||
* Constants related to network buffer management.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.90 1997/07/01 09:32:23 jonathan Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.91 1997/07/07 03:54:27 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -116,6 +116,10 @@
|
|||
#include "asc.h"
|
||||
|
||||
|
||||
extern struct consdev *cn_tab; /* Console I/O table... */
|
||||
extern struct consdev cd;
|
||||
|
||||
|
||||
#if defined(DS5000_25) || defined(DS5000_100) || defined(DS5000_240)
|
||||
/* Will scan from max to min, inclusive */
|
||||
static int tc_max_slot = KN02_TC_MAX;
|
||||
|
@ -311,6 +315,9 @@ mach_init(argc, argv, code, cv)
|
|||
callv = &callvec;
|
||||
}
|
||||
|
||||
/* Use PROM console output until we initialize a console driver. */
|
||||
cn_tab = &cd;
|
||||
|
||||
/* check for direct boot from DS5000 PROM */
|
||||
if (argc > 0 && strcmp(argv[0], "boot") == 0) {
|
||||
argc--;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: scc.c,v 1.25 1997/06/22 07:42:44 jonathan Exp $ */
|
||||
/* $NetBSD: scc.c,v 1.26 1997/07/07 03:54:40 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
|
||||
|
@ -1210,13 +1210,14 @@ sccintr(xxxsc)
|
|||
*/
|
||||
if (tp == scctty(makedev(SCCDEV, SCCKBD_PORT)) &&
|
||||
raster_console()) {
|
||||
#ifdef KADB
|
||||
#ifdef DDB
|
||||
if (cc == LK_DO) {
|
||||
spl0();
|
||||
kdbpanic();
|
||||
Debugger();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
debugChar = cc;
|
||||
#endif
|
||||
|
@ -1447,27 +1448,44 @@ scc_modem_intr(dev)
|
|||
if (chan == SCC_CHANNEL_A)
|
||||
return;
|
||||
s = spltty();
|
||||
|
||||
SCC_READ_REG_ZERO(regs, chan, value);
|
||||
if (sc->scc_softCAR & (1 << chan))
|
||||
car = 1;
|
||||
else {
|
||||
SCC_READ_REG_ZERO(regs, chan, value);
|
||||
car = value & ZSRR0_DCD;
|
||||
}
|
||||
|
||||
|
||||
/* Break on serial console drops into the dbeugger */
|
||||
if ((value & ZSRR0_BREAK) && CONSOLE_ON_UNIT(sc->sc_dv.dv_unit)) {
|
||||
#ifdef DDB
|
||||
splx(s); /* spl0()? */
|
||||
Debugger();
|
||||
return;
|
||||
#else
|
||||
/* XXX maybe fall back to PROM? */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* The pmax driver follows carrier-detect. The Alpha does not.
|
||||
* XXX Why doesn't the Alpha driver follow carrier-detect?
|
||||
* (in the Alpha driver, this is an "#ifdef notdef").
|
||||
* Is it related to console handling?
|
||||
*
|
||||
* Ignore hups on a console tty.
|
||||
*/
|
||||
#ifndef alpha
|
||||
if (!CONSOLE_ON_UNIT(sc->sc_dv.dv_unit)) {
|
||||
if (car) {
|
||||
/* carrier present */
|
||||
if (!(tp->t_state & TS_CARR_ON))
|
||||
(void)(*linesw[tp->t_line].l_modem)(tp, 1);
|
||||
} else if (tp->t_state & TS_CARR_ON)
|
||||
(void)(*linesw[tp->t_line].l_modem)(tp, 0);
|
||||
#endif /* !alpha */
|
||||
}
|
||||
#endif
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue