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)
This commit is contained in:
bouyer 2011-08-27 13:23:52 +00:00
parent 0c15c4be25
commit 4c44c335c5
11 changed files with 280 additions and 62 deletions

View File

@ -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 <machine/asm.h>
#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)

View File

@ -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 <machine/asm.h>
#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)

View File

@ -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 <machine/asm.h>
#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)

View File

@ -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 <machine/asm.h>
#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)

View File

@ -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)

View File

@ -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 <machine/asm.h>
#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)

View File

@ -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.

View File

@ -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 <mips/rmi/rmixlreg.h>
#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_ */

View File

@ -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:

View File

@ -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<<PTR_SCALESHIFT) #08: k0=seg offset (mask 0x3)
PTR_L k1, %lo(CPUVAR(PMAP_SEGTAB))(k1)#09: k1=segment tab
PTR_ADDU k1, k0 #0a: k1=seg entry address
dmfc0 k0, MIPS_COP_0_BAD_VADDR #0b: k0=bad address (again)
PTR_L k1, 0(k1) #0c: k1=seg entry
b MIPSX(tlb_miss_common) #0d
PTR_SRL k0, 1*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2) #0e: k0=seg offset (almost)
#endif /* LP64 */
1: /* handle useg addresses */
lui k1, %hi(CPUVAR(PMAP_SEG0TAB)) #0f: k1=hi of seg0tab
bltz k0, MIPSX(kernelfault) #10: k0<0 -> 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

View File

@ -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 <sys/cdefs.h>
__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: