summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/mips/conf/files.mips6
-rw-r--r--sys/arch/mips/include/archtype.h24
-rw-r--r--sys/arch/mips/include/asm.h5
-rw-r--r--sys/arch/mips/include/cpu.h11
-rw-r--r--sys/arch/mips/include/db_machdep.h80
-rw-r--r--sys/arch/mips/include/frame.h41
-rw-r--r--sys/arch/mips/include/regdef.h6
-rw-r--r--sys/arch/mips/include/regnum.h11
-rw-r--r--sys/arch/mips/include/varargs.h20
-rw-r--r--sys/arch/mips/mips/arcbios.c5
-rw-r--r--sys/arch/mips/mips/clock.c8
-rw-r--r--sys/arch/mips/mips/cpu.c10
-rw-r--r--sys/arch/mips/mips/db_disasm.c406
-rw-r--r--sys/arch/mips/mips/db_machdep.c302
-rw-r--r--sys/arch/mips/mips/disksubr.c12
-rw-r--r--sys/arch/mips/mips/fp.S5
-rw-r--r--sys/arch/mips/mips/mainbus.c11
-rw-r--r--sys/arch/mips/mips/minidebug.c22
-rw-r--r--sys/arch/mips/mips/vm_machdep.c517
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);
+}