diff options
author | Per Fogelstrom <pefo@cvs.openbsd.org> | 1998-03-16 09:03:39 +0000 |
---|---|---|
committer | Per Fogelstrom <pefo@cvs.openbsd.org> | 1998-03-16 09:03:39 +0000 |
commit | 3460a445e62bf6559a4ca00aab3e2959959b5c58 (patch) | |
tree | c9e0ef5165b9e3c93db4a89710e98aa1c6edf834 /sys/arch/mips | |
parent | cd264da84d16c2ce76eb7476eb671189597eb5cc (diff) |
DDB for mips, first cut. Will add some machine dep commands and tune
up a little. Basically works. Still needs symbol table support.
Load store counting does not handle branch likely situations.
Also, some code moved into here as 'machine independent'.
Diffstat (limited to 'sys/arch/mips')
-rw-r--r-- | sys/arch/mips/conf/files.mips | 6 | ||||
-rw-r--r-- | sys/arch/mips/include/archtype.h | 24 | ||||
-rw-r--r-- | sys/arch/mips/include/asm.h | 5 | ||||
-rw-r--r-- | sys/arch/mips/include/cpu.h | 11 | ||||
-rw-r--r-- | sys/arch/mips/include/db_machdep.h | 80 | ||||
-rw-r--r-- | sys/arch/mips/include/frame.h | 41 | ||||
-rw-r--r-- | sys/arch/mips/include/regdef.h | 6 | ||||
-rw-r--r-- | sys/arch/mips/include/regnum.h | 11 | ||||
-rw-r--r-- | sys/arch/mips/include/varargs.h | 20 | ||||
-rw-r--r-- | sys/arch/mips/mips/arcbios.c | 5 | ||||
-rw-r--r-- | sys/arch/mips/mips/clock.c | 8 | ||||
-rw-r--r-- | sys/arch/mips/mips/cpu.c | 10 | ||||
-rw-r--r-- | sys/arch/mips/mips/db_disasm.c | 406 | ||||
-rw-r--r-- | sys/arch/mips/mips/db_machdep.c | 302 | ||||
-rw-r--r-- | sys/arch/mips/mips/disksubr.c | 12 | ||||
-rw-r--r-- | sys/arch/mips/mips/fp.S | 5 | ||||
-rw-r--r-- | sys/arch/mips/mips/mainbus.c | 11 | ||||
-rw-r--r-- | sys/arch/mips/mips/minidebug.c | 22 | ||||
-rw-r--r-- | sys/arch/mips/mips/vm_machdep.c | 517 |
19 files changed, 1437 insertions, 65 deletions
diff --git a/sys/arch/mips/conf/files.mips b/sys/arch/mips/conf/files.mips index e69e260aebb..2e30373c505 100644 --- a/sys/arch/mips/conf/files.mips +++ b/sys/arch/mips/conf/files.mips @@ -1,9 +1,11 @@ -# $OpenBSD: files.mips,v 1.1 1998/01/29 15:08:23 pefo Exp $ +# $OpenBSD: files.mips,v 1.2 1998/03/16 09:02:53 pefo Exp $ file arch/mips/mips/clock.c file arch/mips/mips/cpu_ecoff.c file arch/mips/mips/disksubr.c file arch/mips/mips/mem.c -file arch/mips/mips/minidebug.c file arch/mips/mips/process_machdep.c file arch/mips/mips/sys_machdep.c +file arch/mips/mips/vm_machdep.c +file arch/mips/mips/db_disasm.c ddb +file arch/mips/mips/db_machdep.c ddb diff --git a/sys/arch/mips/include/archtype.h b/sys/arch/mips/include/archtype.h index 5ae11975ff8..ae1cbc3eca4 100644 --- a/sys/arch/mips/include/archtype.h +++ b/sys/arch/mips/include/archtype.h @@ -1,4 +1,4 @@ -/* $OpenBSD: archtype.h,v 1.1 1998/01/28 11:14:36 pefo Exp $ */ +/* $OpenBSD: archtype.h,v 1.2 1998/03/16 09:02:59 pefo Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom * @@ -36,15 +36,21 @@ /* * Define architectural identitys for the different Mips machines. */ -#define ACER_PICA_61 0x1 /* Acer Labs Pica 61 */ -#define MAGNUM 0x2 /* Mips MAGNUM R4000 */ -#define DESKSTATION_RPC44 0x3 /* Deskstation xxx */ -#define DESKSTATION_TYNE 0x4 /* Deskstation xxx */ -#define NKK_AQUARIUS 0x5 /* NKK R4{67}00 PC */ -#define ALGOR_P4032 0x6 /* ALGORITHMICS P-4032 VR4300 */ -#define SNI_RM200 0x7 /* Siemens Nixdorf RM200 */ +#define ARC_CLASS 0x00 /* Arch class ARC */ +#define ACER_PICA_61 0x01 /* Acer Labs Pica 61 */ +#define MAGNUM 0x02 /* Mips MAGNUM R4000 */ +#define DESKSTATION_RPC44 0x03 /* Deskstation xxx */ +#define DESKSTATION_TYNE 0x04 /* Deskstation xxx */ +#define NKK_AQUARIUS 0x05 /* NKK R4{67}00 PC */ +#define NEC_R94 0x06 /* NEC Magnum class */ +#define SNI_RM200 0x07 /* Siemens Nixdorf RM200 */ -#define SGI_INDY 0x10 /* Silicon Graphics Indy */ +#define SGI_CLASS 0x10 /* Silicon Graphics Class */ +#define SGI_INDY 0x11 /* Silicon Graphics Indy */ + +#define ALGOR_CLASS 0x20 /* Algorithmics Class */ +#define ALGOR_P4032 0x21 /* ALGORITHMICS P-4032 */ +#define ALGOR_P5064 0x22 /* ALGORITHMICS P-5064 */ extern int system_type; /* Global system type indicator */ diff --git a/sys/arch/mips/include/asm.h b/sys/arch/mips/include/asm.h index d34fdb32dce..9fc9c7821e2 100644 --- a/sys/arch/mips/include/asm.h +++ b/sys/arch/mips/include/asm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asm.h,v 1.1 1998/01/28 11:14:37 pefo Exp $ */ +/* $OpenBSD: asm.h,v 1.2 1998/03/16 09:03:02 pefo Exp $ */ /* * Copyright (c) 1992, 1993 @@ -178,9 +178,6 @@ x: ; \ #define END(x) \ .end x -#define STAND_FRAME_SIZE 24 -#define STAND_RA_OFFSET 20 - /* * Macros to panic and printf from assembly language. */ diff --git a/sys/arch/mips/include/cpu.h b/sys/arch/mips/include/cpu.h index 7429f92c1f1..df86d6aaca0 100644 --- a/sys/arch/mips/include/cpu.h +++ b/sys/arch/mips/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.1 1998/01/28 11:14:38 pefo Exp $ */ +/* $OpenBSD: cpu.h,v 1.2 1998/03/16 09:03:04 pefo Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -176,10 +176,12 @@ #define BREAK_SSTEP_VAL 513 #define BREAK_BRKPT_VAL 514 #define BREAK_SOVER_VAL 515 +#define BREAK_DDB_VAL 516 #define BREAK_KDB (BREAK_INSTR | (BREAK_KDB_VAL << BREAK_VAL_SHIFT)) #define BREAK_SSTEP (BREAK_INSTR | (BREAK_SSTEP_VAL << BREAK_VAL_SHIFT)) #define BREAK_BRKPT (BREAK_INSTR | (BREAK_BRKPT_VAL << BREAK_VAL_SHIFT)) #define BREAK_SOVER (BREAK_INSTR | (BREAK_SOVER_VAL << BREAK_VAL_SHIFT)) +#define BREAK_DDB (BREAK_INSTR | (BREAK_DDB_VAL << BREAK_VAL_SHIFT)) /* * Mininum and maximum cache sizes. @@ -375,7 +377,7 @@ union cpuprid { #define MIPS_R4700 0x21 /* QED R4700 Orion ISA III */ #define MIPS_R3TOSH 0x22 /* Toshiba R3000 based CPU ISA I */ #define MIPS_R5000 0x23 /* MIPS R5000 based CPU ISA IV */ -#define MIPS_RM5230 0x28 /* QED RM5230 based CPU ISA IV */ +#define MIPS_RM52X0 0x28 /* QED RM52X0 based CPU ISA IV */ /* * MIPS FPU types @@ -395,7 +397,7 @@ union cpuprid { #define MIPS_R3SONY 0x21 /* Sony R3000 based FPU ISA I */ #define MIPS_R3TOSH 0x22 /* Toshiba R3000 based FPU ISA I */ #define MIPS_R5010 0x23 /* MIPS R5000 based FPU ISA IV */ -#define MIPS_RM5230 0x28 /* QED RM5230 based FPU ISA IV */ +#define MIPS_RM5230 0x28 /* QED RM52X0 based FPU ISA IV */ #if defined(_KERNEL) && !defined(_LOCORE) union cpuprid cpu_id; @@ -431,9 +433,6 @@ void savectx __P((struct user *, int)); int copykstack __P((struct user *)); void switch_exit __P((void)); void MipsSaveCurFPState __P((struct proc *)); -#ifdef DEBUG -void mdbpanic __P((void)); -#endif extern u_int32_t cpu_counter_interval; /* Number of counter ticks/tick */ extern u_int32_t cpu_counter_last; /* Last compare value loaded */ diff --git a/sys/arch/mips/include/db_machdep.h b/sys/arch/mips/include/db_machdep.h new file mode 100644 index 00000000000..3f01969b422 --- /dev/null +++ b/sys/arch/mips/include/db_machdep.h @@ -0,0 +1,80 @@ +/* $OpenBSD: db_machdep.h,v 1.1 1998/03/16 09:03:05 pefo Exp $ */ + +/* + * Copyright (c) 1998 Per Fogelstrom, Opsycon AB + * + * 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 under OpenBSD by + * Per Fogelstrom, Opsycon AB, Sweden. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + */ + +#ifndef _MACHINE_DB_MACHDEP_H_ +#define _MACHINE_DB_MACHDEP_H_ + +#include <machine/regnum.h> +#include <machine/frame.h> +#include <machine/trap.h> +#include <vm/vm_param.h> + +#define MID_MACHINE 0 /* XXX booo... */ + +typedef struct trap_frame db_regs_t; +db_regs_t ddb_regs; + +typedef int db_expr_t; +typedef vm_offset_t db_addr_t; + +#define SOFTWARE_SSTEP /* Need software single step */ +#define SOFTWARE_SSTEP_EMUL /* next_instr_address() emulates 100% */ +db_addr_t next_instr_address __P((db_addr_t, boolean_t)); +#define BKPT_SIZE (4) +#define BKPT_SET(ins) (BREAK_DDB) +#define DB_VALID_BREAKPOINT(addr) (((addr) & 3) == 0) + +#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BREAK) +#define IS_WATCHPOINT_TRAP(type, code) (0) /* XXX mips3 watchpoint */ + +#define PC_REGS(regs) ((db_addr_t)(regs)->reg[PC]) +#define DDB_REGS (&ddb_regs) + +/* + * Test of instructions to see class. + */ +#define IT_CALL 0x01 +#define IT_BRANCH 0x02 +#define IT_LOAD 0x03 +#define IT_STORE 0x04 + +#define inst_branch(i) (db_inst_type(i) == IT_BRANCH) +#define inst_trap_return(i) ((i) & 0) +#define inst_call(i) (db_inst_type(i) == IT_CALL) +#define inst_return(i) ((i) == 0x03e00008) +#define inst_load(i) (db_inst_type(i) == IT_LOAD) +#define inst_store(i) (db_inst_type(i) == IT_STORE) + +int db_inst_type __P((int)); +#endif /* _MACHINE_DB_MACHDEP_H_ */ diff --git a/sys/arch/mips/include/frame.h b/sys/arch/mips/include/frame.h index e69de29bb2d..c67c8ee481b 100644 --- a/sys/arch/mips/include/frame.h +++ b/sys/arch/mips/include/frame.h @@ -0,0 +1,41 @@ +/* $OpenBSD: frame.h,v 1.2 1998/03/16 09:03:06 pefo Exp $ */ + +/* + * Copyright (c) 1998 Per Fogelstrom, Opsycon AB + * + * 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 under OpenBSD by + * Per Fogelstrom, Opsycon AB, Sweden. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + */ +#ifndef _MACHINE_FRAME_H_ +#define _MACHINE_FRAME_H_ + +struct trap_frame { + int reg[NUMSAVEREGS]; +}; + +#endif /*_MACHINE_FRAME_H_*/ diff --git a/sys/arch/mips/include/regdef.h b/sys/arch/mips/include/regdef.h index 3461aa7057b..2b2879326e5 100644 --- a/sys/arch/mips/include/regdef.h +++ b/sys/arch/mips/include/regdef.h @@ -1,4 +1,4 @@ -/* $OpenBSD: regdef.h,v 1.1 1998/01/28 11:14:54 pefo Exp $ */ +/* $OpenBSD: regdef.h,v 1.2 1998/03/16 09:03:08 pefo Exp $ */ /* * Copyright (c) 1992, 1993 @@ -38,6 +38,8 @@ * * @(#)regdef.h 8.1 (Berkeley) 6/10/93 */ +#ifndef _MACHINE_REGDEF_H_ +#define _MACHINE_REGDEF_H_ #define zero $0 /* always zero */ #define AT $at /* assembler temp */ @@ -71,3 +73,5 @@ #define sp $29 /* stack pointer */ #define s8 $30 /* one more callee saved */ #define ra $31 /* return address */ + +#endif /* _MACHINE_REGDEF_H_ */ diff --git a/sys/arch/mips/include/regnum.h b/sys/arch/mips/include/regnum.h index 32255d07a76..0766179d722 100644 --- a/sys/arch/mips/include/regnum.h +++ b/sys/arch/mips/include/regnum.h @@ -1,4 +1,4 @@ -/* $OpenBSD: regnum.h,v 1.1 1998/01/28 11:14:54 pefo Exp $ */ +/* $OpenBSD: regnum.h,v 1.2 1998/03/16 09:03:14 pefo Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -41,9 +41,12 @@ * @(#)reg.h 8.2 (Berkeley) 1/11/94 */ +#define STAND_ARG_SIZE 16 +#define STAND_FRAME_SIZE 24 +#define STAND_RA_OFFSET 20 + /* - * Location of the users' stored - * registers relative to ZERO. + * Location of the saved registers relative to ZERO. * Usage is p->p_regs[XX]. */ #define ZERO 0 @@ -86,6 +89,8 @@ #define CAUSE 36 #define PC 37 +#define NUMSAVEREGS 38 /* Number of registers saved in trap */ + #define FPBASE 38 #define F0 (FPBASE+0) #define F1 (FPBASE+1) diff --git a/sys/arch/mips/include/varargs.h b/sys/arch/mips/include/varargs.h index 4101abb3c85..dd5cda76d68 100644 --- a/sys/arch/mips/include/varargs.h +++ b/sys/arch/mips/include/varargs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: varargs.h,v 1.1 1998/01/28 11:14:59 pefo Exp $ */ +/* $OpenBSD: varargs.h,v 1.2 1998/03/16 09:03:16 pefo Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -43,26 +43,12 @@ #ifndef _MACHINE_VARARGS_H_ #define _MACHINE_VARARGS_H_ -#include <machine/ansi.h> - -typedef _BSD_VA_LIST_ va_list; +#include <machine/stdarg.h> #define va_dcl int va_alist; ... +#undef va_start #define va_start(ap) \ ap = (char *)&va_alist -#ifdef _KERNEL -#define va_arg(ap, type) \ - ((type *)(ap += sizeof(type)))[-1] -#else -#define va_arg(ap, type) \ - ((type *)(ap += sizeof(type) == sizeof(int) ? sizeof(type) : \ - sizeof(type) > sizeof(int) ? \ - (-(int)(ap) & (sizeof(type) - 1)) + sizeof(type) : \ - (abort(), 0)))[-1] -#endif - -#define va_end(ap) ((void) 0) - #endif /* !_MACHINE_VARARGS_H_ */ diff --git a/sys/arch/mips/mips/arcbios.c b/sys/arch/mips/mips/arcbios.c index a359dd73dad..d99e375163d 100644 --- a/sys/arch/mips/mips/arcbios.c +++ b/sys/arch/mips/mips/arcbios.c @@ -1,7 +1,7 @@ -/* $OpenBSD: arcbios.c,v 1.1 1998/01/28 12:12:06 pefo Exp $ */ +/* $OpenBSD: arcbios.c,v 1.2 1998/03/16 09:03:19 pefo Exp $ */ /*- * Copyright (c) 1996 M. Warner Losh. All rights reserved. - * Copyright (c) 1996 Per Fogelstrom. All rights reserved. + * Copyright (c) 1996, 1997, 1998 Per Fogelstrom. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,6 +66,7 @@ static struct systypes { int sys_type; } sys_types[] = { { NULL, "PICA-61", ACER_PICA_61 }, + { NULL, "NEC-R94", ACER_PICA_61 }, { NULL, "DESKTECH-TYNE", DESKSTATION_TYNE }, { NULL, "DESKTECH-ARCStation I", DESKSTATION_RPC44 }, { NULL, "Microsoft-Jazz", MAGNUM }, diff --git a/sys/arch/mips/mips/clock.c b/sys/arch/mips/mips/clock.c index ced12c6498f..5433bc80da4 100644 --- a/sys/arch/mips/mips/clock.c +++ b/sys/arch/mips/mips/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.2 1998/01/29 14:55:54 pefo Exp $ */ +/* $OpenBSD: clock.c,v 1.3 1998/03/16 09:03:21 pefo Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom. * Copyright (c) 1988 University of Utah. @@ -40,7 +40,7 @@ * from: Utah Hdr: clock.c 1.18 91/01/21 * * from: @(#)clock.c 8.1 (Berkeley) 6/10/93 - * $Id: clock.c,v 1.2 1998/01/29 14:55:54 pefo Exp $ + * $Id: clock.c,v 1.3 1998/03/16 09:03:21 pefo Exp $ */ #include <sys/param.h> @@ -117,6 +117,7 @@ clockmatch(parent, cfdata, aux) #ifdef arc case ACER_PICA_61: + case MAGNUM: /* make sure that we're looking for this type of device. */ if (!BUS_MATCHNAME(ca, "dallas_rtc")) return (0); @@ -126,6 +127,7 @@ clockmatch(parent, cfdata, aux) case DESKSTATION_RPC44: case DESKSTATION_TYNE: case ALGOR_P4032: + case ALGOR_P5064: break; #endif @@ -159,7 +161,9 @@ clockattach(parent, self, aux) #ifdef arc case ACER_PICA_61: + case MAGNUM: case ALGOR_P4032: + case ALGOR_P5064: BUS_INTR_ESTABLISH((struct confargs *)aux, (intr_handler_t)hardclock, self); set_intr(SOFT_INT_MASK_0 << 7, int5_dummy, 1); diff --git a/sys/arch/mips/mips/cpu.c b/sys/arch/mips/mips/cpu.c index 60453e6dcd0..1fd8b1a08d7 100644 --- a/sys/arch/mips/mips/cpu.c +++ b/sys/arch/mips/mips/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.1 1998/01/28 12:12:07 pefo Exp $ */ +/* $OpenBSD: cpu.c,v 1.2 1998/03/16 09:03:23 pefo Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom @@ -125,8 +125,8 @@ cpuattach(parent, dev, aux) case MIPS_R3TOSH: printf("Toshiba R3000 based CPU"); break; - case MIPS_RM5230: - printf("QED RM5230 based CPU"); + case MIPS_RM52X0: + printf("QED RM52X0 CPU"); break; case MIPS_UNKC2: default: @@ -180,8 +180,8 @@ cpuattach(parent, dev, aux) case MIPS_R5000: printf("MIPS R5000 based FPC"); break; - case MIPS_RM5230: - printf("QED RM5230 based FPC"); + case MIPS_RM52X0: + printf("QED RM52X0 FPC"); break; case MIPS_UNKF1: default: diff --git a/sys/arch/mips/mips/db_disasm.c b/sys/arch/mips/mips/db_disasm.c new file mode 100644 index 00000000000..583d13abe82 --- /dev/null +++ b/sys/arch/mips/mips/db_disasm.c @@ -0,0 +1,406 @@ +/* $OpenBSD: db_disasm.c,v 1.1 1998/03/16 09:03:24 pefo 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 + * $Id: db_disasm.c,v 1.1 1998/03/16 09:03:24 pefo Exp $ + */ + +#include <sys/param.h> +#include <vm/vm_param.h> +#include <sys/systm.h> + +#include <machine/mips_opcode.h> +#include <machine/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" +}; + +static int md_printins __P((int ins, int mdbdot)); + +db_addr_t +db_disasm(loc, altfmt) + db_addr_t loc; + boolean_t altfmt; + +{ + return (md_printins(*(int*)loc, loc)); +} + +/* ARGSUSED */ +static int +md_printins(int ins, int mdbdot) +{ + InstFmt i; + int delay = 0; + + i.word = ins; + + 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: + delay = 1; + /* 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: + delay = 1; + db_printf("0x%08x", mdbdot + 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%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2)); + delay = 1; + 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(delay); +} diff --git a/sys/arch/mips/mips/db_machdep.c b/sys/arch/mips/mips/db_machdep.c new file mode 100644 index 00000000000..7a23f88c981 --- /dev/null +++ b/sys/arch/mips/mips/db_machdep.c @@ -0,0 +1,302 @@ +/* $OpenBSD: db_machdep.c,v 1.1 1998/03/16 09:03:25 pefo Exp $ */ + +/* + * Copyright (c) 1998 Per Fogelstrom, Opsycon AB + * + * 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 under OpenBSD by + * Per Fogelstrom, Opsycon AB, Sweden. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <dev/cons.h> + +#include <mips/db_machdep.h> +#include <machine/mips_opcode.h> + +#include <ddb/db_sym.h> +#include <ddb/db_extern.h> +#include <ddb/db_access.h> +#include <ddb/db_output.h> +#include <ddb/db_variables.h> +#include <ddb/db_interface.h> + +u_int MipsEmulateBranch __P((int *, int, int, u_int)); +void stacktrace_subr __P((int *, int (*)(const char*, ...))); + +int kdbpeek __P((int)); +void kdbpoke __P((int, int)); +int kdb_trap __P((int, struct trap_frame *)); + +int db_active = 0; +db_regs_t ddb_regs; + +struct db_variable db_regs[] = { + { "at", (long *)&ddb_regs.reg[AST], FCN_NULL }, + { "v0", (long *)&ddb_regs.reg[V0], FCN_NULL }, + { "v1", (long *)&ddb_regs.reg[V1], FCN_NULL }, + { "a0", (long *)&ddb_regs.reg[A0], FCN_NULL }, + { "a1", (long *)&ddb_regs.reg[A1], FCN_NULL }, + { "a2", (long *)&ddb_regs.reg[A2], FCN_NULL }, + { "a3", (long *)&ddb_regs.reg[A3], FCN_NULL }, + { "t0", (long *)&ddb_regs.reg[T0], FCN_NULL }, + { "t1", (long *)&ddb_regs.reg[T1], FCN_NULL }, + { "t2", (long *)&ddb_regs.reg[T2], FCN_NULL }, + { "t3", (long *)&ddb_regs.reg[T3], FCN_NULL }, + { "t4", (long *)&ddb_regs.reg[T4], FCN_NULL }, + { "t5", (long *)&ddb_regs.reg[T5], FCN_NULL }, + { "t6", (long *)&ddb_regs.reg[T6], FCN_NULL }, + { "t7", (long *)&ddb_regs.reg[T7], FCN_NULL }, + { "s0", (long *)&ddb_regs.reg[S0], FCN_NULL }, + { "s1", (long *)&ddb_regs.reg[S1], FCN_NULL }, + { "s2", (long *)&ddb_regs.reg[S2], FCN_NULL }, + { "s3", (long *)&ddb_regs.reg[S3], FCN_NULL }, + { "s4", (long *)&ddb_regs.reg[S4], FCN_NULL }, + { "s5", (long *)&ddb_regs.reg[S5], FCN_NULL }, + { "s6", (long *)&ddb_regs.reg[S6], FCN_NULL }, + { "s7", (long *)&ddb_regs.reg[S7], FCN_NULL }, + { "t8", (long *)&ddb_regs.reg[T8], FCN_NULL }, + { "t9", (long *)&ddb_regs.reg[T9], FCN_NULL }, + { "k0", (long *)&ddb_regs.reg[K0], FCN_NULL }, + { "k1", (long *)&ddb_regs.reg[K1], FCN_NULL }, + { "gp", (long *)&ddb_regs.reg[GP], FCN_NULL }, + { "sp", (long *)&ddb_regs.reg[SP], FCN_NULL }, + { "s8", (long *)&ddb_regs.reg[S8], FCN_NULL }, + { "ra", (long *)&ddb_regs.reg[RA], FCN_NULL }, + { "sr", (long *)&ddb_regs.reg[SR], FCN_NULL }, + { "lo", (long *)&ddb_regs.reg[MULLO], FCN_NULL }, + { "hi", (long *)&ddb_regs.reg[MULHI], FCN_NULL }, + { "bad", (long *)&ddb_regs.reg[BADVADDR],FCN_NULL }, + { "cs", (long *)&ddb_regs.reg[CAUSE], FCN_NULL }, + { "pc", (long *)&ddb_regs.reg[PC], FCN_NULL }, +}; +struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); + + +int +kdb_trap(type, t_frame) + int type; + struct trap_frame *t_frame; +{ + switch(type) { + case T_BREAK: /* breakpoint */ + if(db_get_value((t_frame)->reg[PC], sizeof(int), FALSE) == BREAK_SOVER) { + (t_frame)->reg[PC] += BKPT_SIZE; + } + break; + case -1: + break; + default: +#if notyet + if(db_recover != 0) { + db_error("Caught exception in ddb.\n"); + /*NOTREACHED*/ + } + return(FALSE); /* NOT handled */ +#endif + } + + ddb_regs = *t_frame; + + db_active++; + cnpollc(TRUE); + db_trap(type, 0); + cnpollc(FALSE); + db_active--; + + *t_frame = ddb_regs; + return(TRUE); +} +void +db_read_bytes(addr, size, data) + vm_offset_t addr; + size_t size; + char *data; +{ + while(size >= sizeof(int)) { + *((int *)data)++ = kdbpeek(addr); + addr += sizeof(int); + size -= sizeof(int); + } + + if(size) { + int res; + char *p = (char *)&res; + res = kdbpeek(addr); + while(size--) { + *data++ = *p++; + } + } +} + +void +db_write_bytes(addr, size, data) + vm_offset_t addr; + size_t size; + char *data; +{ + vm_offset_t ptr = addr; + size_t len = size; + + while(len >= sizeof(int)) { + kdbpoke(ptr, *((int *)data)++); + ptr += sizeof(int); + len -= sizeof(int); + } + + if(len) { + int res; + char *p = (char *)&res; + res = kdbpeek(ptr); + while(len--) { + *data++ = *p++; + } + kdbpoke(ptr, res); + } + if(addr < VM_MIN_KERNEL_ADDRESS) { + R4K_HitFlushDCache(addr, size); + R4K_FlushICache(PHYS_TO_CACHED(addr & 0xffff), size); + } +} + +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.reg, db_printf); +} + +/* + * To do a single step ddb needs to know the next address + * that we will get to. It means that we need to find out + * both the address for a branch taken and for not taken, NOT! :-) + * MipsEmulateBranch will do the job to find out _exactly_ which + * address we will end up at so the 'dual bp' method is not + * requiered. + */ +db_addr_t +next_instr_address(db_addr_t pc, boolean_t bd) +{ + db_addr_t next; + + next = (db_addr_t)MipsEmulateBranch(ddb_regs.reg, pc, 0, 0); + return(next); +} + + +/* + * Decode instruction and figure out type. + */ +int +db_inst_type(ins) + int ins; +{ + InstFmt inst; + int ityp = 0; + + inst.word = ins; + switch ((int)inst.JType.op) { + case OP_SPECIAL: + switch ((int)inst.RType.func) { + case OP_JR: + ityp = IT_BRANCH; + break; + case OP_JALR: + case OP_SYSCALL: + ityp = IT_CALL; + break; + } + break; + + case OP_BCOND: + switch ((int)inst.IType.rt) { + case OP_BLTZ: + case OP_BLTZL: + case OP_BGEZ: + case OP_BGEZL: + ityp = IT_BRANCH; + break; + + case OP_BLTZAL: + case OP_BLTZALL: + case OP_BGEZAL: + case OP_BGEZALL: + ityp = IT_CALL; + break; + } + break; + + case OP_JAL: + ityp = IT_CALL; + break; + + case OP_J: + case OP_BEQ: + case OP_BEQL: + case OP_BNE: + case OP_BNEL: + case OP_BLEZ: + case OP_BLEZL: + case OP_BGTZ: + case OP_BGTZL: + ityp = IT_BRANCH; + break; + + case OP_COP1: + switch (inst.RType.rs) { + case OP_BCx: + case OP_BCy: + ityp = IT_BRANCH; + break; + } + break; + + case OP_LB: + case OP_LH: + case OP_LW: + case OP_LD: + case OP_LBU: + case OP_LHU: + case OP_LWU: + case OP_LWC1: + ityp = IT_LOAD; + break; + + case OP_SB: + case OP_SH: + case OP_SW: + case OP_SD: + case OP_SWC1: + ityp = IT_STORE; + break; + } + return (ityp); +} diff --git a/sys/arch/mips/mips/disksubr.c b/sys/arch/mips/mips/disksubr.c index 8ee71293e04..45d27a1fe34 100644 --- a/sys/arch/mips/mips/disksubr.c +++ b/sys/arch/mips/mips/disksubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disksubr.c,v 1.4 1998/02/24 04:22:42 deraadt Exp $ */ +/* $OpenBSD: disksubr.c,v 1.5 1998/03/16 09:03:29 pefo Exp $ */ /* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */ /* @@ -80,7 +80,7 @@ char * readdisklabel(dev, strat, lp, osdep) dev_t dev; void (*strat) __P((struct buf *)); - register struct disklabel *lp; + struct disklabel *lp; struct cpu_disklabel *osdep; { struct dos_partition *dp = osdep->dosparts, *dp2; @@ -328,12 +328,12 @@ done: */ int setdisklabel(olp, nlp, openmask, osdep) - register struct disklabel *olp, *nlp; + struct disklabel *olp, *nlp; u_long openmask; struct cpu_disklabel *osdep; { - register i; - register struct partition *opp, *npp; + int i; + struct partition *opp, *npp; /* sanity clause */ if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 || @@ -387,7 +387,7 @@ int writedisklabel(dev, strat, lp, osdep) dev_t dev; void (*strat) __P((struct buf *)); - register struct disklabel *lp; + struct disklabel *lp; struct cpu_disklabel *osdep; { struct dos_partition *dp = osdep->dosparts, *dp2; diff --git a/sys/arch/mips/mips/fp.S b/sys/arch/mips/mips/fp.S index fa2fdc2b351..e258fbf9d12 100644 --- a/sys/arch/mips/mips/fp.S +++ b/sys/arch/mips/mips/fp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fp.S,v 1.1 1998/01/29 15:06:23 pefo Exp $ */ +/* $OpenBSD: fp.S,v 1.2 1998/03/16 09:03:31 pefo Exp $ */ /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)fp.s 8.1 (Berkeley) 6/10/93 - * $Id: fp.S,v 1.1 1998/01/29 15:06:23 pefo Exp $ + * $Id: fp.S,v 1.2 1998/03/16 09:03:31 pefo Exp $ */ /* @@ -44,6 +44,7 @@ #include <machine/regdef.h> #include <machine/asm.h> +#include <machine/regnum.h> #include <machine/cpu.h> #include "assym.h" diff --git a/sys/arch/mips/mips/mainbus.c b/sys/arch/mips/mips/mainbus.c index d809493f8b2..3ae2c4927bb 100644 --- a/sys/arch/mips/mips/mainbus.c +++ b/sys/arch/mips/mips/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.1 1998/01/28 12:12:08 pefo Exp $ */ +/* $OpenBSD: mainbus.c,v 1.2 1998/03/16 09:03:34 pefo Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom. @@ -101,14 +101,16 @@ mbattach(parent, self, aux) config_found(self, &nca, mbprint); #ifdef arc - if (system_type == ACER_PICA_61) { + if (system_type == ACER_PICA_61 || + system_type == MAGNUM) { nca.ca_name = "pica"; nca.ca_slot = 0; nca.ca_offset = 0; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } - if (system_type == ALGOR_P4032) { + if (system_type == ALGOR_P4032 || + system_type == ALGOR_P5064) { nca.ca_name = "algor"; nca.ca_slot = 0; nca.ca_offset = 0; @@ -117,7 +119,8 @@ mbattach(parent, self, aux) } /* The following machines have a PCI bus */ - if (system_type == ALGOR_P4032) { + if (system_type == ALGOR_P4032 || + system_type == ALGOR_P5064) { nca.ca_name = "pbcpcibr"; nca.ca_slot = 0; nca.ca_offset = 0; diff --git a/sys/arch/mips/mips/minidebug.c b/sys/arch/mips/mips/minidebug.c index 598dd26f5ac..cb162bf2b06 100644 --- a/sys/arch/mips/mips/minidebug.c +++ b/sys/arch/mips/mips/minidebug.c @@ -1,4 +1,4 @@ -/* $OpenBSD: minidebug.c,v 1.1 1998/01/28 12:12:09 pefo Exp $ */ +/* $OpenBSD: minidebug.c,v 1.2 1998/03/16 09:03:36 pefo Exp $ */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)kadb.c 8.1 (Berkeley) 6/10/93 - * $Id: minidebug.c,v 1.1 1998/01/28 12:12:09 pefo Exp $ + * $Id: minidebug.c,v 1.2 1998/03/16 09:03:36 pefo Exp $ */ /* @@ -138,6 +138,7 @@ static char *c0_reg[32] = { extern u_int mdbpeek __P((int)); extern void mdbpoke __P((int, int)); +extern void cpu_setwatch __P((int, int)); extern void trapDump __P((char *)); extern void stacktrace __P((void)); extern u_int MipsEmulateBranch __P((int *, int, int, u_int)); @@ -568,6 +569,23 @@ static int ssandrun; /* Single step and run flag (when cont at brk) */ } break; + case 'w': + printf("watch "); + c = gethex(&newaddr, newaddr); + size = 3; + if(c == ',') { + c = cngetc(); + cnputc(c); + if(c == 'r') + size = 2; + else if(c == 'w') + size = 1; + else + size = 0; + } + cpu_setwatch(0, (newaddr & ~7) | size); + break; + default: cnputc('\a'); break; diff --git a/sys/arch/mips/mips/vm_machdep.c b/sys/arch/mips/mips/vm_machdep.c new file mode 100644 index 00000000000..ee9be03fa2e --- /dev/null +++ b/sys/arch/mips/mips/vm_machdep.c @@ -0,0 +1,517 @@ +/* $OpenBSD: vm_machdep.c,v 1.1 1998/03/16 09:03:38 pefo Exp $ */ +/* + * Copyright (c) 1988 University of Utah. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department and 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: Utah Hdr: vm_machdep.c 1.21 91/04/06 + * + * from: @(#)vm_machdep.c 8.3 (Berkeley) 1/4/94 + * $Id: vm_machdep.c,v 1.1 1998/03/16 09:03:38 pefo Exp $ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/malloc.h> +#include <sys/buf.h> +#include <sys/vnode.h> +#include <sys/user.h> +#include <sys/core.h> +#include <sys/exec.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> +#include <vm/vm_page.h> + +#include <machine/pte.h> +#include <machine/cpu.h> + +vm_offset_t kmem_alloc_wait_align __P((vm_map_t, vm_size_t, vm_size_t)); +static int vm_map_findspace_align __P((vm_map_t map, vm_offset_t, vm_size_t, + vm_offset_t *, vm_size_t)); +int vm_map_find_U __P((vm_map_t, vm_object_t, vm_offset_t, vm_offset_t *, + vm_size_t, boolean_t)); + +/* + * Finish a fork operation, with process p2 nearly set up. + * Copy and update the kernel stack and pcb, making the child + * ready to run, and marking it so that it can return differently + * than the parent. Returns 1 in the child process, 0 in the parent. + * We currently double-map the user area so that the stack is at the same + * address in each process; in the future we will probably relocate + * the frame pointers on the stack after copying. + */ +int +cpu_fork(p1, p2) + register struct proc *p1, *p2; +{ + struct user *up = p2->p_addr; + pt_entry_t *pte; + int i; + extern struct proc *machFPCurProcPtr; + + p2->p_md.md_regs = up->u_pcb.pcb_regs; + p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED; + + /* + * Cache the PTEs for the user area in the machine dependent + * part of the proc struct so cpu_switch() can quickly map in + * the user struct and kernel stack. Note: if the virtual address + * translation changes (e.g. swapout) we have to update this. + */ + pte = kvtopte(up); + for (i = 0; i < UPAGES; i++) { + p2->p_md.md_upte[i] = pte->pt_entry & ~(PG_G | PG_RO | PG_WIRED); + pte++; + } + + /* + * Copy floating point state from the FP chip if this process + * has state stored there. + */ + if (p1 == machFPCurProcPtr) + MipsSaveCurFPState(p1); + + /* + * Copy pcb and stack from proc p1 to p2. + * We do this as cheaply as possible, copying only the active + * part of the stack. The stack and pcb need to agree; + */ + p2->p_addr->u_pcb = p1->p_addr->u_pcb; + /* cache segtab for ULTBMiss() */ + p2->p_addr->u_pcb.pcb_segtab = (void *)p2->p_vmspace->vm_pmap.pm_segtab; + + /* + * Arrange for a non-local goto when the new process + * is started, to resume here, returning nonzero from setjmp. + */ +#ifdef DIAGNOSTIC + if (p1 != curproc) + panic("cpu_fork: curproc"); +#endif + if (copykstack(up)) { + /* + * Return 1 in child. + */ + return (1); + } + return (0); +} + +/* + * Finish a swapin operation. + * We neded to update the cached PTEs for the user area in the + * machine dependent part of the proc structure. + */ +void +cpu_swapin(p) + register struct proc *p; +{ + register struct user *up = p->p_addr; + register pt_entry_t *pte; + register int i; + + /* + * Cache the PTEs for the user area in the machine dependent + * part of the proc struct so cpu_switch() can quickly map in + * the user struct and kernel stack. + */ + pte = kvtopte(up); + for (i = 0; i < UPAGES; i++) { + p->p_md.md_upte[i] = pte->pt_entry & ~(PG_G | PG_RO | PG_WIRED); + pte++; + } +} + +/* + * cpu_exit is called as the last action during exit. + * We release the address space and machine-dependent resources, + * including the memory for the user structure and kernel stack. + * Once finished, we call switch_exit, which switches to a temporary + * pcb and stack and never returns. We block memory allocation + * until switch_exit has made things safe again. + */ +void +cpu_exit(p) + struct proc *p; +{ + extern struct proc *machFPCurProcPtr; + + if (machFPCurProcPtr == p) + machFPCurProcPtr = (struct proc *)0; + + vmspace_free(p->p_vmspace); + + (void) splhigh(); + kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES)); + switch_exit(); + /* NOTREACHED */ +} + +/* + * Dump the machine specific header information at the start of a core dump. + */ +int +cpu_coredump(p, vp, cred, chdr) + struct proc *p; + struct vnode *vp; + struct ucred *cred; + struct core *chdr; +{ + int error; + /*register struct user *up = p->p_addr;*/ + struct coreseg cseg; + extern struct proc *machFPCurProcPtr; + + CORE_SETMAGIC(*chdr, COREMAGIC, MID_MIPS, 0); + chdr->c_hdrsize = ALIGN(sizeof(*chdr)); + chdr->c_seghdrsize = ALIGN(sizeof(cseg)); + chdr->c_cpusize = sizeof (p -> p_addr -> u_pcb.pcb_regs); + + /* + * Copy floating point state from the FP chip if this process + * has state stored there. + */ + if (p == machFPCurProcPtr) + MipsSaveCurFPState(p); + + CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MIPS, CORE_CPU); + cseg.c_addr = 0; + cseg.c_size = chdr->c_cpusize; + + error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize, + (off_t)chdr->c_hdrsize, UIO_SYSSPACE, + IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p); + if (error) + return error; + + error = vn_rdwr(UIO_WRITE, vp, + (caddr_t)(&(p -> p_addr -> u_pcb.pcb_regs)), + (off_t)chdr -> c_cpusize, + (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), + UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, + cred, (int *)NULL, p); + + if (!error) + chdr->c_nseg++; + + return error; +} + +/* + * Move pages from one kernel virtual address to another. + * Both addresses are assumed to reside in the Sysmap, + * and size must be a multiple of CLSIZE. + */ +void +pagemove(from, to, size) + caddr_t from, to; + size_t size; +{ + pt_entry_t *fpte, *tpte; + + if (size % CLBYTES) + panic("pagemove"); + fpte = kvtopte(from); + tpte = kvtopte(to); + if(((int)from & CpuCacheAliasMask) != ((int)to & CpuCacheAliasMask)) { + R4K_HitFlushDCache((vm_offset_t)from, size); + } + while (size > 0) { + R4K_TLBFlushAddr((vm_offset_t)from); + R4K_TLBUpdate((vm_offset_t)to, fpte->pt_entry); + *tpte++ = *fpte; + fpte->pt_entry = PG_NV | PG_G; + fpte++; + size -= NBPG; + from += NBPG; + to += NBPG; + } +} + +extern vm_map_t phys_map; + +/* + * Map an IO request into kernel virtual address space. Requests fall into + * one of five catagories: + * + * B_PHYS|B_UAREA: User u-area swap. + * Address is relative to start of u-area (p_addr). + * B_PHYS|B_PAGET: User page table swap. + * Address is a kernel VA in usrpt (Usrptmap). + * B_PHYS|B_DIRTY: Dirty page push. + * Address is a VA in proc2's address space. + * B_PHYS|B_PGIN: Kernel pagein of user pages. + * Address is VA in user's address space. + * B_PHYS: User "raw" IO request. + * Address is VA in user's address space. + * + * All requests are (re)mapped into kernel VA space via the phys_map + */ +void +vmapbuf(bp, len) + struct buf *bp; + vm_size_t len; +{ + register caddr_t addr; + register vm_size_t sz; + struct proc *p; + int off; + vm_offset_t kva; + register vm_offset_t pa; + + if ((bp->b_flags & B_PHYS) == 0) + panic("vmapbuf"); + addr = bp->b_saveaddr = bp->b_un.b_addr; + off = (int)addr & PGOFSET; + p = bp->b_proc; + sz = round_page(off + len); + kva = kmem_alloc_wait_align(phys_map, sz, (vm_size_t)addr & CpuCacheAliasMask); + bp->b_un.b_addr = (caddr_t) (kva + off); + sz = atop(sz); + while (sz--) { + pa = pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map), + (vm_offset_t)addr); + if (pa == 0) + panic("vmapbuf: null page frame"); + pmap_enter(vm_map_pmap(phys_map), kva, trunc_page(pa), + VM_PROT_READ|VM_PROT_WRITE, TRUE); + addr += PAGE_SIZE; + kva += PAGE_SIZE; + } +} + +/* + * Free the io map PTEs associated with this IO operation. + * We also invalidate the TLB entries and restore the original b_addr. + */ +void +vunmapbuf(bp, len) + struct buf *bp; + vm_size_t len; +{ + register caddr_t addr = bp->b_un.b_addr; + register vm_size_t sz; + vm_offset_t kva; + + if ((bp->b_flags & B_PHYS) == 0) + panic("vunmapbuf"); + sz = round_page(len + ((int)addr & PGOFSET)); + kva = (vm_offset_t)((int)addr & ~PGOFSET); + kmem_free_wakeup(phys_map, kva, sz); + bp->b_un.b_addr = bp->b_saveaddr; + bp->b_saveaddr = NULL; +} + + +/* + * SAVE_HINT: + * + * Saves the specified entry as the hint for + * future lookups. Performs necessary interlocks. + */ +#define SAVE_HINT(map,value) \ + simple_lock(&(map)->hint_lock); \ + (map)->hint = (value); \ + simple_unlock(&(map)->hint_lock); + + +/* + * kmem_alloc_upage: + * + * Allocate pageable memory to the kernel's address map. + * map must be "kernel_map" below. + * (Currently only used when allocating U pages). + */ +vm_offset_t +kmem_alloc_upage(map, size) + vm_map_t map; + register vm_size_t size; +{ + vm_offset_t addr; + register int result; + + + size = round_page(size); + + addr = vm_map_min(map); + result = vm_map_find_U(map, NULL, (vm_offset_t) 0, + &addr, size, TRUE); + if (result != KERN_SUCCESS) { + return(0); + } + + return(addr); +} + +/* + * vm_map_find finds an unallocated region in the target address + * map with the given length aligned on U virtual address. + * The search is defined to be first-fit from the specified address; + * the region found is returned in the same parameter. + * + */ +int +vm_map_find_U(map, object, offset, addr, length, find_space) + vm_map_t map; + vm_object_t object; + vm_offset_t offset; + vm_offset_t *addr; /* IN/OUT */ + vm_size_t length; + boolean_t find_space; +{ + register vm_offset_t start; + int result; + + start = *addr; + vm_map_lock(map); + if (find_space) { + if (vm_map_findspace_align(map, start, length, addr, 0)) { + vm_map_unlock(map); + return (KERN_NO_SPACE); + } + start = *addr; + } + result = vm_map_insert(map, object, offset, start, start + length); + vm_map_unlock(map); + return (result); +} + +/* + * Find sufficient space for `length' bytes in the given map, starting at + * `start'. The map must be locked. Returns 0 on success, 1 on no space. + */ +static int +vm_map_findspace_align(map, start, length, addr, align) + vm_map_t map; + vm_offset_t start; + vm_size_t length; + vm_offset_t *addr; + vm_size_t align; +{ + register vm_map_entry_t entry, next; + register vm_offset_t end; + + if (start < map->min_offset) + start = map->min_offset; + if (start > map->max_offset) + return (1); + + /* + * Look for the first possible address; if there's already + * something at this address, we have to start after it. + */ + if (start == map->min_offset) { + if ((entry = map->first_free) != &map->header) + start = entry->end; + } else { + vm_map_entry_t tmp; + if (vm_map_lookup_entry(map, start, &tmp)) + start = tmp->end; + entry = tmp; + } + + /* + * Look through the rest of the map, trying to fit a new region in + * the gap between existing regions, or after the very last region. + */ + for (;; start = (entry = next)->end) { + /* + * Find the end of the proposed new region. Be sure we didn't + * go beyond the end of the map, or wrap around the address; + * if so, we lose. Otherwise, if this is the last entry, or + * if the proposed new region fits before the next entry, we + * win. + */ + start = ((start + NBPG -1) & ~(NBPG - 1)); /* Paranoia */ + if((start & CpuCacheAliasMask) <= align) { + start += align - (start & CpuCacheAliasMask); + } + else { + start = ((start + CpuCacheAliasMask) & ~CpuCacheAliasMask); + start += align; + } + + end = start + length; + if (end > map->max_offset || end < start) + return (1); + next = entry->next; + if (next == &map->header || next->start >= end) + break; + } + SAVE_HINT(map, entry); + *addr = start; + return (0); +} + +/* + * kmem_alloc_wait_align + * + * Allocates pageable memory from a sub-map of the kernel. If the submap + * has no room, the caller sleeps waiting for more memory in the submap. + * + */ +vm_offset_t +kmem_alloc_wait_align(map, size, align) + vm_map_t map; + vm_size_t size; + vm_size_t align; +{ + vm_offset_t addr; + + size = round_page(size); + + for (;;) { + /* + * To make this work for more than one map, + * use the map's lock to lock out sleepers/wakers. + */ + vm_map_lock(map); + if (vm_map_findspace_align(map, 0, size, &addr, align) == 0) + break; + /* no space now; see if we can ever get space */ + if (vm_map_max(map) - vm_map_min(map) < size) { + vm_map_unlock(map); + return (0); + } + assert_wait(map, TRUE); + vm_map_unlock(map); + thread_block("mKmwait"); + } + vm_map_insert(map, NULL, (vm_offset_t)0, addr, addr + size); + vm_map_unlock(map); + return (addr); +} |