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:
parent
0c15c4be25
commit
4c44c335c5
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue