mp_exception.S revision 166105
1/*- 2 * Copyright (c) 2002 Jake Burkholder. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <machine/asm.h> 28__FBSDID("$FreeBSD: head/sys/sparc64/sparc64/mp_exception.S 166105 2007-01-19 11:15:34Z marius $"); 29 30#include <machine/asi.h> 31#include <machine/asmacros.h> 32#include <machine/cache.h> 33#include <machine/ktr.h> 34#include <machine/pstate.h> 35 36#include "assym.s" 37 38 .register %g2, #ignore 39 .register %g3, #ignore 40 41#define IPI_DONE(r1, r2, r3, r4) \ 42 lduw [PCPU(CPUMASK)], r4 ; \ 43 ATOMIC_CLEAR_INT(r1, r2, r3, r4) 44 45/* 46 * Invalidate a physical page in the data cache. For UltraSPARC I and II. 47 */ 48ENTRY(tl_ipi_spitfire_dcache_page_inval) 49#if KTR_COMPILE & KTR_SMP 50 CATR(KTR_SMP, "ipi_dcache_page_inval: pa=%#lx" 51 , %g1, %g2, %g3, 7, 8, 9) 52 ldx [%g5 + ICA_PA], %g2 53 stx %g2, [%g1 + KTR_PARM1] 549: 55#endif 56 57 ldx [%g5 + ICA_PA], %g6 58 srlx %g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6 59 60 SET(cache, %g3, %g2) 61 lduw [%g2 + DC_SIZE], %g3 62 lduw [%g2 + DC_LINESIZE], %g4 63 sub %g3, %g4, %g2 64 651: ldxa [%g2] ASI_DCACHE_TAG, %g1 66 srlx %g1, DC_VALID_SHIFT, %g3 67 andcc %g3, DC_VALID_MASK, %g0 68 bz,pt %xcc, 2f 69 set DC_TAG_MASK, %g3 70 sllx %g3, DC_TAG_SHIFT, %g3 71 and %g1, %g3, %g1 72 cmp %g1, %g6 73 bne,a,pt %xcc, 2f 74 nop 75 stxa %g1, [%g2] ASI_DCACHE_TAG 76 membar #Sync 77 782: brgz,pt %g2, 1b 79 sub %g2, %g4, %g2 80 81 IPI_DONE(%g5, %g1, %g2, %g3) 82 retry 83END(tl_ipi_spitfire_dcache_page_inval) 84 85/* 86 * Invalidate a physical page in the instruction cache. For UltraSPARC I and 87 * II. 88 */ 89ENTRY(tl_ipi_spitfire_icache_page_inval) 90#if KTR_COMPILE & KTR_SMP 91 CATR(KTR_SMP, "ipi_icache_page_inval: pa=%#lx" 92 , %g1, %g2, %g3, 7, 8, 9) 93 ldx [%g5 + ICA_PA], %g2 94 stx %g2, [%g1 + KTR_PARM1] 959: 96#endif 97 98 ldx [%g5 + ICA_PA], %g6 99 srlx %g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6 100 101 SET(cache, %g3, %g2) 102 lduw [%g2 + IC_SIZE], %g3 103 lduw [%g2 + IC_LINESIZE], %g4 104 sub %g3, %g4, %g2 105 1061: ldda [%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */ 107 srlx %g1, IC_VALID_SHIFT, %g3 108 andcc %g3, IC_VALID_MASK, %g0 109 bz,pt %xcc, 2f 110 set IC_TAG_MASK, %g3 111 sllx %g3, IC_TAG_SHIFT, %g3 112 and %g1, %g3, %g1 113 cmp %g1, %g6 114 bne,a,pt %xcc, 2f 115 nop 116 stxa %g1, [%g2] ASI_ICACHE_TAG 117 membar #Sync 118 1192: brgz,pt %g2, 1b 120 sub %g2, %g4, %g2 121 122 IPI_DONE(%g5, %g1, %g2, %g3) 123 retry 124END(tl_ipi_spitfire_icache_page_inval) 125 126/* 127 * Invalidate a physical page in the data cache. For UltraSPARC III. 128 */ 129ENTRY(tl_ipi_cheetah_dcache_page_inval) 130#if KTR_COMPILE & KTR_SMP 131 CATR(KTR_SMP, "ipi_dcache_page_inval: pa=%#lx" 132 , %g1, %g2, %g3, 7, 8, 9) 133 ldx [%g5 + ICA_PA], %g2 134 stx %g2, [%g1 + KTR_PARM1] 1359: 136#endif 137 138 ldx [%g5 + ICA_PA], %g1 139 140 set PAGE_SIZE, %g2 141 add %g1, %g2, %g3 142 143 SET(cache, %g4, %g2) 144 lduw [%g2 + DC_LINESIZE], %g2 145 1461: stxa %g0, [%g1] ASI_DCACHE_INVALIDATE 147 membar #Sync 148 149 add %g1, %g2, %g1 150 cmp %g1, %g3 151 blt,a,pt %xcc, 1b 152 nop 153 154 IPI_DONE(%g5, %g1, %g2, %g3) 155 retry 156END(tl_ipi_cheetah_dcache_page_inval) 157 158/* 159 * Trigger a softint at the desired level. 160 */ 161ENTRY(tl_ipi_level) 162#if KTR_COMPILE & KTR_SMP 163 CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx" 164 , %g1, %g2, %g3, 7, 8, 9) 165 lduw [PCPU(CPUID)], %g2 166 stx %g2, [%g1 + KTR_PARM1] 167 lduw [PCPU(MID)], %g2 168 stx %g2, [%g1 + KTR_PARM2] 169 stx %g4, [%g1 + KTR_PARM3] 170 stx %g5, [%g1 + KTR_PARM4] 1719: 172#endif 173 174 mov 1, %g1 175 sllx %g1, %g5, %g1 176 wr %g1, 0, %set_softint 177 retry 178END(tl_ipi_level) 179 180/* 181 * Demap a page from the dtlb and/or itlb. 182 */ 183ENTRY(tl_ipi_tlb_page_demap) 184#if KTR_COMPILE & KTR_SMP 185 CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx" 186 , %g1, %g2, %g3, 7, 8, 9) 187 ldx [%g5 + ITA_PMAP], %g2 188 stx %g2, [%g1 + KTR_PARM1] 189 ldx [%g5 + ITA_VA], %g2 190 stx %g2, [%g1 + KTR_PARM2] 1919: 192#endif 193 194 ldx [%g5 + ITA_PMAP], %g1 195 196 SET(kernel_pmap_store, %g3, %g2) 197 mov TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3 198 199 cmp %g1, %g2 200 movne %xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3 201 202 ldx [%g5 + ITA_VA], %g2 203 or %g2, %g3, %g2 204 205 stxa %g0, [%g2] ASI_DMMU_DEMAP 206 stxa %g0, [%g2] ASI_IMMU_DEMAP 207 membar #Sync 208 209 IPI_DONE(%g5, %g1, %g2, %g3) 210 retry 211END(tl_ipi_tlb_page_demap) 212 213/* 214 * Demap a range of pages from the dtlb and itlb. 215 */ 216ENTRY(tl_ipi_tlb_range_demap) 217#if KTR_COMPILE & KTR_SMP 218 CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx" 219 , %g1, %g2, %g3, 7, 8, 9) 220 ldx [%g5 + ITA_PMAP], %g2 221 stx %g2, [%g1 + KTR_PARM1] 222 ldx [%g5 + ITA_START], %g2 223 stx %g2, [%g1 + KTR_PARM2] 224 ldx [%g5 + ITA_END], %g2 225 stx %g2, [%g1 + KTR_PARM3] 2269: 227#endif 228 229 ldx [%g5 + ITA_PMAP], %g1 230 231 SET(kernel_pmap_store, %g3, %g2) 232 mov TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3 233 234 cmp %g1, %g2 235 movne %xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3 236 237 ldx [%g5 + ITA_START], %g1 238 ldx [%g5 + ITA_END], %g2 239 240 set PAGE_SIZE, %g6 241 2421: or %g1, %g3, %g4 243 stxa %g0, [%g4] ASI_DMMU_DEMAP 244 stxa %g0, [%g4] ASI_IMMU_DEMAP 245 membar #Sync 246 247 add %g1, %g6, %g1 248 cmp %g1, %g2 249 blt,a,pt %xcc, 1b 250 nop 251 252 IPI_DONE(%g5, %g1, %g2, %g3) 253 retry 254END(tl_ipi_tlb_range_demap) 255 256/* 257 * Demap the primary context from the dtlb and itlb. 258 */ 259ENTRY(tl_ipi_tlb_context_demap) 260#if KTR_COMPILE & KTR_SMP 261 CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx" 262 , %g1, %g2, %g3, 7, 8, 9) 263 ldx [%g5 + ITA_PMAP], %g2 264 stx %g2, [%g1 + KTR_PARM1] 265 ldx [%g5 + ITA_VA], %g2 266 stx %g2, [%g1 + KTR_PARM2] 2679: 268#endif 269 270 mov TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1 271 stxa %g0, [%g1] ASI_DMMU_DEMAP 272 stxa %g0, [%g1] ASI_IMMU_DEMAP 273 membar #Sync 274 275 IPI_DONE(%g5, %g1, %g2, %g3) 276 retry 277END(tl_ipi_tlb_context_demap) 278