Module Name: src
Committed By: matt
Date: Thu Feb 9 20:01:21 UTC 2012
Modified Files:
src/sys/arch/mips/include [matt-nb5-mips64]: locore.h
src/sys/arch/mips/mips [matt-nb5-mips64]: locore.S locore_mips1.S
mipsX_subr.S mips_fixup.c
Log Message:
Update mips_fixup.c to version from -HEAD.
Move cpu_switchto to locore jumpvec and create a stub for it.
To generate a diff of this commit:
cvs rdiff -u -r1.78.36.1.2.31 -r1.78.36.1.2.32 \
src/sys/arch/mips/include/locore.h
cvs rdiff -u -r1.167.38.24 -r1.167.38.25 src/sys/arch/mips/mips/locore.S
cvs rdiff -u -r1.64.26.1.2.14 -r1.64.26.1.2.15 \
src/sys/arch/mips/mips/locore_mips1.S
cvs rdiff -u -r1.26.36.1.2.54 -r1.26.36.1.2.55 \
src/sys/arch/mips/mips/mipsX_subr.S
cvs rdiff -u -r1.1.2.12 -r1.1.2.13 src/sys/arch/mips/mips/mips_fixup.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/mips/include/locore.h
diff -u src/sys/arch/mips/include/locore.h:1.78.36.1.2.31 src/sys/arch/mips/include/locore.h:1.78.36.1.2.32
--- src/sys/arch/mips/include/locore.h:1.78.36.1.2.31 Fri Dec 23 08:09:08 2011
+++ src/sys/arch/mips/include/locore.h Thu Feb 9 20:01:21 2012
@@ -111,6 +111,8 @@ struct mips_jump_fixup_info {
void fixup_splcalls(void); /* splstubs.c */
bool mips_fixup_exceptions(mips_fixup_callback_t);
bool mips_fixup_zero_relative(int32_t, uint32_t [2]);
+intptr_t
+ mips_fixup_addr(const uint32_t *);
void mips_fixup_stubs(uint32_t *, uint32_t *);
/*
@@ -348,6 +350,7 @@ typedef struct {
void (*ljv_tlb_enter)(size_t, vaddr_t, uint32_t);
void (*ljv_tlb_read_indexed)(size_t, struct tlbmask *);
void (*ljv_tlb_write_indexed)(size_t, const struct tlbmask *);
+ lwp_t * (*ljv_cpu_switchto)(lwp_t *, lwp_t *, bool);
} mips_locore_jumpvec_t;
typedef struct {
Index: src/sys/arch/mips/mips/locore.S
diff -u src/sys/arch/mips/mips/locore.S:1.167.38.24 src/sys/arch/mips/mips/locore.S:1.167.38.25
--- src/sys/arch/mips/mips/locore.S:1.167.38.24 Thu Jan 19 08:28:49 2012
+++ src/sys/arch/mips/mips/locore.S Thu Feb 9 20:01:21 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.167.38.24 2012/01/19 08:28:49 matt Exp $ */
+/* locore.S,v 1.167.38.24 2012/01/19 08:28:49 matt Exp */
/*
* Copyright (c) 1992, 1993
@@ -172,17 +172,18 @@ _C_LABEL(kernel_text):
_C_LABEL(verylocore):
/*
- * struct lwp *cpu_switchto(struct lwp *cur, struct lwp *next)
+ * lwp_t *mips_cpu_switchto(lwp_t *cur, lwp_t *next, bool returning)
* Switch to the specified next LWP
* Arguments:
* a0 the current LWP
* a1 the LWP to switch to
+ * a2 returning to a softint LWP
* Returns:
* v0 the LWP we have switched from
*
* called at IPL_SCHED
*/
-NESTED(cpu_switchto, CALLFRAME_SIZ, ra)
+NESTED(mips_cpu_switchto, CALLFRAME_SIZ, ra)
#ifdef PARANOIA
/*
* Make sure we are at IPL_SCHED
@@ -299,7 +300,7 @@ NESTED(cpu_switchto, CALLFRAME_SIZ, ra)
#else
JR_HB_RA
#endif /* PARANOIA */
-END(cpu_switchto)
+END(mips_cpu_switchto)
#ifdef __HAVE_FAST_SOFTINTS
/*
Index: src/sys/arch/mips/mips/locore_mips1.S
diff -u src/sys/arch/mips/mips/locore_mips1.S:1.64.26.1.2.14 src/sys/arch/mips/mips/locore_mips1.S:1.64.26.1.2.15
--- src/sys/arch/mips/mips/locore_mips1.S:1.64.26.1.2.14 Fri Dec 23 23:12:34 2011
+++ src/sys/arch/mips/mips/locore_mips1.S Thu Feb 9 20:01:21 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: locore_mips1.S,v 1.64.26.1.2.14 2011/12/23 23:12:34 matt Exp $ */
+/* locore_mips1.S,v 1.64.26.1.2.14 2011/12/23 23:12:34 matt Exp */
/*
* Copyright (c) 1992, 1993
@@ -1735,6 +1735,7 @@ _C_LABEL(MIPSX(locore_vec)):
PTR_WORD _C_LABEL(MIPSX(tlb_enter))
PTR_WORD _C_LABEL(MIPSX(tlb_read_indexed))
PTR_WORD _C_LABEL(MIPSX(tlb_write_indexed))
+ PTR_WORD _C_LABEL(mips_cpu_switchto)
.globl _C_LABEL(MIPSX(locoresw))
_C_LABEL(MIPSX(locoresw)):
Index: src/sys/arch/mips/mips/mipsX_subr.S
diff -u src/sys/arch/mips/mips/mipsX_subr.S:1.26.36.1.2.54 src/sys/arch/mips/mips/mipsX_subr.S:1.26.36.1.2.55
--- src/sys/arch/mips/mips/mipsX_subr.S:1.26.36.1.2.54 Thu Jan 19 08:28:49 2012
+++ src/sys/arch/mips/mips/mipsX_subr.S Thu Feb 9 20:01:21 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: mipsX_subr.S,v 1.26.36.1.2.54 2012/01/19 08:28:49 matt Exp $ */
+/* $NetBSD: mipsX_subr.S,v 1.26.36.1.2.55 2012/02/09 20:01:21 matt Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -2912,6 +2912,7 @@ _C_LABEL(MIPSX(locore_vec)):
PTR_WORD _C_LABEL(MIPSX(tlb_enter))
PTR_WORD _C_LABEL(MIPSX(tlb_read_indexed))
PTR_WORD _C_LABEL(MIPSX(tlb_write_indexed))
+ PTR_WORD _C_LABEL(mips_cpu_switchto)
.globl _C_LABEL(MIPSX(locoresw))
_C_LABEL(MIPSX(locoresw)):
Index: src/sys/arch/mips/mips/mips_fixup.c
diff -u src/sys/arch/mips/mips/mips_fixup.c:1.1.2.12 src/sys/arch/mips/mips/mips_fixup.c:1.1.2.13
--- src/sys/arch/mips/mips/mips_fixup.c:1.1.2.12 Fri Nov 4 07:47:40 2011
+++ src/sys/arch/mips/mips/mips_fixup.c Thu Feb 9 20:01:21 2012
@@ -1,3 +1,5 @@
+/* $NetBSD: mips_fixup.c,v 1.1.2.13 2012/02/09 20:01:21 matt Exp $ */
+
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -28,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "mips_fixup.c,v 1.1.2.10 2011/04/29 08:26:28 matt Exp");
+__KERNEL_RCSID(0, "$NetBSD: mips_fixup.c,v 1.1.2.13 2012/02/09 20:01:21 matt Exp $");
#include "opt_mips3_wired.h"
#include "opt_multiprocessor.h"
@@ -40,12 +42,13 @@ __KERNEL_RCSID(0, "mips_fixup.c,v 1.1.2.
#include <mips/cache.h>
#include <mips/mips3_pte.h>
#include <mips/regnum.h>
+#include <mips/mips_opcode.h>
-#define INSN_LUI_P(insn) (((insn) >> 26) == 017)
-#define INSN_LW_P(insn) (((insn) >> 26) == 043)
-#define INSN_SW_P(insn) (((insn) >> 26) == 053)
-#define INSN_LD_P(insn) (((insn) >> 26) == 067)
-#define INSN_SD_P(insn) (((insn) >> 26) == 077)
+#define INSN_LUI_P(insn) (((insn) >> 26) == OP_LUI)
+#define INSN_LW_P(insn) (((insn) >> 26) == OP_LW)
+#define INSN_SW_P(insn) (((insn) >> 26) == OP_SW)
+#define INSN_LD_P(insn) (((insn) >> 26) == OP_LD)
+#define INSN_SD_P(insn) (((insn) >> 26) == OP_SD)
#define INSN_LOAD_P(insn) (INSN_LD_P(insn) || INSN_LW_P(insn))
#define INSN_STORE_P(insn) (INSN_SD_P(insn) || INSN_SW_P(insn))
@@ -136,7 +139,7 @@ mips_fixup_exceptions(mips_fixup_callbac
if (fixed)
mips_icache_sync_range((vaddr_t)start,
- sizeof(start[0]) * (end - start));
+ sizeof(start[0]) * (end - start));
return fixed;
}
@@ -226,13 +229,151 @@ fixup_mips_jump(uint32_t *insnp, const s
*insnp = insn;
}
+intptr_t
+mips_fixup_addr(const uint32_t *stubp)
+{
+ /*
+ * Stubs typically look like:
+ * lui v0, %hi(sym)
+ * lX t9, %lo(sym)(v0)
+ * [nop]
+ * jr t9
+ * nop
+ *
+ * Or for loongson2 (
+ * lui v0, %hi(sym)
+ * lX t9, %lo(sym)(v0)
+ * lui at,0xcfff
+ * ori at,at,0xffff
+ * and t9,t9,at
+ * jr t9
+ * move at,at
+ * or:
+ * lui v0, %hi(sym)
+ * lX t9, %lo(sym)(v0)
+ * li at, 0x3
+ * dmtc0 at, $22
+ * jr t9
+ * nop
+ */
+ mips_reg_t regs[32];
+ uint32_t used = 1;
+ size_t n;
+ const char *errstr = "mips";
+ /*
+ * This is basically a small MIPS emulator for those instructions
+ * that might in a stub routine.
+ */
+ for (n = 0; n < 16; n++) {
+ const InstFmt insn = { .word = stubp[n] };
+ switch (insn.IType.op) {
+ case OP_LUI:
+ regs[insn.IType.rt] = (int16_t)insn.IType.imm << 16;
+ used |= (1 << insn.IType.rt);
+ break;
+#ifdef _LP64
+ case OP_LD:
+ if ((used & (1 << insn.IType.rs)) == 0) {
+ errstr = "LD";
+ goto out;
+ }
+ regs[insn.IType.rt] = *(const int64_t *)
+ (regs[insn.IType.rs] + (int16_t)insn.IType.imm);
+ used |= (1 << insn.IType.rt);
+ break;
+#else
+ case OP_LW:
+ if ((used & (1 << insn.IType.rs)) == 0) {
+ errstr = "LW";
+ goto out;
+ }
+ regs[insn.IType.rt] = *(const int32_t *)
+ ((intptr_t)regs[insn.IType.rs]
+ + (int16_t)insn.IType.imm);
+ used |= (1 << insn.IType.rt);
+ break;
+#endif
+ case OP_ORI:
+ if ((used & (1 << insn.IType.rs)) == 0) {
+ errstr = "ORI";
+ goto out;
+ }
+ regs[insn.IType.rt] |= insn.IType.imm;
+ used |= (1 << insn.IType.rt);
+ break;
+ case OP_COP0:
+ switch (insn.RType.rs) {
+ case OP_DMT:
+ if (insn.RType.rd != 22) {
+ errstr = "dmtc0 dst";
+ goto out;
+ }
+ if ((used & (1 << insn.RType.rt)) == 0) {
+ errstr = "dmtc0 src";
+ goto out;
+ }
+ break;
+ default:
+ errstr = "COP0";
+ goto out;
+ }
+ break;
+ case OP_SPECIAL:
+ switch (insn.RType.func) {
+ case OP_JR:
+ if ((used & (1 << insn.RType.rs)) == 0) {
+ errstr = "JR";
+ goto out;
+ }
+ if (stubp[n+1] != 0
+ && stubp[n+1] != 0x30c600ff /* and a2,a2,0xff */
+ && stubp[n+1] != 0x00200825) {
+ n++;
+ errstr = "delay slot";
+ goto out;
+ }
+ return regs[insn.RType.rs];
+ case OP_AND:
+ if ((used & (1 << insn.RType.rs)) == 0
+ || (used & (1 << insn.RType.rt)) == 0) {
+ errstr = "AND";
+ goto out;
+ }
+ regs[insn.RType.rd] =
+ regs[insn.RType.rs] & regs[insn.RType.rt];
+ used |= (1 << insn.RType.rd);
+ break;
+ case OP_SLL: /* nop */
+ if (insn.RType.rd != _R_ZERO) {
+ errstr = "NOP";
+ goto out;
+ }
+ break;
+ default:
+ errstr = "SPECIAL";
+ goto out;
+ }
+ break;
+ default:
+ errstr = "mips";
+ goto out;
+ }
+ }
+
+ out:
+ printf("%s: unexpected %s insn %#x at %p\n",
+ __func__, errstr,
+ stubp[n], &stubp[n]);
+ return 0;
+}
+
void
mips_fixup_stubs(uint32_t *start, uint32_t *end)
{
#ifdef DEBUG
size_t fixups_done = 0;
uint32_t cycles =
-#if (MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2 + MIPS64_RMIXL + MIPS64R2_RMIXL) > 0
+#if (MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
(CPUISMIPS3 ? mips3_cp0_count_read() : 0);
#else
0;
@@ -262,43 +403,8 @@ mips_fixup_stubs(uint32_t *start, uint32
|| stubp < __stub_start || __stub_end <= stubp)
continue;
- /*
- * Stubs typically look like:
- * lui v0, %hi(sym)
- * lX t9, %lo(sym)(v0)
- * [nop]
- * jr t9
- * nop
- */
- const uint32_t lui_insn = stubp[0];
- const uint32_t load_insn = stubp[1];
-#ifdef DIAGNOSTIC
- if (stubp[2] == 0) {
- KASSERT(stubp[3] == 0x03200008); /* jr t9 */
- KASSERT(stubp[4] == 0); /* nop */
- } else {
- KASSERT(stubp[2] == 0x03200008); /* jr t9 */
- KASSERT(stubp[3] == 0); /* nop */
- }
+ const intptr_t real_addr = mips_fixup_addr(stubp);
- KASSERT(INSN_LUI_P(lui_insn));
-#ifdef _LP64
- KASSERT(INSN_LD_P(load_insn));
-#else
- KASSERT(INSN_LW_P(load_insn));
-#endif
- const u_int lui_reg = (lui_insn >> 16) & 31;
- const u_int load_reg = (load_insn >> 16) & 31;
-#endif
- KASSERT(((load_insn >> 21) & 31) == lui_reg);
- KASSERT(load_reg == _R_T9);
-
- intptr_t load_addr = ((int16_t)lui_insn << 16) + (int16_t) load_insn;
-#ifdef _LP64
- const intptr_t real_addr = *(int64_t *)load_addr;
-#else
- const intptr_t real_addr = *(int32_t *)load_addr;
-#endif
/*
* If the real_addr has been set yet, don't fix up.
*/
@@ -333,7 +439,7 @@ mips_fixup_stubs(uint32_t *start, uint32
sizeof(uint32_t [end - start]));
#ifdef DEBUG
-#if (MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2 + MIPS64_RMIXL + MIPS64R2_RMIXL) > 0
+#if (MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
if (CPUISMIPS3)
cycles = mips3_cp0_count_read() - cycles;
#endif
@@ -346,6 +452,7 @@ mips_fixup_stubs(uint32_t *start, uint32
#define __stub __section(".stub")
void mips_cpu_switch_resume(struct lwp *) __stub;
+lwp_t * cpu_switchto(lwp_t *, lwp_t *, bool) __stub;
void tlb_set_asid(uint32_t) __stub;
void tlb_invalidate_all(void) __stub;
void tlb_invalidate_globals(void) __stub;
@@ -369,6 +476,12 @@ mips_cpu_switch_resume(struct lwp *l)
(*mips_locore_jumpvec.ljv_cpu_switch_resume)(l);
}
+lwp_t *
+cpu_switchto(lwp_t *from, lwp_t *to, bool returning)
+{
+ return (*mips_locore_jumpvec.ljv_cpu_switchto)(from, to, returning);
+}
+
void
tlb_set_asid(uint32_t asid)
{