From 30893a910216b2e239aef6a391f370f6e7fdd595 Mon Sep 17 00:00:00 2001 From: matt Date: Sun, 31 Jul 2011 15:39:28 +0000 Subject: [PATCH] Add support for a loongson2_subr.S. This is needed since that chip needs special handling to manually flush the ITLB on TLB updates. --- sys/arch/mips/conf/files.mips | 5 +- sys/arch/mips/mips/locore_mips3.S | 3 +- sys/arch/mips/mips/loongson2_subr.S | 15 ++++++ sys/arch/mips/mips/mips32_subr.S | 3 +- sys/arch/mips/mips/mips32r2_subr.S | 3 +- sys/arch/mips/mips/mips3_subr.S | 3 +- sys/arch/mips/mips/mips64_subr.S | 3 +- sys/arch/mips/mips/mips64r2_subr.S | 3 +- sys/arch/mips/mips/mipsX_subr.S | 61 ++++++++++++++++++++--- sys/arch/mips/mips/mips_machdep.c | 77 ++++++++++++++++++++++++++--- 10 files changed, 154 insertions(+), 22 deletions(-) create mode 100644 sys/arch/mips/mips/loongson2_subr.S diff --git a/sys/arch/mips/conf/files.mips b/sys/arch/mips/conf/files.mips index 4a50612e889b..d1c359941e0d 100644 --- a/sys/arch/mips/conf/files.mips +++ b/sys/arch/mips/conf/files.mips @@ -1,13 +1,13 @@ -# $NetBSD: files.mips,v 1.70 2011/06/12 03:35:43 rmind Exp $ +# $NetBSD: files.mips,v 1.71 2011/07/31 15:39:28 matt Exp $ # defflag opt_cputype.h NOFPU FPEMUL MIPS64_SB1 - MIPS3_LOONGSON2F ENABLE_MIPS_16KB_PAGE MIPS64_XLP MIPS64_XLR MIPS64_XLS # and the rest... # MIPS1 MIPS2 MIPS3 MIPS4 MIPS5 + # MIPS3_LOONGSON2 # MIPS32 MIPS32R2 MIPS64 MIPS64R2 # MIPS3_4100 # ENABLE_MIPS_4KB_PAGE @@ -27,6 +27,7 @@ file arch/mips/mips/mips32_subr.S mips32 file arch/mips/mips/mips32r2_subr.S mips32r2 file arch/mips/mips/mips64_subr.S mips64 file arch/mips/mips/mips64r2_subr.S mips64r2 +file arch/mips/mips/loongson2_subr.S mips3_loongson2 file arch/mips/mips/sigcode.S file arch/mips/mips/copy.S file arch/mips/mips/lock_stubs_llsc.S multiprocessor diff --git a/sys/arch/mips/mips/locore_mips3.S b/sys/arch/mips/mips/locore_mips3.S index 62374940c5d4..6c7ec24635af 100644 --- a/sys/arch/mips/mips/locore_mips3.S +++ b/sys/arch/mips/mips/locore_mips3.S @@ -1,4 +1,4 @@ -/* $NetBSD: locore_mips3.S,v 1.100 2011/07/10 23:21:59 matt Exp $ */ +/* $NetBSD: locore_mips3.S,v 1.101 2011/07/31 15:39:29 matt Exp $ */ /* * Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author) @@ -151,6 +151,7 @@ *---------------------------------------------------------------------------- */ LEAF(mips3_wbflush) +XLEAF(loongson2_wbflush) XLEAF(mips32_wbflush) XLEAF(mips32r2_wbflush) XLEAF(mips64_wbflush) diff --git a/sys/arch/mips/mips/loongson2_subr.S b/sys/arch/mips/mips/loongson2_subr.S new file mode 100644 index 000000000000..fed20277670e --- /dev/null +++ b/sys/arch/mips/mips/loongson2_subr.S @@ -0,0 +1,15 @@ +/* $NetBSD: loongson2_subr.S,v 1.1 2011/07/31 15:39:29 matt Exp $ */ + +#undef MIPS1 +/* #undef MIPS3 */ +/* #undef MIPS3_LOONGSON2 */ +#undef MIPS32 +#undef MIPS32R2 +#undef MIPS64 +#undef MIPS64R2 +#undef MIPS64_SB1 +#undef MIPS64_XLP +#undef MIPS64_XLR +#undef MIPS64_XLS + +#include diff --git a/sys/arch/mips/mips/mips32_subr.S b/sys/arch/mips/mips/mips32_subr.S index 22e9342c90fb..a1838ea7ba5f 100644 --- a/sys/arch/mips/mips/mips32_subr.S +++ b/sys/arch/mips/mips/mips32_subr.S @@ -1,7 +1,8 @@ -/* $NetBSD: mips32_subr.S,v 1.5 2011/03/15 07:39:22 matt Exp $ */ +/* $NetBSD: mips32_subr.S,v 1.6 2011/07/31 15:39:29 matt Exp $ */ #undef MIPS1 #undef MIPS3 +#undef MIPS3_LOONGSON2 /* #undef MIPS32 */ #undef MIPS32R2 #undef MIPS64 diff --git a/sys/arch/mips/mips/mips32r2_subr.S b/sys/arch/mips/mips/mips32r2_subr.S index c45f8d719fad..757e621b7e1e 100644 --- a/sys/arch/mips/mips/mips32r2_subr.S +++ b/sys/arch/mips/mips/mips32r2_subr.S @@ -1,7 +1,8 @@ -/* $NetBSD: mips32r2_subr.S,v 1.1 2011/03/15 07:39:22 matt Exp $ */ +/* $NetBSD: mips32r2_subr.S,v 1.2 2011/07/31 15:39:29 matt Exp $ */ #undef MIPS1 #undef MIPS3 +#undef MIPS3_LOONGSON2 #undef MIPS32 /* #undef MIPS32R2 */ #undef MIPS64 diff --git a/sys/arch/mips/mips/mips3_subr.S b/sys/arch/mips/mips/mips3_subr.S index 1d1084380ea1..2c927d317de3 100644 --- a/sys/arch/mips/mips/mips3_subr.S +++ b/sys/arch/mips/mips/mips3_subr.S @@ -1,7 +1,8 @@ -/* $NetBSD: mips3_subr.S,v 1.5 2011/03/15 07:39:22 matt Exp $ */ +/* $NetBSD: mips3_subr.S,v 1.6 2011/07/31 15:39:29 matt Exp $ */ #undef MIPS1 /* #undef MIPS3 */ +#undef MIPS3_LOONGSON2 #undef MIPS32 #undef MIPS32R2 #undef MIPS64 diff --git a/sys/arch/mips/mips/mips64_subr.S b/sys/arch/mips/mips/mips64_subr.S index 17dd892de835..09f9254bfc6f 100644 --- a/sys/arch/mips/mips/mips64_subr.S +++ b/sys/arch/mips/mips/mips64_subr.S @@ -1,7 +1,8 @@ -/* $NetBSD: mips64_subr.S,v 1.5 2011/03/15 07:39:22 matt Exp $ */ +/* $NetBSD: mips64_subr.S,v 1.6 2011/07/31 15:39:29 matt Exp $ */ #undef MIPS1 #undef MIPS3 +#undef MIPS3_LOONGSON2 #undef MIPS32 #undef MIPS32R2 /* #undef MIPS64 */ diff --git a/sys/arch/mips/mips/mips64r2_subr.S b/sys/arch/mips/mips/mips64r2_subr.S index a7664f56a4ae..93fd54760244 100644 --- a/sys/arch/mips/mips/mips64r2_subr.S +++ b/sys/arch/mips/mips/mips64r2_subr.S @@ -1,7 +1,8 @@ -/* $NetBSD: mips64r2_subr.S,v 1.1 2011/03/15 07:39:22 matt Exp $ */ +/* $NetBSD: mips64r2_subr.S,v 1.2 2011/07/31 15:39:29 matt Exp $ */ #undef MIPS1 #undef MIPS3 +#undef MIPS3_LOONGSON2 #undef MIPS32 #undef MIPS32R2 #undef MIPS64 diff --git a/sys/arch/mips/mips/mipsX_subr.S b/sys/arch/mips/mips/mipsX_subr.S index f5b765b74004..ff2d4c753610 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.50 2011/07/10 23:21:59 matt Exp $ */ +/* $NetBSD: mipsX_subr.S,v 1.51 2011/07/31 15:39:29 matt Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -228,7 +228,9 @@ * CPP function renaming macros. */ -#if defined(MIPS3) +#if defined(MIPS3_LOONGSON2) +#define MIPSX(name) __CONCAT(loongson2_,name) +#elif defined(MIPS3) #define MIPSX(name) __CONCAT(mips3_,name) #endif @@ -1639,7 +1641,10 @@ LEAF_NOPROFILE(MIPSX(tlb_invalid_exception)) #endif tlbwi # write TLB COP0_SYNC -#ifdef MIPS3 +#ifdef MIPS3_LOONGSON2 + li k0, 4 # ugly + mtc0 k0, MIPS_COP_0_DIAG # invalidate ITLB +#elif defined(MIPS3) nop nop #endif @@ -1671,7 +1676,10 @@ MIPSX(kern_tlbi_odd): #endif tlbwi # update TLB COP0_SYNC -#ifdef MIPS3 +#ifdef MIPS3_LOONGSON2 + li k0, 4 # ugly + mtc0 k0, MIPS_COP_0_DIAG # invalidate ITLB +#elif defined(MIPS3) nop nop #endif @@ -1753,7 +1761,10 @@ LEAF(MIPSX(tlb_update)) COP0_SYNC tlbwi # update slot found COP0_SYNC -#ifdef MIPS3 +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#elif defined(MIPS3) nop # required for QED5230 nop # required for QED5230 #endif @@ -1772,7 +1783,10 @@ LEAF(MIPSX(tlb_update)) COP0_SYNC tlbwi # update slot found COP0_SYNC -#ifdef MIPS3 +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#elif defined(MIPS3) nop # required for QED5230 nop # required for QED5230 #endif @@ -1890,7 +1904,10 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_addr)) tlbwi COP0_SYNC -#ifdef MIPS3 +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#elif defined(MIPS3) nop nop #endif @@ -1956,6 +1973,12 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_asids)) _MFC0 t0, MIPS_COP_0_TLB_HI # restore PID. mtc0 t3, MIPS_COP_0_TLB_PG_MASK # restore pgMask COP0_SYNC + +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#endif + mtc0 v1, MIPS_COP_0_STATUS # restore status register JR_HB_RA # new ASID will be set soon END(MIPSX(tlb_invalidate_asids)) @@ -2005,6 +2028,12 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_globals)) _MTC0 t0, MIPS_COP_0_TLB_HI # restore current ASID mtc0 t3, MIPS_COP_0_TLB_PG_MASK # restore pgMask COP0_SYNC + +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#endif + mtc0 v1, MIPS_COP_0_STATUS # restore status register JR_HB_RA END(MIPSX(tlb_invalidate_globals)) @@ -2047,6 +2076,12 @@ LEAF_NOPROFILE(MIPSX(tlb_invalidate_all)) _MTC0 t0, MIPS_COP_0_TLB_HI # restore ASID mtc0 t2, MIPS_COP_0_TLB_PG_MASK # restore pgMask COP0_SYNC + +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#endif + mtc0 v1, MIPS_COP_0_STATUS # restore status register JR_HB_RA END(MIPSX(tlb_invalidate_all)) @@ -2204,6 +2239,12 @@ LEAF(MIPSX(tlb_enter)) COP0_SYNC _MTC0 ta1, MIPS_COP_0_TLB_HI # restore EntryHi + +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#endif + JR_HB_RA .set at END(MIPSX(tlb_enter)) @@ -2432,6 +2473,12 @@ LEAF(MIPSX(tlb_write_indexed)) _MTC0 t0, MIPS_COP_0_TLB_HI # Restore the PID. mtc0 v0, MIPS_COP_0_TLB_PG_MASK # Restore page mask. COP0_SYNC + +#ifdef MIPS3_LOONGSON2 + li v0, 4 # ugly + mtc0 v0, MIPS_COP_0_DIAG # invalidate ITLB +#endif + mtc0 v1, MIPS_COP_0_STATUS # Restore the status register JR_HB_RA END(MIPSX(tlb_write_indexed)) diff --git a/sys/arch/mips/mips/mips_machdep.c b/sys/arch/mips/mips/mips_machdep.c index edcf1d57cb2e..d02167abe807 100644 --- a/sys/arch/mips/mips/mips_machdep.c +++ b/sys/arch/mips/mips/mips_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: mips_machdep.c,v 1.244 2011/06/14 05:30:40 matt Exp $ */ +/* $NetBSD: mips_machdep.c,v 1.245 2011/07/31 15:39:29 matt Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -112,7 +112,7 @@ #include /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.244 2011/06/14 05:30:40 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.245 2011/07/31 15:39:29 matt Exp $"); #define __INTR_PRIVATE #include "opt_cputype.h" @@ -220,6 +220,12 @@ extern const struct locoresw mips3_locoresw; extern const mips_locore_jumpvec_t mips3_locore_vec; #endif +#if defined(MIPS3_LOONGSON2) +static void loongson2_vector_init(const struct splsw *); +extern const struct locoresw loongson2_locoresw; +extern const mips_locore_jumpvec_t loongson2_locore_vec; +#endif + #if defined(MIPS32) static void mips32_vector_init(const struct splsw *); extern const struct locoresw mips32_locoresw; @@ -432,11 +438,11 @@ static const struct pridtab cputab[] = { (2 << CPU_MIPS_CACHED_CCA_SHIFT)) #endif { 0, MIPS_LOONGSON2, MIPS_REV_LOONGSON2E, -1, CPU_ARCH_MIPS3, 64, - CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | MIPS_LOONGSON2_CCA, 0, 0, - "ICT Loongson 2E CPU" }, + CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | CPU_MIPS_LOONGSON2 + | MIPS_LOONGSON2_CCA, 0, 0, "ICT Loongson 2E CPU" }, { 0, MIPS_LOONGSON2, MIPS_REV_LOONGSON2F, -1, CPU_ARCH_MIPS3, 64, - CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | MIPS_LOONGSON2_CCA, 0, 0, - "ICT Loongson 2F CPU" }, + CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | CPU_MIPS_LOONGSON2 + | MIPS_LOONGSON2_CCA, 0, 0, "ICT Loongson 2F CPU" }, #if 0 /* ID collisions : can we use a CU1 test or similar? */ { 0, MIPS_R3SONY, -1, -1, CPU_ARCH_MIPS1, -1, @@ -479,6 +485,7 @@ static const struct pridtab cputab[] = { MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG7, 0, "34K" }, { MIPS_PRID_CID_MTI, MIPS_74K, -1, -1, -1, 0, + CPU_MIPS_HAVE_SPECIAL_CCA | (0 << CPU_MIPS_CACHED_CCA_SHIFT) | MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, MIPS_CP0FL_USE | MIPS_CP0FL_EBASE | MIPS_CP0FL_USERLOCAL | MIPS_CP0FL_HWRENA | @@ -742,6 +749,53 @@ mips3_vector_init(const struct splsw *splsw) } #endif /* MIPS3 */ +#if defined(MIPS3_LOONGSON2) +static void +loongson2_vector_init(const struct splsw *splsw) +{ + /* r4000 exception handler address and end */ + extern char loongson2_exception[], loongson2_exception_end[]; + + /* TLB miss handler address and end */ + extern char loongson2_tlb_miss[]; + extern char loongson2_xtlb_miss[]; + + /* Cache error handler */ + extern char loongson2_cache[]; + + /* + * Copy down exception vector code. + */ + + if (loongson2_xtlb_miss - loongson2_tlb_miss != 0x80) + panic("startup: %s vector code not 128 bytes in length", + "UTLB"); + if (loongson2_cache - loongson2_xtlb_miss != 0x80) + panic("startup: %s vector code not 128 bytes in length", + "XTLB"); + if (loongson2_exception - loongson2_cache != 0x80) + panic("startup: %s vector code not 128 bytes in length", + "Cache error"); + if (loongson2_exception_end - loongson2_exception > 0x80) + panic("startup: %s vector code too large", + "General exception"); + + memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, loongson2_tlb_miss, + loongson2_exception_end - loongson2_tlb_miss); + + /* + * Copy locore-function vector. + */ + mips_locore_jumpvec = loongson2_locore_vec; + + mips_icache_sync_all(); + mips_dcache_wbinv_all(); + + /* Clear BEV in SR so we start handling our own exceptions */ + mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV); +} +#endif /* MIPS3_LOONGSON2 */ + #if defined(MIPS32) static void mips32_vector_init(const struct splsw *splsw) @@ -1174,12 +1228,21 @@ mips_vector_init(const struct splsw *splsw, bool multicpu_p) #endif mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE)); mips3_cp0_wired_write(0); +#if defined(MIPS3_LOONGSON2) + if (opts->mips_cpu_flags & CPU_MIPS_LOONGSON2) { + (*loongson2_locore_vec.ljv_tlb_invalidate_all)(); + mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); + loongson2_vector_init(splsw); + mips_locoresw = loongson2_locoresw; + break; + } +#endif /* MIPS3_LOONGSON2 */ (*mips3_locore_vec.ljv_tlb_invalidate_all)(); mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); mips3_vector_init(splsw); mips_locoresw = mips3_locoresw; break; -#endif +#endif /* MIPS3 */ #if defined(MIPS32) case CPU_ARCH_MIPS32: mips3_tlb_probe();