From 4c44c335c5f843ea8f2463e3c9aa46eeb8162a1d Mon Sep 17 00:00:00 2001 From: bouyer Date: Sat, 27 Aug 2011 13:23:52 +0000 Subject: [PATCH] loongson2f support: - Add some loongson2 definitions to cpuregs.h, from OpenBSD - Make sure that the at register is useable before every jump register instruction (exept when register is k0 or k1) because -mfix-loongson2f-btb needs the at register for its workaround - add code to mips_fixup.c to handle the instructions added by -mfix-loongson2f-btb - Add a ls2-specific tlb miss handler: it doesn't have separate handler for the xtlbmiss exeption. - Fixes for some #ifdef MIPS3_LOONGSON2 assembly code (using the wrong register) --- common/lib/libc/arch/mips/atomic/atomic_add.S | 15 ++- common/lib/libc/arch/mips/atomic/atomic_and.S | 15 ++- common/lib/libc/arch/mips/atomic/atomic_dec.S | 14 +- common/lib/libc/arch/mips/atomic/atomic_inc.S | 15 ++- common/lib/libc/arch/mips/atomic/atomic_or.S | 12 +- .../lib/libc/arch/mips/atomic/atomic_swap.S | 15 ++- common/lib/libc/arch/mips/string/bcopy.S | 8 +- sys/arch/mips/include/cpuregs.h | 59 ++++++++- sys/arch/mips/mips/lock_stubs_ras.S | 37 ++++-- sys/arch/mips/mips/mipsX_subr.S | 120 +++++++++++++----- sys/arch/mips/mips/mips_fixup.c | 32 ++++- 11 files changed, 280 insertions(+), 62 deletions(-) diff --git a/common/lib/libc/arch/mips/atomic/atomic_add.S b/common/lib/libc/arch/mips/atomic/atomic_add.S index 298ad243ac82..303f8123cb98 100644 --- a/common/lib/libc/arch/mips/atomic/atomic_add.S +++ b/common/lib/libc/arch/mips/atomic/atomic_add.S @@ -1,4 +1,4 @@ -/* $NetBSD: atomic_add.S,v 1.2 2009/12/14 00:38:59 matt Exp $ */ +/* $NetBSD: atomic_add.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -30,12 +30,21 @@ #include #include "atomic_op_asm.h" -RCSID("$NetBSD: atomic_add.S,v 1.2 2009/12/14 00:38:59 matt Exp $") +RCSID("$NetBSD: atomic_add.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $") .text - .set noat .set noreorder +#ifdef _KERNEL_OPT +#include "opt_cputype.h" +#ifndef MIPS3_LOONGSON2F + .set noat .set nomacro +#endif +#else /* _KERNEL_OPT */ + .set noat + .set nomacro +#endif /* _KERNEL_OPT */ + LEAF(_atomic_add_32) 1: INT_LL t0, 0(a0) diff --git a/common/lib/libc/arch/mips/atomic/atomic_and.S b/common/lib/libc/arch/mips/atomic/atomic_and.S index 7d233d037466..6f3553c34b14 100644 --- a/common/lib/libc/arch/mips/atomic/atomic_and.S +++ b/common/lib/libc/arch/mips/atomic/atomic_and.S @@ -1,4 +1,4 @@ -/* $NetBSD: atomic_and.S,v 1.2 2009/12/14 00:38:59 matt Exp $ */ +/* $NetBSD: atomic_and.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -30,12 +30,21 @@ #include #include "atomic_op_asm.h" -RCSID("$NetBSD: atomic_and.S,v 1.2 2009/12/14 00:38:59 matt Exp $") +RCSID("$NetBSD: atomic_and.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $") .text - .set noat .set noreorder +#ifdef _KERNEL_OPT +#include "opt_cputype.h" +#ifndef MIPS3_LOONGSON2F + .set noat .set nomacro +#endif +#else /* _KERNEL_OPT */ + .set noat + .set nomacro +#endif /* _KERNEL_OPT */ + LEAF(_atomic_and_32) 1: INT_LL t0, 0(a0) diff --git a/common/lib/libc/arch/mips/atomic/atomic_dec.S b/common/lib/libc/arch/mips/atomic/atomic_dec.S index f44850f548f5..99b5d64a5b60 100644 --- a/common/lib/libc/arch/mips/atomic/atomic_dec.S +++ b/common/lib/libc/arch/mips/atomic/atomic_dec.S @@ -1,4 +1,4 @@ -/* $NetBSD: atomic_dec.S,v 1.2 2009/12/14 00:39:00 matt Exp $ */ +/* $NetBSD: atomic_dec.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -30,12 +30,20 @@ #include #include "atomic_op_asm.h" -RCSID("$NetBSD: atomic_dec.S,v 1.2 2009/12/14 00:39:00 matt Exp $") +RCSID("$NetBSD: atomic_dec.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $") .text - .set noat .set noreorder +#ifdef _KERNEL_OPT +#include "opt_cputype.h" +#ifndef MIPS3_LOONGSON2F + .set noat .set nomacro +#endif +#else /* _KERNEL_OPT */ + .set noat + .set nomacro +#endif /* _KERNEL_OPT */ LEAF(_atomic_dec_32) 1: INT_LL t0, 0(a0) diff --git a/common/lib/libc/arch/mips/atomic/atomic_inc.S b/common/lib/libc/arch/mips/atomic/atomic_inc.S index 5ab8e493416b..b7606f2116a3 100644 --- a/common/lib/libc/arch/mips/atomic/atomic_inc.S +++ b/common/lib/libc/arch/mips/atomic/atomic_inc.S @@ -1,4 +1,4 @@ -/* $NetBSD: atomic_inc.S,v 1.2 2009/12/14 00:39:00 matt Exp $ */ +/* $NetBSD: atomic_inc.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -30,12 +30,21 @@ #include #include "atomic_op_asm.h" -RCSID("$NetBSD: atomic_inc.S,v 1.2 2009/12/14 00:39:00 matt Exp $") +RCSID("$NetBSD: atomic_inc.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $") .text - .set noat .set noreorder +#ifdef _KERNEL_OPT +#include "opt_cputype.h" +#ifndef MIPS3_LOONGSON2F + .set noat .set nomacro +#endif +#else /* _KERNEL_OPT */ + .set noat + .set nomacro +#endif /* _KERNEL_OPT */ + LEAF(_atomic_inc_32) 1: INT_LL t0, 0(a0) diff --git a/common/lib/libc/arch/mips/atomic/atomic_or.S b/common/lib/libc/arch/mips/atomic/atomic_or.S index bf25d894564c..d66ae710c750 100644 --- a/common/lib/libc/arch/mips/atomic/atomic_or.S +++ b/common/lib/libc/arch/mips/atomic/atomic_or.S @@ -1,4 +1,4 @@ -/* $NetBSD: atomic_or.S,v 1.2 2009/12/14 00:39:00 matt Exp $ */ +/* $NetBSD: atomic_or.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -31,9 +31,17 @@ #include "atomic_op_asm.h" .text - .set noat .set noreorder +#ifdef _KERNEL_OPT +#include "opt_cputype.h" +#ifndef MIPS3_LOONGSON2F + .set noat .set nomacro +#endif +#else /* _KERNEL_OPT */ + .set noat + .set nomacro +#endif /* _KERNEL_OPT */ LEAF(_atomic_or_32) 1: INT_LL t0, 0(a0) diff --git a/common/lib/libc/arch/mips/atomic/atomic_swap.S b/common/lib/libc/arch/mips/atomic/atomic_swap.S index b5f94778dade..e437d8d00d80 100644 --- a/common/lib/libc/arch/mips/atomic/atomic_swap.S +++ b/common/lib/libc/arch/mips/atomic/atomic_swap.S @@ -1,4 +1,4 @@ -/* $NetBSD: atomic_swap.S,v 1.2 2009/12/14 00:39:00 matt Exp $ */ +/* $NetBSD: atomic_swap.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -30,12 +30,21 @@ #include #include "atomic_op_asm.h" -RCSID("$NetBSD: atomic_swap.S,v 1.2 2009/12/14 00:39:00 matt Exp $") +RCSID("$NetBSD: atomic_swap.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $") .text - .set noat .set noreorder +#ifdef _KERNEL_OPT +#include "opt_cputype.h" +#ifndef MIPS3_LOONGSON2F + .set noat .set nomacro +#endif +#else /* _KERNEL_OPT */ + .set noat + .set nomacro +#endif /* _KERNEL_OPT */ + LEAF(_atomic_swap_32) 1: INT_LL v0, 0(a0) diff --git a/common/lib/libc/arch/mips/string/bcopy.S b/common/lib/libc/arch/mips/string/bcopy.S index 05f6777e0659..d301185ef15b 100644 --- a/common/lib/libc/arch/mips/string/bcopy.S +++ b/common/lib/libc/arch/mips/string/bcopy.S @@ -1,4 +1,4 @@ -/* $NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $ */ +/* $NetBSD: bcopy.S,v 1.4 2011/08/27 13:23:52 bouyer Exp $ */ /* * Mach Operating System @@ -46,7 +46,7 @@ #if 0 RCSID("from: @(#)mips_bcopy.s 2.2 CMU 18/06/93") #else - RCSID("$NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $") + RCSID("$NetBSD: bcopy.S,v 1.4 2011/08/27 13:23:52 bouyer Exp $") #endif #endif /* LIBC_SCCS and not lint */ @@ -170,8 +170,10 @@ LEAF(FUNCTION) PTR_ADDU DSTREG,1 4: # copydone + .set at #-mfix-loongson2f-btb j ra nop + .set noat /* * Copy from unaligned source to aligned dest. @@ -264,8 +266,10 @@ LEAF(FUNCTION) PTR_SUBU DSTREG,1 4: # copydone + .set at #-mfix-loongson2f-btb j ra nop + .set noat /* * Copy from unaligned source to aligned dest. diff --git a/sys/arch/mips/include/cpuregs.h b/sys/arch/mips/include/cpuregs.h index f3248d53ae4d..fcd29d934e15 100644 --- a/sys/arch/mips/include/cpuregs.h +++ b/sys/arch/mips/include/cpuregs.h @@ -1,4 +1,20 @@ -/* $NetBSD: cpuregs.h,v 1.85 2011/08/02 05:12:32 matt Exp $ */ +/* $NetBSD: cpuregs.h,v 1.86 2011/08/27 13:23:52 bouyer Exp $ */ + +/* + * Copyright (c) 2009 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ /* * Copyright (c) 1992, 1993 @@ -970,4 +986,45 @@ #include #endif +#ifdef MIPS3_LOONGSON2 +/* + * Loongson 2E/2F specific defines + */ + +/* + * Address Window registers physical addresses + * + * The Loongson 2F processor has an AXI crossbar with four possible bus + * masters, each one having four programmable address windows. + * + * Each window is defined with three 64-bit registers: + * - a base address register, defining the address in the master address + * space (base register). + * - an address mask register, defining which address bits are valid in this + * window. A given address matches a window if (addr & mask) == base. + * - the location of the window base in the target, as well at the target + * number itself (mmap register). The lower 20 bits of the address are + * forced as zeroes regardless of their value in this register. + * The translated address is thus (addr & ~mask) | (mmap & ~0xfffff). + */ + +#define LOONGSON_AWR_BASE_ADDRESS 0x3ff00000ULL + +#define LOONGSON_AWR_BASE(master, window) \ + (LOONGSON_AWR_BASE_ADDRESS + (window) * 0x08 + (master) * 0x60 + 0x00) +#define LOONGSON_AWR_SIZE(master, window) \ + (LOONGSON_AWR_BASE_ADDRESS + (window) * 0x08 + (master) * 0x60 + 0x20) +#define LOONGSON_AWR_MMAP(master, window) \ + (LOONGSON_AWR_BASE_ADDRESS + (window) * 0x08 + (master) * 0x60 + 0x40) + +/* + * Bits in the diagnostic register + */ + +#define COP_0_DIAG_ITLB_CLEAR 0x04 +#define COP_0_DIAG_BTB_CLEAR 0x02 +#define COP_0_DIAG_RAS_DISABLE 0x01 + +#endif /* MIPS3_LOONGSON2 */ + #endif /* _MIPS_CPUREGS_H_ */ diff --git a/sys/arch/mips/mips/lock_stubs_ras.S b/sys/arch/mips/mips/lock_stubs_ras.S index 3e756ccdc9ab..cd3d38bb770b 100644 --- a/sys/arch/mips/mips/lock_stubs_ras.S +++ b/sys/arch/mips/mips/lock_stubs_ras.S @@ -1,4 +1,4 @@ -/* $NetBSD: lock_stubs_ras.S,v 1.3 2011/04/29 22:04:42 matt Exp $ */ +/* $NetBSD: lock_stubs_ras.S,v 1.4 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -80,6 +80,20 @@ .set noreorder .set noat +/* + * to work around the branch prediction engine misbehavior of + * Loongson 2F processors we need to clear the branch target buffer before + * a j ra. This requires extra instructions which don't fit in the RAS blocks, + * so do a PC-relative just to a block of code (this is the same size as + * a j ra) where we can let the assembler install the workaround. + */ +#ifdef MIPS3_LOONGSON2F +#define J_RA j loongson_return +#else +#define J_RA j ra +#endif + + /* * unsigned long ras_atomic_cas_ulong(volatile unsigned long *val, * unsigned long old, unsigned long new); @@ -89,7 +103,7 @@ EXPORT(_lock_ras_start) STATIC_LEAF(ras_atomic_cas_noupdate) - j ra + J_RA move v0, t0 END(ras_atomic_cas_noupdate) @@ -105,7 +119,7 @@ _atomic_cas_ulong_ras_start: nop PTR_S a2, (a0) /* <- critical section end */ _atomic_cas_ulong_ras_end: - j ra + J_RA move v0, a1 END(ras_atomic_cas_ulong) @@ -125,7 +139,7 @@ _atomic_cas_uint_ras_start: nop INT_S a2, (a0) /* <- critical section end */ _atomic_cas_uint_ras_end: - j ra + J_RA move v0, a1 END(ras_atomic_cas_uint) @@ -146,7 +160,7 @@ _ucas_ulong_ras_start: LONG_S a2, (a0) /* <- critical section end */ _ucas_ulong_ras_end: PTR_S zero, PCB_ONFAULT(v1) - j ra + J_RA LONG_S t0, 0(a3) END(_ucas_ulong_ras) @@ -165,7 +179,7 @@ _ucas_uint_ras_start: INT_S a2, (a0) /* <- critical section end */ _ucas_uint_ras_end: PTR_S zero, PCB_ONFAULT(v1) - j ra + J_RA INT_S t0, 0(a3) END(_ucas_uint_ras) @@ -184,7 +198,7 @@ _mutex_enter_ras_start: nop PTR_S MIPS_CURLWP, (a0)/* <- critical section end */ _mutex_enter_ras_end: - j ra + J_RA nop END(ras_mutex_enter) @@ -203,7 +217,7 @@ _mutex_exit_ras_start: nop PTR_S zero, (a0) /* <- critical section end */ _mutex_exit_ras_exit: - j ra + J_RA nop END(ras_mutex_exit) @@ -223,6 +237,13 @@ END(ras_mutex_vector_exit) .p2align LOG2_MIPS_LOCK_RAS_SIZE /* Get out of the RAS block */ + .set at +#ifdef MIPS3_LOONGSON2F +loongson_return: + j ra + nop +#endif + /* * Patch up the given address. We arrive here if we might have trapped * within one of the critical sections above. Do: diff --git a/sys/arch/mips/mips/mipsX_subr.S b/sys/arch/mips/mips/mipsX_subr.S index a5db1008d4ca..9e707f3ffe40 100644 --- a/sys/arch/mips/mips/mipsX_subr.S +++ b/sys/arch/mips/mips/mipsX_subr.S @@ -1,4 +1,4 @@ -/* $NetBSD: mipsX_subr.S,v 1.53 2011/08/16 06:55:12 matt Exp $ */ +/* $NetBSD: mipsX_subr.S,v 1.54 2011/08/27 13:23:52 bouyer Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -330,8 +330,54 @@ * * Don't check for invalid pte's here. We load them as well and * let the processor trap to load the correct value after service. + * + * Loongson2 processors don't have separate tlbmiss and xtlbmiss handlers; + * so we have to check for useg addresses in tlb_miss. The good news is that + * we can use 64 intructions form tlbmiss instead of 32. + * *---------------------------------------------------------------------------- */ +#ifdef MIPS3_LOONGSON2 +/* this loongson2-specific part is almost a copy of xtlb_miss */ +VECTOR(MIPSX(tlb_miss), unknown) + .set noat + dmfc0 k0, MIPS_COP_0_BAD_VADDR #00: k0=bad address +#ifdef _LP64 + nop #01: nop + bltz k0, MIPSX(kernelfault) #02: k0<0 -> kernel fault + PTR_SRL k1, k0, 31 #03: clear useg bits + beqz k1, 1f #04: k1==0 -> useg address + PTR_SRL k1,k0,2*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2)+PGSHIFT #05: clear valid bits + bnez k1, MIPSX(nopagetable) #06: not legal address + PTR_SRL k0, 2*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2) #05: k0=seg offset (almost) + lui k1, %hi(CPUVAR(PMAP_SEGTAB)) #07: k1=hi of segtab + andi k0, NBPG-(1< kernel fault + dsrl k0, 31 #11: clear low 31 bits + bnez k0, MIPSX(nopagetable) #12: not legal address + PTR_L k1, %lo(CPUVAR(PMAP_SEG0TAB))(k1)#13: k1=segment tab base + dmfc0 k0, MIPS_COP_0_BAD_VADDR #14: k0=bad address (again) + nop #15 + b MIPSX(tlb_miss_common) #16 + PTR_SRL k0, 1*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2) #17: k0=seg offset (almost) +_VECTOR_END(MIPSX(tlb_miss)) +/* dummy xtlb_miss (also a placeholder for tlb_miss_common) */ +VECTOR(MIPSX(xtlb_miss), unknown) + lui k0, %hi(_C_LABEL(panic)) #00 + addiu k0, %lo(_C_LABEL(panic)) #01 + lui a0, %hi(loongson2_xtlb_miss_str) #02 + jr k0 #03 + addiu a0, %lo(loongson2_xtlb_miss_str) #04 +#else /* !MIPS3_LOONGSON2 */ VECTOR(MIPSX(tlb_miss), unknown) .set noat #ifdef MIPS3_LOONGSON2 @@ -343,6 +389,7 @@ VECTOR(MIPSX(tlb_miss), unknown) bltz k0, MIPSX(kernelfault) #02: k0<0 -> 4f (kernel fault) PTR_SRL k0, 1*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2)#03: k0=seg offset (almost) PTR_L k1, %lo(CPUVAR(PMAP_SEG0TAB))(k1)#04: k1=seg0tab +#endif /* !MIPS3_LOONGSON2 */ MIPSX(tlb_miss_common): #ifdef _LP64 beqz k1, MIPSX(nopagetable) #05: is there a pagetable? @@ -380,8 +427,13 @@ MIPSX(tlb_miss_common): #endif eret #1f: return from exception .set at +#ifdef MIPS3_LOONGSON2 +_VECTOR_END(MIPSX(xtlb_miss)) +#else _VECTOR_END(MIPSX(tlb_miss)) +#endif +#ifndef MIPS3_LOONGSON2 #if defined(USE_64BIT_CP0_FUNCTIONS) /* * mipsN_xtlb_miss routine @@ -397,6 +449,9 @@ _VECTOR_END(MIPSX(tlb_miss)) * * Don't check for invalid pte's here. We load them as well and * let the processor trap to load the correct value after service. + * + * Loongson2 CPUs don't have separate tlbmiss and xtlbmiss, so we have + * to check the address size here and branch to tlb_miss if needed. */ VECTOR(MIPSX(xtlb_miss), unknown) .set noat @@ -429,6 +484,7 @@ _VECTOR_END(MIPSX(xtlb_miss)) #else .space 128 #endif /* USE_64BIT_CP0_FUNCTIONS */ +#endif /* !MIPS3_LOONGSON2 */ /* * Vector to real handler in KSEG1. @@ -1431,6 +1487,7 @@ NESTED_NOPROFILE(MIPSX(systemcall), CALLFRAME_SIZ, ra) /* * Call the system call handler. */ + .set at jalr t9 move a0, MIPS_CURLWP # 1st arg is curlwp @@ -1446,7 +1503,6 @@ NESTED_NOPROFILE(MIPSX(systemcall), CALLFRAME_SIZ, ra) lui ra, %hi(MIPSX(user_return)) # return directly to user return j _C_LABEL(ast) PTR_ADDIU ra, %lo(MIPSX(user_return)) # return directly to user return - .set at END(MIPSX(systemcall)) /* @@ -1716,6 +1772,8 @@ END(MIPSX(tlb_invalid_exception)) .globl _C_LABEL(MIPSX(exceptionentry_end)) _C_LABEL(MIPSX(exceptionentry_end)): + .set at + /*-------------------------------------------------------------------------- * * mipsN_tlb_set_asid -- @@ -1784,8 +1842,8 @@ LEAF(MIPSX(tlb_update)) tlbwi # update slot found COP0_SYNC #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR - mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB + li t1, MIPS_DIAG_ITLB_CLEAR + mtc0 t1, MIPS_COP_0_DIAG # invalidate ITLB #elif defined(MIPS3) nop # required for QED5230 nop # required for QED5230 @@ -1806,8 +1864,8 @@ LEAF(MIPSX(tlb_update)) tlbwi # update slot found COP0_SYNC #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR - mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB + li t1, MIPS_DIAG_ITLB_CLEAR + mtc0 t1, MIPS_COP_0_DIAG # invalidate ITLB #elif defined(MIPS3) nop # required for QED5230 nop # required for QED5230 @@ -1927,7 +1985,7 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_addr)) tlbwi COP0_SYNC #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR + li v0, MIPS_DIAG_ITLB_CLEAR mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB #elif defined(MIPS3) nop @@ -1997,7 +2055,7 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_asids)) COP0_SYNC #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR + li v0, MIPS_DIAG_ITLB_CLEAR mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB #endif @@ -2052,7 +2110,7 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_globals)) COP0_SYNC #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR + li v0, MIPS_DIAG_ITLB_CLEAR mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB #endif @@ -2100,7 +2158,7 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_all)) COP0_SYNC #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR + li v0, MIPS_DIAG_ITLB_CLEAR mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB #endif @@ -2261,14 +2319,12 @@ LEAF(MIPSX(tlb_enter)) COP0_SYNC _MTC0 ta1, MIPS_COP_0_TLB_HI # restore EntryHi - #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR + li v0, MIPS_DIAG_ITLB_CLEAR mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB #endif - - JR_HB_RA .set at + JR_HB_RA END(MIPSX(tlb_enter)) /* @@ -2502,7 +2558,7 @@ LEAF(MIPSX(tlb_write_indexed)) COP0_SYNC #ifdef MIPS3_LOONGSON2 - li k0, MIPS_DIAG_ITLB_CLEAR + li v0, MIPS_DIAG_ITLB_CLEAR mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB #endif @@ -2539,12 +2595,12 @@ LEAF_NOPROFILE(MIPSX(VCED)) cache (CACHE_R4K_D | CACHEOP_R4K_HIT_INV), 0(k0) #ifdef DEBUG _MFC0 k0, MIPS_COP_0_BAD_VADDR - PTR_LA k1, VCED_vaddr + PTR_LA k1, MIPSX(VCED_vaddr) PTR_S k0, 0(k1) _MFC0 k0, MIPS_COP_0_EXC_PC - PTR_LA k1, VCED_epc + PTR_LA k1, MIPSX(VCED_epc) PTR_S k0, 0(k1) - PTR_LA k1, VCED_count # count number of exceptions + PTR_LA k1, MIPSX(VCED_count) # count number of exceptions PTR_SRL k0, k0, 26 # position upper 4 bits of VA and k0, k0, 0x3c # mask it off PTR_ADDU k1, k0 # get address of count table @@ -2557,14 +2613,14 @@ LEAF_NOPROFILE(MIPSX(VCED)) #ifdef DEBUG .data - .globl _C_LABEL(VCED_count) -_C_LABEL(VCED_count): + .globl _C_LABEL(MIPSX(VCED_count)) +_C_LABEL(MIPSX(VCED_count)): LONG_WORD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - .globl _C_LABEL(VCED_epc) -_C_LABEL(VCED_epc): + .globl _C_LABEL(MIPSX(VCED_epc)) +_C_LABEL(MIPSX(VCED_epc)): PTR_WORD 0 - .globl _C_LABEL(VCED_vaddr) -_C_LABEL(VCED_vaddr): + .globl _C_LABEL(MIPSX(VCED_vaddr)) +_C_LABEL(MIPSX(VCED_vaddr)): PTR_WORD 0 .text #endif @@ -2577,9 +2633,9 @@ LEAF_NOPROFILE(MIPSX(VCEI)) cache (CACHE_R4K_I | CACHEOP_R4K_HIT_INV), 0(k0) #ifdef DEBUG _MFC0 k0, MIPS_COP_0_BAD_VADDR - PTR_LA k1, VCEI_vaddr + PTR_LA k1, MIPSX(VCEI_vaddr) PTR_S k0, 0(k1) - PTR_LA k1, VCEI_count # count number of exceptions + PTR_LA k1, MIPSX(VCEI_count) # count number of exceptions PTR_SRL k0, k0, 26 # position upper 4 bits of VA and k0, k0, 0x3c # mask it off PTR_ADDU k1, k0 # get address of count table @@ -2592,11 +2648,11 @@ LEAF_NOPROFILE(MIPSX(VCEI)) #ifdef DEBUG .data - .globl _C_LABEL(VCEI_count) -_C_LABEL(VCEI_count): + .globl _C_LABEL(MIPSX(VCEI_count)) +_C_LABEL(MIPSX(VCEI_count)): LONG_WORD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - .globl _C_LABEL(VCEI_vaddr) -_C_LABEL(VCEI_vaddr): + .globl _C_LABEL(MIPSX(VCEI_vaddr)) +_C_LABEL(MIPSX(VCEI_vaddr)): PTR_WORD 0 .text #endif @@ -2740,3 +2796,7 @@ MIPSX(excpt_sw): #else PTR_WORD _C_LABEL(MIPSX(user_gen_exception)) # 31 #endif +#ifdef MIPS3_LOONGSON2 +loongson2_xtlb_miss_str: + .string "loongson2_xtlb_miss" +#endif diff --git a/sys/arch/mips/mips/mips_fixup.c b/sys/arch/mips/mips/mips_fixup.c index 0da94e627f8b..8bd88f10b056 100644 --- a/sys/arch/mips/mips/mips_fixup.c +++ b/sys/arch/mips/mips/mips_fixup.c @@ -1,4 +1,4 @@ -/* $NetBSD: mips_fixup.c,v 1.8 2011/08/24 15:11:52 matt Exp $ */ +/* $NetBSD: mips_fixup.c,v 1.9 2011/08/27 13:23:52 bouyer Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mips_fixup.c,v 1.8 2011/08/24 15:11:52 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mips_fixup.c,v 1.9 2011/08/27 13:23:52 bouyer Exp $"); #include "opt_mips3_wired.h" #include "opt_multiprocessor.h" @@ -239,7 +239,7 @@ mips_fixup_addr(const uint32_t *stubp) * jr t9 * nop * - * Or for loongson2: + * Or for loongson2 ( * lui v0, %hi(sym) * lX t9, %lo(sym)(v0) * lui at,0xcfff @@ -247,9 +247,16 @@ mips_fixup_addr(const uint32_t *stubp) * 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 = 0; + uint32_t used = 1; size_t n; const char *errstr = "mips"; /* @@ -293,6 +300,23 @@ mips_fixup_addr(const uint32_t *stubp) 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: