1 /* SPDX-License-Identifier: GPL-2.0-or-later * !! 1 /* $Id: entry.S,v 1.144 2002/02/09 19:49:30 davem Exp $ 2 /* !! 2 * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. 3 * Linux/PA-RISC Project (http://www.parisc-li << 4 * 3 * 5 * kernel entry points (interruptions, system !! 4 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) 6 * Copyright (C) 1999,2000 Philipp Rumpf !! 5 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) 7 * Copyright (C) 1999 SuSE GmbH Nuernberg !! 6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 8 * Copyright (C) 2000 Hewlett-Packard (John M !! 7 * Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 9 * Copyright (C) 1999 Hewlett-Packard (Frank << 10 */ 8 */ 11 9 12 #include <asm/asm-offsets.h> !! 10 #include <linux/config.h> 13 !! 11 #include <linux/errno.h> 14 /* we have the following possibilities to act << 15 * - handle in assembly and use shadowed regi << 16 * - save registers to kernel stack and handl << 17 12 18 !! 13 #include <asm/head.h> 19 #include <asm/psw.h> !! 14 #include <asm/asi.h> 20 #include <asm/cache.h> /* for L1_CACH !! 15 #include <asm/smp.h> 21 #include <asm/assembly.h> /* for LDREG/S !! 16 #include <asm/ptrace.h> >> 17 #include <asm/page.h> 22 #include <asm/signal.h> 18 #include <asm/signal.h> 23 #include <asm/unistd.h> !! 19 #include <asm/pgtable.h> 24 #include <asm/ldcw.h> !! 20 #include <asm/processor.h> 25 #include <asm/traps.h> !! 21 #include <asm/visasm.h> 26 #include <asm/thread_info.h> !! 22 #include <asm/estate.h> 27 #include <asm/alternative.h> !! 23 #include <asm/auxio.h> 28 #include <asm/spinlock_types.h> << 29 << 30 #include <linux/linkage.h> << 31 #include <linux/pgtable.h> << 32 << 33 #ifdef CONFIG_64BIT << 34 .level 2.0w << 35 #else << 36 .level 2.0 << 37 #endif << 38 << 39 /* << 40 * We need seven instructions after a TLB inse << 41 * The PA8800/PA8900 processors are an excepti << 42 * The RFI changes both IAOQ_Back and IAOQ_Fro << 43 */ << 44 #ifdef CONFIG_64BIT << 45 #define NUM_PIPELINE_INSNS 12 << 46 #else << 47 #define NUM_PIPELINE_INSNS 7 << 48 #endif << 49 << 50 /* Insert num nops */ << 51 .macro insert_nops num << 52 .rept \num << 53 nop << 54 .endr << 55 .endm << 56 << 57 /* Get aligned page_table_lock address << 58 .macro get_ptl reg << 59 mfctl %cr28,\reg << 60 .endm << 61 << 62 /* space_to_prot macro creates a prot << 63 << 64 #if (SPACEID_SHIFT) == 0 << 65 .macro space_to_prot spc prot << 66 depd,z \spc,62,31,\prot << 67 .endm << 68 #else << 69 .macro space_to_prot spc prot << 70 extrd,u \spc,(64 - (SPACEID_SHIFT)),32 << 71 .endm << 72 #endif << 73 /* << 74 * The "get_stack" macros are responsi << 75 * kernel stack value. << 76 * << 77 * If sr7 == 0 << 78 * Already using a kernel sta << 79 * get_stack_use_r30 macro to << 80 * on the stack, and store re << 81 * else << 82 * Need to set up a kernel st << 83 * get_stack_use_cr30 macro t << 84 * to the pt_regs structure c << 85 * task pointer pointed to by << 86 * pointer from the task stru << 87 * << 88 * Note that we use shadowed registers << 89 * we can save %r26 and %r29. %r26 is << 90 * %r8 (a shadowed register) which tem << 91 * either the fault type ("code") or t << 92 * to use a non-shadowed register to c << 93 * the rfir in virt_map. We use %r26 s << 94 * up being passed as the argument to << 95 * or handle_interruption. %r29 is use << 96 * the register save area, and once ag << 97 * be a non-shadowed register so that << 98 */ << 99 << 100 .macro get_stack_use_cr30 << 101 << 102 /* we save the registers in the task s << 103 << 104 copy %r30, %r17 << 105 mfctl %cr30, %r1 << 106 tophys %r1,%r9 /* task_struct << 107 LDREG TASK_STACK(%r9),%r30 << 108 ldo PT_SZ_ALGN(%r30),%r30 << 109 mtsp %r0,%sr7 /* clear sr7 a << 110 mtsp %r16,%sr3 << 111 ldo TASK_REGS(%r9),%r9 << 112 STREG %r17,PT_GR30(%r9) << 113 STREG %r29,PT_GR29(%r9) << 114 STREG %r26,PT_GR26(%r9) << 115 STREG %r16,PT_SR7(%r9) << 116 copy %r9,%r29 << 117 .endm << 118 << 119 .macro get_stack_use_r30 << 120 << 121 /* we put a struct pt_regs on the stac << 122 << 123 tophys %r30,%r9 << 124 copy %r30,%r1 << 125 ldo PT_SZ_ALGN(%r30),%r30 << 126 STREG %r1,PT_GR30(%r9) << 127 STREG %r29,PT_GR29(%r9) << 128 STREG %r26,PT_GR26(%r9) << 129 STREG %r16,PT_SR7(%r9) << 130 copy %r9,%r29 << 131 .endm << 132 << 133 .macro rest_stack << 134 LDREG PT_GR1(%r29), %r1 << 135 LDREG PT_GR30(%r29),%r30 << 136 LDREG PT_GR29(%r29),%r29 << 137 .endm << 138 << 139 /* default interruption handler << 140 * (calls traps.c:handle_interruption) << 141 .macro def code << 142 b intr_save << 143 ldi \code, %r8 << 144 .align 32 << 145 .endm << 146 << 147 /* Interrupt interruption handler << 148 * (calls irq.c:do_cpu_irq_mask) */ << 149 .macro extint code << 150 b intr_extint << 151 mfsp %sr7,%r16 << 152 .align 32 << 153 .endm << 154 24 155 .import os_hpmc, code !! 25 /* #define SYSCALL_TRACING 1 */ 156 26 157 /* HPMC handler */ !! 27 #define curptr g6 158 .macro hpmc code << 159 nop /* must be a N << 160 load32 PA(os_hpmc), %r3 << 161 bv,n 0(%r3) << 162 nop << 163 .word 0 /* checksum (w << 164 .word 0 /* address of << 165 .word 0 /* length of h << 166 .endm << 167 << 168 /* << 169 * Performance Note: Instructions will << 170 * this part of the code later on, onc << 171 * that the tlb miss handlers are clos << 172 */ << 173 << 174 /* Register definitions for tlb miss h << 175 << 176 va = r8 /* virtual address for << 177 spc = r24 /* space for which the << 178 << 179 #ifndef CONFIG_64BIT << 180 << 181 /* << 182 * itlb miss interruption handler (par << 183 */ << 184 28 185 .macro itlb_11 code !! 29 #define NR_SYSCALLS 272 /* Each OS is different... */ 186 << 187 mfctl %pcsq, spc << 188 b itlb_miss_11 << 189 mfctl %pcoq, va << 190 << 191 .align 32 << 192 .endm << 193 #endif << 194 << 195 /* << 196 * itlb miss interruption handler (par << 197 */ << 198 << 199 .macro itlb_20 code << 200 mfctl %pcsq, spc << 201 #ifdef CONFIG_64BIT << 202 b itlb_miss_20w << 203 #else << 204 b itlb_miss_20 << 205 #endif << 206 mfctl %pcoq, va << 207 30 >> 31 .text 208 .align 32 32 .align 32 209 .endm << 210 << 211 #ifndef CONFIG_64BIT << 212 /* << 213 * naitlb miss interruption handler (p << 214 */ << 215 << 216 .macro naitlb_11 code << 217 33 218 mfctl %isr,spc !! 34 .globl sparc64_vpte_patchme1 219 b naitlb_miss_11 !! 35 .globl sparc64_vpte_patchme2 220 mfctl %ior,va !! 36 /* 221 !! 37 * On a second level vpte miss, check whether the original fault is to the OBP 222 .align 32 !! 38 * range (note that this is only possible for instruction miss, data misses to 223 .endm !! 39 * obp range do not use vpte). If so, go back directly to the faulting address. 224 #endif !! 40 * This is because we want to read the tpc, otherwise we have no way of knowing 225 !! 41 * the 8k aligned faulting address if we are using >8k kernel pagesize. This also 226 /* !! 42 * ensures no vpte range addresses are dropped into tlb while obp is executing 227 * naitlb miss interruption handler (p !! 43 * (see inherit_locked_prom_mappings() rant). 228 */ !! 44 */ 229 !! 45 sparc64_vpte_nucleus: 230 .macro naitlb_20 code !! 46 mov 0xf, %g5 231 !! 47 sllx %g5, 28, %g5 ! Load 0xf0000000 232 mfctl %isr,spc !! 48 cmp %g4, %g5 ! Is addr >= LOW_OBP_ADDRESS? 233 #ifdef CONFIG_64BIT !! 49 blu,pn %xcc, sparc64_vpte_patchme1 234 b naitlb_miss_20w !! 50 mov 0x1, %g5 235 #else !! 51 sllx %g5, 32, %g5 ! Load 0x100000000 236 b naitlb_miss_20 !! 52 cmp %g4, %g5 ! Is addr < HI_OBP_ADDRESS? 237 #endif !! 53 blu,pn %xcc, obp_iaddr_patch 238 mfctl %ior,va !! 54 nop 239 !! 55 sparc64_vpte_patchme1: 240 .align 32 !! 56 sethi %hi(0), %g5 ! This has to be patched 241 .endm !! 57 sparc64_vpte_patchme2: 242 !! 58 or %g5, %lo(0), %g5 ! This is patched too 243 #ifndef CONFIG_64BIT !! 59 ba,pt %xcc, sparc64_kpte_continue ! Part of dtlb_backend 244 /* !! 60 add %g1, %g1, %g1 ! Finish PMD offset adjustment 245 * dtlb miss interruption handler (par !! 61 246 */ !! 62 vpte_noent: 247 !! 63 mov TLB_SFSR, %g1 ! Restore %g1 value 248 .macro dtlb_11 code !! 64 stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS 249 !! 65 done ! Slick trick 250 mfctl %isr, spc !! 66 251 b dtlb_miss_11 !! 67 .globl obp_iaddr_patch 252 mfctl %ior, va !! 68 .globl obp_daddr_patch 253 !! 69 254 .align 32 !! 70 obp_iaddr_patch: 255 .endm !! 71 sethi %hi(0), %g5 ! This and following is patched 256 #endif !! 72 or %g5, %lo(0), %g5 ! g5 now holds obp pmd base physaddr 257 !! 73 wrpr %g0, 1, %tl ! Behave as if we are at TL0 258 /* !! 74 rdpr %tpc, %g4 ! Find original faulting iaddr 259 * dtlb miss interruption handler (par !! 75 srlx %g4, 13, %g4 ! Throw out context bits 260 */ !! 76 sllx %g4, 13, %g4 ! g4 has vpn + ctx0 now 261 !! 77 mov TLB_SFSR, %g1 ! Restore %g1 value 262 .macro dtlb_20 code !! 78 stxa %g4, [%g1 + %g1] ASI_IMMU ! Restore previous TAG_ACCESS 263 !! 79 srlx %g4, 23, %g6 ! Find pmd number 264 mfctl %isr, spc !! 80 and %g6, 0x7ff, %g6 ! Find pmd number 265 #ifdef CONFIG_64BIT !! 81 sllx %g6, 2, %g6 ! Find pmd offset 266 b dtlb_miss_20w !! 82 lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pmd, ie pagetable physaddr 267 #else !! 83 brz,pn %g5, longpath ! Kill the PROM ? :-) 268 b dtlb_miss_20 !! 84 sllx %g5, 11, %g5 ! Shift into place 269 #endif !! 85 srlx %g4, 13, %g6 ! find pte number in pagetable 270 mfctl %ior, va !! 86 and %g6, 0x3ff, %g6 ! find pte number in pagetable 271 !! 87 sllx %g6, 3, %g6 ! find pte offset in pagetable 272 .align 32 !! 88 ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pte 273 .endm !! 89 brgez,pn %g5, longpath ! Kill the PROM ? :-) 274 !! 90 nop 275 #ifndef CONFIG_64BIT !! 91 stxa %g5, [%g0] ASI_ITLB_DATA_IN ! put into tlb 276 /* nadtlb miss interruption handler (p !! 92 retry ! go back to original fault 277 !! 93 278 .macro nadtlb_11 code !! 94 obp_daddr_patch: 279 !! 95 sethi %hi(0), %g5 ! This and following is patched 280 mfctl %isr,spc !! 96 or %g5, %lo(0), %g5 ! g5 now holds obp pmd base physaddr 281 b nadtlb_miss_11 !! 97 srlx %g4, 23, %g6 ! Find pmd number 282 mfctl %ior,va !! 98 and %g6, 0x7ff, %g6 ! Find pmd number 283 !! 99 sllx %g6, 2, %g6 ! Find pmd offset 284 .align 32 !! 100 lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pmd, ie pagetable physaddr 285 .endm !! 101 brz,pn %g5, longpath 286 #endif !! 102 sllx %g5, 11, %g5 ! Shift into place 287 !! 103 srlx %g4, 13, %g6 ! find pte number in pagetable 288 /* nadtlb miss interruption handler (p !! 104 and %g6, 0x3ff, %g6 ! find pte number in pagetable 289 !! 105 sllx %g6, 3, %g6 ! find pte offset in pagetable 290 .macro nadtlb_20 code !! 106 ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pte >> 107 brgez,pn %g5, longpath >> 108 nop >> 109 stxa %g5, [%g0] ASI_DTLB_DATA_IN ! put into tlb >> 110 retry 291 111 292 mfctl %isr,spc !! 112 /* 293 #ifdef CONFIG_64BIT !! 113 * On a first level data miss, check whether this is to the OBP range (note that 294 b nadtlb_miss_20w !! 114 * such accesses can be made by prom, as well as by kernel using prom_getproperty 295 #else !! 115 * on "address"), and if so, do not use vpte access ... rather, use information 296 b nadtlb_miss_20 !! 116 * saved during inherit_prom_mappings() using 8k pagesize. 297 #endif !! 117 */ 298 mfctl %ior,va !! 118 kvmap: >> 119 mov 0xf, %g5 >> 120 sllx %g5, 28, %g5 ! Load 0xf0000000 >> 121 cmp %g4, %g5 ! Is addr >= LOW_OBP_ADDRESS? >> 122 blu,pn %xcc, vmalloc_addr >> 123 mov 0x1, %g5 >> 124 sllx %g5, 32, %g5 ! Load 0x100000000 >> 125 cmp %g4, %g5 ! Is addr < HI_OBP_ADDRESS? >> 126 blu,pn %xcc, obp_daddr_patch >> 127 nop >> 128 vmalloc_addr: ! vmalloc addr accessed >> 129 ldxa [%g3 + %g6] ASI_N, %g5 ! Yep, load k-vpte >> 130 brgez,pn %g5, longpath ! Valid, load into TLB >> 131 nop >> 132 stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB >> 133 retry >> 134 >> 135 /* This is trivial with the new code... */ >> 136 .globl do_fpdis >> 137 do_fpdis: >> 138 sethi %hi(TSTATE_PEF), %g4 ! IEU0 >> 139 rdpr %tstate, %g5 >> 140 andcc %g5, %g4, %g0 >> 141 be,pt %xcc, 1f >> 142 nop >> 143 rd %fprs, %g5 >> 144 andcc %g5, FPRS_FEF, %g0 >> 145 be,pt %xcc, 1f >> 146 nop >> 147 >> 148 /* Legal state when DCR_IFPOE is set in Cheetah %dcr. */ >> 149 sethi %hi(109f), %g7 >> 150 ba,pt %xcc, etrap >> 151 109: or %g7, %lo(109b), %g7 >> 152 add %g0, %g0, %g0 >> 153 ba,a,pt %xcc, rtrap_clr_l6 >> 154 >> 155 1: ldub [%g6 + TI_FPSAVED], %g5 ! Load Group >> 156 wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles >> 157 andcc %g5, FPRS_FEF, %g0 ! IEU1 Group >> 158 be,a,pt %icc, 1f ! CTI >> 159 clr %g7 ! IEU0 >> 160 ldx [%g6 + TI_GSR], %g7 ! Load Group >> 161 1: andcc %g5, FPRS_DL, %g0 ! IEU1 >> 162 bne,pn %icc, 2f ! CTI >> 163 fzero %f0 ! FPA >> 164 andcc %g5, FPRS_DU, %g0 ! IEU1 Group >> 165 bne,pn %icc, 1f ! CTI >> 166 fzero %f2 ! FPA >> 167 faddd %f0, %f2, %f4 >> 168 fmuld %f0, %f2, %f6 >> 169 faddd %f0, %f2, %f8 >> 170 fmuld %f0, %f2, %f10 >> 171 faddd %f0, %f2, %f12 >> 172 fmuld %f0, %f2, %f14 >> 173 faddd %f0, %f2, %f16 >> 174 fmuld %f0, %f2, %f18 >> 175 faddd %f0, %f2, %f20 >> 176 fmuld %f0, %f2, %f22 >> 177 faddd %f0, %f2, %f24 >> 178 fmuld %f0, %f2, %f26 >> 179 faddd %f0, %f2, %f28 >> 180 fmuld %f0, %f2, %f30 >> 181 faddd %f0, %f2, %f32 >> 182 fmuld %f0, %f2, %f34 >> 183 faddd %f0, %f2, %f36 >> 184 fmuld %f0, %f2, %f38 >> 185 faddd %f0, %f2, %f40 >> 186 fmuld %f0, %f2, %f42 >> 187 faddd %f0, %f2, %f44 >> 188 fmuld %f0, %f2, %f46 >> 189 faddd %f0, %f2, %f48 >> 190 fmuld %f0, %f2, %f50 >> 191 faddd %f0, %f2, %f52 >> 192 fmuld %f0, %f2, %f54 >> 193 faddd %f0, %f2, %f56 >> 194 fmuld %f0, %f2, %f58 >> 195 b,pt %xcc, fpdis_exit2 >> 196 faddd %f0, %f2, %f60 >> 197 1: mov SECONDARY_CONTEXT, %g3 >> 198 add %g6, TI_FPREGS + 0x80, %g1 >> 199 faddd %f0, %f2, %f4 >> 200 fmuld %f0, %f2, %f6 >> 201 ldxa [%g3] ASI_DMMU, %g5 >> 202 add %g6, TI_FPREGS + 0xc0, %g2 >> 203 stxa %g0, [%g3] ASI_DMMU >> 204 membar #Sync >> 205 faddd %f0, %f2, %f8 >> 206 fmuld %f0, %f2, %f10 >> 207 ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-( >> 208 ldda [%g2] ASI_BLK_S, %f48 >> 209 faddd %f0, %f2, %f12 >> 210 fmuld %f0, %f2, %f14 >> 211 faddd %f0, %f2, %f16 >> 212 fmuld %f0, %f2, %f18 >> 213 faddd %f0, %f2, %f20 >> 214 fmuld %f0, %f2, %f22 >> 215 faddd %f0, %f2, %f24 >> 216 fmuld %f0, %f2, %f26 >> 217 faddd %f0, %f2, %f28 >> 218 fmuld %f0, %f2, %f30 >> 219 b,pt %xcc, fpdis_exit >> 220 membar #Sync >> 221 2: andcc %g5, FPRS_DU, %g0 >> 222 bne,pt %icc, 3f >> 223 fzero %f32 >> 224 mov SECONDARY_CONTEXT, %g3 >> 225 fzero %f34 >> 226 ldxa [%g3] ASI_DMMU, %g5 >> 227 add %g6, TI_FPREGS, %g1 >> 228 stxa %g0, [%g3] ASI_DMMU >> 229 membar #Sync >> 230 add %g6, TI_FPREGS + 0x40, %g2 >> 231 faddd %f32, %f34, %f36 >> 232 fmuld %f32, %f34, %f38 >> 233 ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( >> 234 ldda [%g2] ASI_BLK_S, %f16 >> 235 faddd %f32, %f34, %f40 >> 236 fmuld %f32, %f34, %f42 >> 237 faddd %f32, %f34, %f44 >> 238 fmuld %f32, %f34, %f46 >> 239 faddd %f32, %f34, %f48 >> 240 fmuld %f32, %f34, %f50 >> 241 faddd %f32, %f34, %f52 >> 242 fmuld %f32, %f34, %f54 >> 243 faddd %f32, %f34, %f56 >> 244 fmuld %f32, %f34, %f58 >> 245 faddd %f32, %f34, %f60 >> 246 fmuld %f32, %f34, %f62 >> 247 ba,pt %xcc, fpdis_exit >> 248 membar #Sync >> 249 3: mov SECONDARY_CONTEXT, %g3 >> 250 add %g6, TI_FPREGS, %g1 >> 251 ldxa [%g3] ASI_DMMU, %g5 >> 252 mov 0x40, %g2 >> 253 stxa %g0, [%g3] ASI_DMMU >> 254 membar #Sync >> 255 ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( >> 256 ldda [%g1 + %g2] ASI_BLK_S, %f16 >> 257 add %g1, 0x80, %g1 >> 258 ldda [%g1] ASI_BLK_S, %f32 >> 259 ldda [%g1 + %g2] ASI_BLK_S, %f48 >> 260 membar #Sync >> 261 fpdis_exit: >> 262 stxa %g5, [%g3] ASI_DMMU >> 263 membar #Sync >> 264 fpdis_exit2: >> 265 wr %g7, 0, %gsr >> 266 ldx [%g6 + TI_XFSR], %fsr >> 267 rdpr %tstate, %g3 >> 268 or %g3, %g4, %g3 ! anal... >> 269 wrpr %g3, %tstate >> 270 wr %g0, FPRS_FEF, %fprs ! clean DU/DL bits >> 271 retry 299 272 300 .align 32 273 .align 32 301 .endm !! 274 fp_other_bounce: 302 !! 275 call do_fpother 303 #ifndef CONFIG_64BIT !! 276 add %sp, PTREGS_OFF, %o0 304 /* !! 277 ba,pt %xcc, rtrap 305 * dirty bit trap interruption handler !! 278 clr %l6 306 */ << 307 << 308 .macro dbit_11 code << 309 << 310 mfctl %isr,spc << 311 b dbit_trap_11 << 312 mfctl %ior,va << 313 279 >> 280 .globl do_fpother_check_fitos 314 .align 32 281 .align 32 315 .endm !! 282 do_fpother_check_fitos: 316 #endif !! 283 sethi %hi(fp_other_bounce - 4), %g7 317 !! 284 or %g7, %lo(fp_other_bounce - 4), %g7 318 /* !! 285 319 * dirty bit trap interruption handler !! 286 /* NOTE: Need to preserve %g7 until we fully commit 320 */ !! 287 * to the fitos fixup. 321 !! 288 */ 322 .macro dbit_20 code !! 289 stx %fsr, [%g6 + TI_XFSR] 323 !! 290 rdpr %tstate, %g3 324 mfctl %isr,spc !! 291 andcc %g3, TSTATE_PRIV, %g0 325 #ifdef CONFIG_64BIT !! 292 bne,pn %xcc, do_fptrap_after_fsr 326 b dbit_trap_20w !! 293 nop 327 #else !! 294 ldx [%g6 + TI_XFSR], %g3 328 b dbit_trap_20 !! 295 srlx %g3, 14, %g1 329 #endif !! 296 and %g1, 7, %g1 330 mfctl %ior,va !! 297 cmp %g1, 2 ! Unfinished FP-OP >> 298 bne,pn %xcc, do_fptrap_after_fsr >> 299 sethi %hi(1 << 23), %g1 ! Inexact >> 300 andcc %g3, %g1, %g0 >> 301 bne,pn %xcc, do_fptrap_after_fsr >> 302 rdpr %tpc, %g1 >> 303 lduwa [%g1] ASI_AIUP, %g3 ! This cannot ever fail >> 304 #define FITOS_MASK 0xc1f83fe0 >> 305 #define FITOS_COMPARE 0x81a01880 >> 306 sethi %hi(FITOS_MASK), %g1 >> 307 or %g1, %lo(FITOS_MASK), %g1 >> 308 and %g3, %g1, %g1 >> 309 sethi %hi(FITOS_COMPARE), %g2 >> 310 or %g2, %lo(FITOS_COMPARE), %g2 >> 311 cmp %g1, %g2 >> 312 bne,pn %xcc, do_fptrap_after_fsr >> 313 nop >> 314 std %f62, [%g6 + TI_FPREGS + (62 * 4)] >> 315 sethi %hi(fitos_table_1), %g1 >> 316 and %g3, 0x1f, %g2 >> 317 or %g1, %lo(fitos_table_1), %g1 >> 318 sllx %g2, 2, %g2 >> 319 jmpl %g1 + %g2, %g0 >> 320 ba,pt %xcc, fitos_emul_continue >> 321 >> 322 fitos_table_1: >> 323 fitod %f0, %f62 >> 324 fitod %f1, %f62 >> 325 fitod %f2, %f62 >> 326 fitod %f3, %f62 >> 327 fitod %f4, %f62 >> 328 fitod %f5, %f62 >> 329 fitod %f6, %f62 >> 330 fitod %f7, %f62 >> 331 fitod %f8, %f62 >> 332 fitod %f9, %f62 >> 333 fitod %f10, %f62 >> 334 fitod %f11, %f62 >> 335 fitod %f12, %f62 >> 336 fitod %f13, %f62 >> 337 fitod %f14, %f62 >> 338 fitod %f15, %f62 >> 339 fitod %f16, %f62 >> 340 fitod %f17, %f62 >> 341 fitod %f18, %f62 >> 342 fitod %f19, %f62 >> 343 fitod %f20, %f62 >> 344 fitod %f21, %f62 >> 345 fitod %f22, %f62 >> 346 fitod %f23, %f62 >> 347 fitod %f24, %f62 >> 348 fitod %f25, %f62 >> 349 fitod %f26, %f62 >> 350 fitod %f27, %f62 >> 351 fitod %f28, %f62 >> 352 fitod %f29, %f62 >> 353 fitod %f30, %f62 >> 354 fitod %f31, %f62 >> 355 >> 356 fitos_emul_continue: >> 357 sethi %hi(fitos_table_2), %g1 >> 358 srl %g3, 25, %g2 >> 359 or %g1, %lo(fitos_table_2), %g1 >> 360 and %g2, 0x1f, %g2 >> 361 sllx %g2, 2, %g2 >> 362 jmpl %g1 + %g2, %g0 >> 363 ba,pt %xcc, fitos_emul_fini >> 364 >> 365 fitos_table_2: >> 366 fdtos %f62, %f0 >> 367 fdtos %f62, %f1 >> 368 fdtos %f62, %f2 >> 369 fdtos %f62, %f3 >> 370 fdtos %f62, %f4 >> 371 fdtos %f62, %f5 >> 372 fdtos %f62, %f6 >> 373 fdtos %f62, %f7 >> 374 fdtos %f62, %f8 >> 375 fdtos %f62, %f9 >> 376 fdtos %f62, %f10 >> 377 fdtos %f62, %f11 >> 378 fdtos %f62, %f12 >> 379 fdtos %f62, %f13 >> 380 fdtos %f62, %f14 >> 381 fdtos %f62, %f15 >> 382 fdtos %f62, %f16 >> 383 fdtos %f62, %f17 >> 384 fdtos %f62, %f18 >> 385 fdtos %f62, %f19 >> 386 fdtos %f62, %f20 >> 387 fdtos %f62, %f21 >> 388 fdtos %f62, %f22 >> 389 fdtos %f62, %f23 >> 390 fdtos %f62, %f24 >> 391 fdtos %f62, %f25 >> 392 fdtos %f62, %f26 >> 393 fdtos %f62, %f27 >> 394 fdtos %f62, %f28 >> 395 fdtos %f62, %f29 >> 396 fdtos %f62, %f30 >> 397 fdtos %f62, %f31 >> 398 >> 399 fitos_emul_fini: >> 400 ldd [%g6 + TI_FPREGS + (62 * 4)], %f62 >> 401 done 331 402 >> 403 .globl do_fptrap 332 .align 32 404 .align 32 333 .endm !! 405 do_fptrap: 334 !! 406 stx %fsr, [%g6 + TI_XFSR] 335 /* In LP64, the space contains part of !! 407 do_fptrap_after_fsr: 336 * fault. We have to extract this and !! 408 ldub [%g6 + TI_FPSAVED], %g3 337 * zeroing the corresponding bits in t !! 409 rd %fprs, %g1 338 .macro space_adjust spc,va !! 410 or %g3, %g1, %g3 339 #ifdef CONFIG_64BIT !! 411 stb %g3, [%g6 + TI_FPSAVED] 340 extrd,u \spc,63,SPACEID_SHIFT, !! 412 rd %gsr, %g3 341 depd %r0,63,SPACEID_SHIFT,\ !! 413 stx %g3, [%g6 + TI_GSR] 342 depd \tmp,31,SPACEID_SHIFT, !! 414 mov SECONDARY_CONTEXT, %g3 343 #endif !! 415 add %g6, TI_FPREGS, %g2 344 .endm !! 416 ldxa [%g3] ASI_DMMU, %g5 345 !! 417 stxa %g0, [%g3] ASI_DMMU 346 .import swapper_pg_dir,code !! 418 membar #Sync >> 419 andcc %g1, FPRS_DL, %g0 >> 420 be,pn %icc, 4f >> 421 mov 0x40, %g3 >> 422 stda %f0, [%g2] ASI_BLK_S >> 423 stda %f16, [%g2 + %g3] ASI_BLK_S >> 424 andcc %g1, FPRS_DU, %g0 >> 425 be,pn %icc, 5f >> 426 4: add %g2, 128, %g2 >> 427 stda %f32, [%g2] ASI_BLK_S >> 428 stda %f48, [%g2 + %g3] ASI_BLK_S >> 429 5: mov SECONDARY_CONTEXT, %g1 >> 430 membar #Sync >> 431 stxa %g5, [%g1] ASI_DMMU >> 432 membar #Sync >> 433 ba,pt %xcc, etrap >> 434 wr %g0, 0, %fprs 347 435 348 /* Get the pgd. For faults on space z !! 436 /* The registers for cross calls will be: 349 * is simply swapper_pg_dir. For user << 350 * pgd is stored in %cr25 */ << 351 .macro get_pgd spc,re << 352 ldil L%PA(swapper_pg_dir),\ << 353 ldo R%PA(swapper_pg_dir)(\ << 354 or,COND(=) %r0,\spc,%r0 << 355 mfctl %cr25,\reg << 356 .endm << 357 << 358 /* << 359 space_check(spc,tmp,fault) << 360 << 361 spc - The space we saw the fau << 362 tmp - The place to store the c << 363 fault - Function to call on fa << 364 << 365 Only allow faults on different << 366 currently active one if we're << 367 << 368 */ << 369 .macro space_check spc,tm << 370 mfsp %sr7,\tmp << 371 /* check against %r0 which is same val << 372 or,COND(<>) %r0,\spc,%r0 /* use << 373 * as << 374 * che << 375 copy \spc,\tmp << 376 or,COND(=) %r0,\tmp,%r0 /* nul << 377 cmpb,COND(<>),n \tmp,\spc,\fault << 378 .endm << 379 << 380 /* Look up a PTE in a 2-Level scheme ( << 381 * level if the entry isn't present << 382 * 437 * 383 * NOTE: we use ldw even for LP64, sin !! 438 * DATA 0: [low 32-bits] Address of function to call, jmp to this 384 * can address up to 1TB !! 439 * [high 32-bits] MMU Context Argument 0, place in %g5 385 */ !! 440 * DATA 1: Address Argument 1, place in %g6 386 .macro L2_ptep pmd,pte,index, !! 441 * DATA 2: Address Argument 2, place in %g7 387 #if CONFIG_PGTABLE_LEVELS == 3 << 388 extru_safe \va,31-ASM_PMD_SHIFT,A << 389 #else << 390 extru_safe \va,31-ASM_PGDIR_SHIFT << 391 #endif << 392 dep %r0,31,PAGE_SHIFT,\pmd << 393 #if CONFIG_PGTABLE_LEVELS < 3 << 394 copy %r0,\pte << 395 #endif << 396 ldw,s \index(\pmd),\pmd << 397 bb,>=,n \pmd,_PxD_PRESENT_BIT, << 398 dep %r0,31,PxD_FLAG_SHIFT, << 399 SHLREG \pmd,PxD_VALUE_SHIFT,\ << 400 extru_safe \va,31-PAGE_SHIFT,ASM_ << 401 dep %r0,31,PAGE_SHIFT,\pmd << 402 shladd \index,BITS_PER_PTE_EN << 403 .endm << 404 << 405 /* Look up PTE in a 3-Level scheme. */ << 406 .macro L3_ptep pgd,pte,index, << 407 #if CONFIG_PGTABLE_LEVELS == 3 << 408 copy %r0,\pte << 409 extrd,u \va,63-ASM_PGDIR_SHIFT << 410 ldw,s \index(\pgd),\pgd << 411 bb,>=,n \pgd,_PxD_PRESENT_BIT, << 412 shld \pgd,PxD_VALUE_SHIFT,\ << 413 #endif << 414 L2_ptep \pgd,\pte,\index,\va,\ << 415 .endm << 416 << 417 /* Acquire page_table_lock and check p << 418 .macro ptl_lock spc,pt << 419 #ifdef CONFIG_TLB_PTLOCK << 420 98: cmpib,COND(=),n 0,\spc,2f << 421 get_ptl \tmp << 422 1: LDCW 0(\tmp),\tmp1 << 423 cmpib,COND(=) 0,\tmp1,1b << 424 nop << 425 LDREG 0(\ptp),\pte << 426 bb,<,n \pte,_PAGE_PRESENT_BIT << 427 b \fault << 428 stw \tmp1,0(\tmp) << 429 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, << 430 #endif << 431 2: LDREG 0(\ptp),\pte << 432 bb,>=,n \pte,_PAGE_PRESENT_BIT << 433 3: << 434 .endm << 435 << 436 /* Release page_table_lock if for user << 437 store to ensure all prior accesses << 438 releasing the lock. Note stw may no << 439 provide one extra nop when CONFIG_T << 440 .macro ptl_unlock spc,tm << 441 #ifdef CONFIG_TLB_PTLOCK << 442 98: get_ptl \tmp << 443 ldi __ARCH_SPIN_LOCK_UNLOC << 444 or,COND(=) %r0,\spc,%r0 << 445 stw,ma \tmp2,0(\tmp) << 446 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, << 447 insert_nops NUM_PIPELINE_INSNS - 4 << 448 #else << 449 insert_nops NUM_PIPELINE_INSNS - 1 << 450 #endif << 451 .endm << 452 << 453 /* Set the _PAGE_ACCESSED bit of the P << 454 * don't needlessly dirty the cache li << 455 .macro update_accessed ptp,pt << 456 ldi _PAGE_ACCESSED,\tmp1 << 457 or \tmp1,\pte,\tmp << 458 and,COND(<>) \tmp1,\pte,%r0 << 459 STREG \tmp,0(\ptp) << 460 .endm << 461 << 462 /* Set the dirty bit (and accessed bit << 463 * clever, this is only used from the << 464 .macro update_dirty ptp,pt << 465 ldi _PAGE_ACCESSED|_PAGE_D << 466 or \tmp,\pte,\pte << 467 STREG \pte,0(\ptp) << 468 .endm << 469 << 470 /* We have (depending on the page size << 471 * - 38 to 52-bit Physical Page Number << 472 * - 12 to 26-bit page offset << 473 */ << 474 /* bitshift difference between a PFN ( << 475 * to a CPU TLB 4k PFN (4k => 12 bits << 476 #define PAGE_ADD_SHIFT (PAGE_ << 477 #define PAGE_ADD_HUGE_SHIFT (REAL_ << 478 #define PFN_START_BIT (63-ASM_PFN_PT << 479 << 480 /* Drop prot bits and convert to page << 481 .macro convert_for_tlb_insert << 482 #ifdef CONFIG_HUGETLB_PAGE << 483 copy \pte,\tmp << 484 extrd,u \tmp,PFN_START_BIT,PFN << 485 << 486 depdi _PAGE_SIZE_ENCODING_DE << 487 (63-58)+PAGE_A << 488 extrd,u,*= \tmp,_PAGE_HPAGE_BIT+3 << 489 depdi _HUGE_PAGE_SIZE_ENCODI << 490 (63-58)+PAGE_A << 491 #else /* Huge pages disabled */ << 492 extrd,u \pte,PFN_START_BIT,PFN << 493 depdi _PAGE_SIZE_ENCODING_DE << 494 (63-58)+PAGE_A << 495 #endif << 496 .endm << 497 << 498 /* Convert the pte and prot to tlb ins << 499 * this happens is quite subtle, read << 500 .macro make_insert_tlb spc,pt << 501 space_to_prot \spc \prot /* c << 502 /* The following is the real subtlety. << 503 * T <-> _PAGE_REFTRAP << 504 * D <-> _PAGE_DIRTY << 505 * B <-> _PAGE_DMB (memory break) << 506 * << 507 * Then incredible subtlety: The acces << 508 * _PAGE_GATEWAY, _PAGE_EXEC and _PAGE << 509 * See 3-14 of the parisc 2.0 manual << 510 * << 511 * Finally, _PAGE_READ goes in the top << 512 * trigger an access rights trap in us << 513 * tries to read an unreadable page */ << 514 #if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT << 515 /* need to drop DMB bit, as it's used << 516 depi 0,_PAGE_SPECIAL_BIT,1, << 517 #endif << 518 depd \pte,8,7,\prot << 519 << 520 /* PAGE_USER indicates the page can be << 521 * so deposit X1|11 to PL1|PL2 (rememb << 522 * contains _PAGE_READ) */ << 523 extrd,u,*= \pte,_PAGE_USER_BIT+32 << 524 depdi 7,11,3,\prot << 525 /* If we're a gateway page, drop PL2 b << 526 * to kernel privilege (so we can exec << 527 * Any privilege promotion page always << 528 extrd,u,*= \pte,_PAGE_GATEWAY_BIT << 529 depd %r0,11,2,\prot /* If << 530 << 531 /* Enforce uncacheable pages. << 532 * This should ONLY be use for MMIO on << 533 * Memory/DMA is cache coherent on all << 534 * (that means T-class is NOT supporte << 535 * on most of those machines only hand << 536 */ << 537 extrd,u,*= \pte,_PAGE_NO_CACHE_BI << 538 depdi 1,12,1,\prot << 539 << 540 /* Drop prot bits and convert to page << 541 convert_for_tlb_insert20 \pte \tmp << 542 .endm << 543 << 544 /* Identical macro to make_insert_tlb << 545 * makes the tlb entry for the differe << 546 * insertion instructions */ << 547 .macro make_insert_tlb_11 << 548 #if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT << 549 /* need to drop DMB bit, as it's used << 550 depi 0,_PAGE_SPECIAL_BIT,1, << 551 #endif << 552 zdep \spc,30,15,\prot << 553 dep \pte,8,7,\prot << 554 extru,= \pte,_PAGE_NO_CACHE_BI << 555 depi 1,12,1,\prot << 556 extru,= \pte,_PAGE_USER_BIT,1, << 557 depi 7,11,3,\prot /* Set << 558 extru,= \pte,_PAGE_GATEWAY_BIT << 559 depi 0,11,2,\prot /* If << 560 << 561 /* Get rid of prot bits and convert to << 562 << 563 depi 0,31,ASM_PFN_PTE_SHIFT << 564 SHRREG \pte,(ASM_PFN_PTE_SHIF << 565 .endm << 566 << 567 /* This is for ILP32 PA2.0 only. The << 568 * to extend into I/O space if the add << 569 * so we extend the f's into the top w << 570 * this case */ << 571 .macro f_extend pte,tm << 572 extrd,s \pte,42,4,\tmp << 573 addi,<> 1,\tmp,%r0 << 574 extrd,s \pte,63,25,\pte << 575 .endm << 576 << 577 /* The alias region is comprised of a << 578 * aligned to 8 MB. It is used to clea << 579 * using kernel virtual addresses cong << 580 * virtual address. << 581 * 442 * 582 * To use the alias page, you set %r26 !! 443 * With this method we can do most of the cross-call tlb/cache 583 * entry (identifying the physical pag !! 444 * flushing very quickly. 584 * the from tlb entry (or nothing if o << 585 * clear_user_page_asm) */ << 586 .macro do_alias spc,tm << 587 cmpib,COND(<>),n 0,\spc,\fault << 588 ldil L%(TMPALIAS_MAP_START) << 589 copy \va,\tmp1 << 590 depi_safe 0,31,TMPALIAS_SIZE_BIT << 591 cmpb,COND(<>),n \tmp,\tmp1,\fault << 592 mfctl %cr19,\tmp /* iir << 593 /* get the opcode (first six bits) int << 594 extrw,u \tmp,5,6,\tmp << 595 /* << 596 * Only setting the T bit prevents dat << 597 * Setting access rights to zero preve << 598 * 445 * 599 * Note subtlety here: _PAGE_GATEWAY, !! 446 * Current CPU's IRQ worklist table is locked into %g1, 600 * to type field and _PAGE_READ goes t !! 447 * don't touch. 601 */ 448 */ 602 ldi (_PAGE_REFTRAP|_PAGE_R !! 449 .text 603 /* !! 450 .align 32 604 * so if the opcode is one (i.e. this !! 451 .globl do_ivec 605 * instruction) nullify the next load !! 452 do_ivec: 606 * Otherwise this is a normal data ope !! 453 mov 0x40, %g3 607 */ !! 454 ldxa [%g3 + %g0] ASI_INTR_R, %g3 608 cmpiclr,= 0x01,\tmp,%r0 !! 455 sethi %hi(KERNBASE), %g4 609 ldi (_PAGE_DIRTY|_PAGE_REA !! 456 cmp %g3, %g4 610 .ifc \patype,20 !! 457 bgeu,pn %xcc, do_ivec_xcall 611 depd,z \prot,8,7,\prot !! 458 srlx %g3, 32, %g5 612 .else !! 459 stxa %g0, [%g0] ASI_INTR_RECEIVE 613 .ifc \patype,11 !! 460 membar #Sync 614 depw,z \prot,8,7,\prot !! 461 615 .else !! 462 sethi %hi(ivector_table), %g2 616 .error "undefined PA type to do_alias" !! 463 sllx %g3, 5, %g3 617 .endif !! 464 or %g2, %lo(ivector_table), %g2 618 .endif !! 465 add %g2, %g3, %g3 619 /* !! 466 ldx [%g3 + 0x08], %g2 /* irq_info */ 620 * OK, it is in the temp alias region, !! 467 ldub [%g3 + 0x04], %g4 /* pil */ 621 * Check "subtle" note in pacache.S re !! 468 brz,pn %g2, do_ivec_spurious 622 */ !! 469 mov 1, %g2 623 extrw,u,= \va,31-TMPALIAS_SIZE_B !! 470 624 or,COND(tr) %r23,%r0,\pte !! 471 sllx %g2, %g4, %g2 625 or %r26,%r0,\pte !! 472 sllx %g4, 2, %g4 626 !! 473 lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ 627 /* convert phys addr in \pte (from r23 !! 474 stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ 628 SHRREG \pte,PAGE_SHIFT+PAGE_A !! 475 stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ 629 depi_safe _PAGE_SIZE_ENCODING_DE !! 476 wr %g2, 0x0, %set_softint 630 .endm !! 477 retry 631 !! 478 do_ivec_xcall: 632 !! 479 mov 0x50, %g1 633 /* !! 480 634 * Fault_vectors are architecturally r !! 481 ldxa [%g1 + %g0] ASI_INTR_R, %g1 635 * boundary !! 482 srl %g3, 0, %g3 636 */ !! 483 mov 0x60, %g7 637 !! 484 ldxa [%g7 + %g0] ASI_INTR_R, %g7 638 .section .text.hot !! 485 stxa %g0, [%g0] ASI_INTR_RECEIVE 639 .align 2048 !! 486 membar #Sync 640 !! 487 ba,pt %xcc, 1f 641 ENTRY(fault_vector_20) !! 488 nop 642 /* First vector is invalid (0) */ << 643 .ascii "cows can fly" << 644 .byte 0 << 645 .align 32 << 646 << 647 hpmc 1 << 648 def 2 << 649 def 3 << 650 extint 4 << 651 def 5 << 652 itlb_20 PARISC_ITLB_TRAP << 653 def 7 << 654 def 8 << 655 def 9 << 656 def 10 << 657 def 11 << 658 def 12 << 659 def 13 << 660 def 14 << 661 dtlb_20 15 << 662 naitlb_20 16 << 663 nadtlb_20 17 << 664 def 18 << 665 def 19 << 666 dbit_20 20 << 667 def 21 << 668 def 22 << 669 def 23 << 670 def 24 << 671 def 25 << 672 def 26 << 673 def 27 << 674 def 28 << 675 def 29 << 676 def 30 << 677 def 31 << 678 END(fault_vector_20) << 679 << 680 #ifndef CONFIG_64BIT << 681 << 682 .align 2048 << 683 << 684 ENTRY(fault_vector_11) << 685 /* First vector is invalid (0) */ << 686 .ascii "cows can fly" << 687 .byte 0 << 688 .align 32 << 689 << 690 hpmc 1 << 691 def 2 << 692 def 3 << 693 extint 4 << 694 def 5 << 695 itlb_11 PARISC_ITLB_TRAP << 696 def 7 << 697 def 8 << 698 def 9 << 699 def 10 << 700 def 11 << 701 def 12 << 702 def 13 << 703 def 14 << 704 dtlb_11 15 << 705 naitlb_11 16 << 706 nadtlb_11 17 << 707 def 18 << 708 def 19 << 709 dbit_11 20 << 710 def 21 << 711 def 22 << 712 def 23 << 713 def 24 << 714 def 25 << 715 def 26 << 716 def 27 << 717 def 28 << 718 def 29 << 719 def 30 << 720 def 31 << 721 END(fault_vector_11) << 722 << 723 #endif << 724 /* Fault vector is separately protecte << 725 .align PAGE_SIZE << 726 << 727 .import handle_interruption,co << 728 .import do_cpu_irq_mask,code << 729 << 730 /* << 731 * Child Returns here << 732 * << 733 * copy_thread moved args into task sa << 734 */ << 735 << 736 ENTRY(ret_from_kernel_thread) << 737 /* Call schedule_tail first though */ << 738 BL schedule_tail, %r2 << 739 nop << 740 << 741 mfctl %cr30,%r1 /* task_struct << 742 LDREG TASK_PT_GR25(%r1), %r26 << 743 #ifdef CONFIG_64BIT << 744 LDREG TASK_PT_GR27(%r1), %r27 << 745 #endif << 746 LDREG TASK_PT_GR26(%r1), %r1 << 747 ble 0(%sr7, %r1) << 748 copy %r31, %r2 << 749 b finish_child_return << 750 nop << 751 END(ret_from_kernel_thread) << 752 489 >> 490 .align 32 >> 491 1: jmpl %g3, %g0 >> 492 nop 753 493 754 /* !! 494 do_ivec_spurious: 755 * struct task_struct *_switch_to(stru !! 495 stw %g3, [%g6 + 0x00] /* irq_work(cpu, 0) = bucket */ 756 * struct task_struct *next) !! 496 rdpr %pstate, %g5 >> 497 >> 498 wrpr %g5, PSTATE_IG | PSTATE_AG, %pstate >> 499 sethi %hi(109f), %g7 >> 500 ba,pt %xcc, etrap >> 501 109: or %g7, %lo(109b), %g7 >> 502 call catch_disabled_ivec >> 503 add %sp, PTREGS_OFF, %o0 >> 504 ba,pt %xcc, rtrap >> 505 clr %l6 >> 506 >> 507 .globl save_alternate_globals >> 508 save_alternate_globals: /* %o0 = save_area */ >> 509 rdpr %pstate, %o5 >> 510 andn %o5, PSTATE_IE, %o1 >> 511 wrpr %o1, PSTATE_AG, %pstate >> 512 stx %g0, [%o0 + 0x00] >> 513 stx %g1, [%o0 + 0x08] >> 514 stx %g2, [%o0 + 0x10] >> 515 stx %g3, [%o0 + 0x18] >> 516 stx %g4, [%o0 + 0x20] >> 517 stx %g5, [%o0 + 0x28] >> 518 stx %g6, [%o0 + 0x30] >> 519 stx %g7, [%o0 + 0x38] >> 520 wrpr %o1, PSTATE_IG, %pstate >> 521 stx %g0, [%o0 + 0x40] >> 522 stx %g1, [%o0 + 0x48] >> 523 stx %g2, [%o0 + 0x50] >> 524 stx %g3, [%o0 + 0x58] >> 525 stx %g4, [%o0 + 0x60] >> 526 stx %g5, [%o0 + 0x68] >> 527 stx %g6, [%o0 + 0x70] >> 528 stx %g7, [%o0 + 0x78] >> 529 wrpr %o1, PSTATE_MG, %pstate >> 530 stx %g0, [%o0 + 0x80] >> 531 stx %g1, [%o0 + 0x88] >> 532 stx %g2, [%o0 + 0x90] >> 533 stx %g3, [%o0 + 0x98] >> 534 stx %g4, [%o0 + 0xa0] >> 535 stx %g5, [%o0 + 0xa8] >> 536 stx %g6, [%o0 + 0xb0] >> 537 stx %g7, [%o0 + 0xb8] >> 538 wrpr %o5, 0x0, %pstate >> 539 retl >> 540 nop >> 541 >> 542 .globl restore_alternate_globals >> 543 restore_alternate_globals: /* %o0 = save_area */ >> 544 rdpr %pstate, %o5 >> 545 andn %o5, PSTATE_IE, %o1 >> 546 wrpr %o1, PSTATE_AG, %pstate >> 547 ldx [%o0 + 0x00], %g0 >> 548 ldx [%o0 + 0x08], %g1 >> 549 ldx [%o0 + 0x10], %g2 >> 550 ldx [%o0 + 0x18], %g3 >> 551 ldx [%o0 + 0x20], %g4 >> 552 ldx [%o0 + 0x28], %g5 >> 553 ldx [%o0 + 0x30], %g6 >> 554 ldx [%o0 + 0x38], %g7 >> 555 wrpr %o1, PSTATE_IG, %pstate >> 556 ldx [%o0 + 0x40], %g0 >> 557 ldx [%o0 + 0x48], %g1 >> 558 ldx [%o0 + 0x50], %g2 >> 559 ldx [%o0 + 0x58], %g3 >> 560 ldx [%o0 + 0x60], %g4 >> 561 ldx [%o0 + 0x68], %g5 >> 562 ldx [%o0 + 0x70], %g6 >> 563 ldx [%o0 + 0x78], %g7 >> 564 wrpr %o1, PSTATE_MG, %pstate >> 565 ldx [%o0 + 0x80], %g0 >> 566 ldx [%o0 + 0x88], %g1 >> 567 ldx [%o0 + 0x90], %g2 >> 568 ldx [%o0 + 0x98], %g3 >> 569 ldx [%o0 + 0xa0], %g4 >> 570 ldx [%o0 + 0xa8], %g5 >> 571 ldx [%o0 + 0xb0], %g6 >> 572 ldx [%o0 + 0xb8], %g7 >> 573 wrpr %o5, 0x0, %pstate >> 574 retl >> 575 nop >> 576 >> 577 .globl getcc, setcc >> 578 getcc: >> 579 ldx [%o0 + PT_V9_TSTATE], %o1 >> 580 srlx %o1, 32, %o1 >> 581 and %o1, 0xf, %o1 >> 582 retl >> 583 stx %o1, [%o0 + PT_V9_G1] >> 584 setcc: >> 585 ldx [%o0 + PT_V9_TSTATE], %o1 >> 586 ldx [%o0 + PT_V9_G1], %o2 >> 587 or %g0, %ulo(TSTATE_ICC), %o3 >> 588 sllx %o3, 32, %o3 >> 589 andn %o1, %o3, %o1 >> 590 sllx %o2, 32, %o2 >> 591 and %o2, %o3, %o2 >> 592 or %o1, %o2, %o1 >> 593 retl >> 594 stx %o1, [%o0 + PT_V9_TSTATE] >> 595 >> 596 .globl utrap, utrap_ill >> 597 utrap: brz,pn %g1, etrap >> 598 nop >> 599 save %sp, -128, %sp >> 600 rdpr %tstate, %l6 >> 601 rdpr %cwp, %l7 >> 602 andn %l6, TSTATE_CWP, %l6 >> 603 wrpr %l6, %l7, %tstate >> 604 rdpr %tpc, %l6 >> 605 rdpr %tnpc, %l7 >> 606 wrpr %g1, 0, %tnpc >> 607 done >> 608 utrap_ill: >> 609 call bad_trap >> 610 add %sp, PTREGS_OFF, %o0 >> 611 ba,pt %xcc, rtrap >> 612 clr %l6 >> 613 >> 614 #ifdef CONFIG_BLK_DEV_FD >> 615 .globl floppy_hardint >> 616 floppy_hardint: >> 617 wr %g0, (1 << 11), %clear_softint >> 618 sethi %hi(doing_pdma), %g1 >> 619 ld [%g1 + %lo(doing_pdma)], %g2 >> 620 brz,pn %g2, floppy_dosoftint >> 621 sethi %hi(fdc_status), %g3 >> 622 ldx [%g3 + %lo(fdc_status)], %g3 >> 623 sethi %hi(pdma_vaddr), %g5 >> 624 ldx [%g5 + %lo(pdma_vaddr)], %g4 >> 625 sethi %hi(pdma_size), %g5 >> 626 ldx [%g5 + %lo(pdma_size)], %g5 >> 627 >> 628 next_byte: >> 629 lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 >> 630 andcc %g7, 0x80, %g0 >> 631 be,pn %icc, floppy_fifo_emptied >> 632 andcc %g7, 0x20, %g0 >> 633 be,pn %icc, floppy_overrun >> 634 andcc %g7, 0x40, %g0 >> 635 be,pn %icc, floppy_write >> 636 sub %g5, 1, %g5 >> 637 >> 638 inc %g3 >> 639 lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 >> 640 dec %g3 >> 641 orcc %g0, %g5, %g0 >> 642 stb %g7, [%g4] >> 643 bne,pn %xcc, next_byte >> 644 add %g4, 1, %g4 >> 645 >> 646 b,pt %xcc, floppy_tdone >> 647 nop >> 648 >> 649 floppy_write: >> 650 ldub [%g4], %g7 >> 651 orcc %g0, %g5, %g0 >> 652 inc %g3 >> 653 stba %g7, [%g3] ASI_PHYS_BYPASS_EC_E >> 654 dec %g3 >> 655 bne,pn %xcc, next_byte >> 656 add %g4, 1, %g4 >> 657 >> 658 floppy_tdone: >> 659 sethi %hi(pdma_vaddr), %g1 >> 660 stx %g4, [%g1 + %lo(pdma_vaddr)] >> 661 sethi %hi(pdma_size), %g1 >> 662 stx %g5, [%g1 + %lo(pdma_size)] >> 663 sethi %hi(auxio_register), %g1 >> 664 ldx [%g1 + %lo(auxio_register)], %g7 >> 665 lduba [%g7] ASI_PHYS_BYPASS_EC_E, %g5 >> 666 or %g5, AUXIO_AUX1_FTCNT, %g5 >> 667 /* andn %g5, AUXIO_AUX1_MASK, %g5 */ >> 668 stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E >> 669 andn %g5, AUXIO_AUX1_FTCNT, %g5 >> 670 /* andn %g5, AUXIO_AUX1_MASK, %g5 */ >> 671 >> 672 nop; nop; nop; nop; nop; nop; >> 673 nop; nop; nop; nop; nop; nop; >> 674 >> 675 stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E >> 676 sethi %hi(doing_pdma), %g1 >> 677 b,pt %xcc, floppy_dosoftint >> 678 st %g0, [%g1 + %lo(doing_pdma)] >> 679 >> 680 floppy_fifo_emptied: >> 681 sethi %hi(pdma_vaddr), %g1 >> 682 stx %g4, [%g1 + %lo(pdma_vaddr)] >> 683 sethi %hi(pdma_size), %g1 >> 684 stx %g5, [%g1 + %lo(pdma_size)] >> 685 sethi %hi(irq_action), %g1 >> 686 or %g1, %lo(irq_action), %g1 >> 687 ldx [%g1 + (11 << 3)], %g3 ! irqaction[floppy_irq] >> 688 ldx [%g3 + 0x08], %g4 ! action->flags>>48==ino >> 689 sethi %hi(ivector_table), %g3 >> 690 srlx %g4, 48, %g4 >> 691 or %g3, %lo(ivector_table), %g3 >> 692 sllx %g4, 5, %g4 >> 693 ldx [%g3 + %g4], %g4 ! &ivector_table[ino] >> 694 ldx [%g4 + 0x10], %g4 ! bucket->iclr >> 695 stwa %g0, [%g4] ASI_PHYS_BYPASS_EC_E ! ICLR_IDLE >> 696 membar #Sync ! probably not needed... >> 697 retry >> 698 >> 699 floppy_overrun: >> 700 sethi %hi(pdma_vaddr), %g1 >> 701 stx %g4, [%g1 + %lo(pdma_vaddr)] >> 702 sethi %hi(pdma_size), %g1 >> 703 stx %g5, [%g1 + %lo(pdma_size)] >> 704 sethi %hi(doing_pdma), %g1 >> 705 st %g0, [%g1 + %lo(doing_pdma)] >> 706 >> 707 floppy_dosoftint: >> 708 rdpr %pil, %g2 >> 709 wrpr %g0, 15, %pil >> 710 sethi %hi(109f), %g7 >> 711 b,pt %xcc, etrap_irq >> 712 109: or %g7, %lo(109b), %g7 >> 713 >> 714 mov 11, %o0 >> 715 mov 0, %o1 >> 716 call sparc_floppy_irq >> 717 add %sp, PTREGS_OFF, %o2 >> 718 >> 719 b,pt %xcc, rtrap_irq >> 720 nop >> 721 >> 722 #endif /* CONFIG_BLK_DEV_FD */ >> 723 >> 724 /* XXX Here is stuff we still need to write... -DaveM XXX */ >> 725 .globl netbsd_syscall >> 726 netbsd_syscall: >> 727 retl >> 728 nop >> 729 >> 730 /* These next few routines must be sure to clear the >> 731 * SFSR FaultValid bit so that the fast tlb data protection >> 732 * handler does not flush the wrong context and lock up the >> 733 * box. >> 734 */ >> 735 .globl __do_data_access_exception >> 736 .globl __do_data_access_exception_tl1 >> 737 __do_data_access_exception_tl1: >> 738 rdpr %pstate, %g4 >> 739 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate >> 740 mov TLB_SFSR, %g3 >> 741 mov DMMU_SFAR, %g5 >> 742 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR >> 743 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR >> 744 stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit >> 745 membar #Sync >> 746 ba,pt %xcc, winfix_dax >> 747 rdpr %tpc, %g3 >> 748 __do_data_access_exception: >> 749 rdpr %pstate, %g4 >> 750 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate >> 751 mov TLB_SFSR, %g3 >> 752 mov DMMU_SFAR, %g5 >> 753 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR >> 754 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR >> 755 stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit >> 756 membar #Sync >> 757 sethi %hi(109f), %g7 >> 758 ba,pt %xcc, etrap >> 759 109: or %g7, %lo(109b), %g7 >> 760 mov %l4, %o1 >> 761 mov %l5, %o2 >> 762 call data_access_exception >> 763 add %sp, PTREGS_OFF, %o0 >> 764 ba,pt %xcc, rtrap >> 765 clr %l6 >> 766 >> 767 .globl __do_instruction_access_exception >> 768 .globl __do_instruction_access_exception_tl1 >> 769 __do_instruction_access_exception_tl1: >> 770 rdpr %pstate, %g4 >> 771 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate >> 772 mov TLB_SFSR, %g3 >> 773 mov DMMU_SFAR, %g5 >> 774 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR >> 775 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR >> 776 stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit >> 777 membar #Sync >> 778 sethi %hi(109f), %g7 >> 779 ba,pt %xcc, etraptl1 >> 780 109: or %g7, %lo(109b), %g7 >> 781 mov %l4, %o1 >> 782 mov %l5, %o2 >> 783 call instruction_access_exception_tl1 >> 784 add %sp, PTREGS_OFF, %o0 >> 785 ba,pt %xcc, rtrap >> 786 clr %l6 >> 787 >> 788 __do_instruction_access_exception: >> 789 rdpr %pstate, %g4 >> 790 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate >> 791 mov TLB_SFSR, %g3 >> 792 mov DMMU_SFAR, %g5 >> 793 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR >> 794 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR >> 795 stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit >> 796 membar #Sync >> 797 sethi %hi(109f), %g7 >> 798 ba,pt %xcc, etrap >> 799 109: or %g7, %lo(109b), %g7 >> 800 mov %l4, %o1 >> 801 mov %l5, %o2 >> 802 call instruction_access_exception >> 803 add %sp, PTREGS_OFF, %o0 >> 804 ba,pt %xcc, rtrap >> 805 clr %l6 >> 806 >> 807 /* This is the trap handler entry point for ECC correctable >> 808 * errors. They are corrected, but we listen for the trap >> 809 * so that the event can be logged. 757 * 810 * 758 * switch kernel stacks and return pre !! 811 * Disrupting errors are either: 759 ENTRY_CFI(_switch_to) !! 812 * 1) single-bit ECC errors during UDB reads to system 760 STREG %r2, -RP_OFFSET(%r30) !! 813 * memory 761 !! 814 * 2) data parity errors during write-back events 762 callee_save_float << 763 callee_save << 764 << 765 load32 _switch_to_ret, %r2 << 766 << 767 STREG %r2, TASK_PT_KPC(%r26) << 768 LDREG TASK_PT_KPC(%r25), %r2 << 769 << 770 STREG %r30, TASK_PT_KSP(%r26) << 771 LDREG TASK_PT_KSP(%r25), %r30 << 772 bv %r0(%r2) << 773 mtctl %r25,%cr30 << 774 << 775 ENTRY(_switch_to_ret) << 776 mtctl %r0, %cr0 /* Nee << 777 callee_rest << 778 callee_rest_float << 779 << 780 LDREG -RP_OFFSET(%r30), %r2 << 781 bv %r0(%r2) << 782 copy %r26, %r28 << 783 ENDPROC_CFI(_switch_to) << 784 << 785 /* << 786 * Common rfi return path for interrup << 787 * sys_rt_sigreturn (sometimes). The << 788 * return via this path if the signal << 789 * was running; if the process was blo << 790 * normal syscall_exit path is used. << 791 * proceses exit via intr_restore. << 792 * 815 * 793 * XXX If any syscalls that change a p !! 816 * As far as I can make out from the manual, the CEE trap 794 * this way, then we will need to copy !! 817 * is only for correctable errors during memory read 795 * adjust IASQ[0..1]. !! 818 * accesses by the front-end of the processor. 796 * 819 * >> 820 * The code below is only for trap level 1 CEE events, >> 821 * as it is the only situation where we can safely record >> 822 * and log. For trap level >1 we just clear the CE bit >> 823 * in the AFSR and return. 797 */ 824 */ 798 825 799 .align PAGE_SIZE !! 826 /* Our trap handling infrastructure allows us to preserve 800 !! 827 * two 64-bit values during etrap for arguments to 801 ENTRY_CFI(syscall_exit_rfi) !! 828 * subsequent C code. Therefore we encode the information 802 mfctl %cr30,%r16 /* tas !! 829 * as follows: 803 ldo TASK_REGS(%r16),%r16 << 804 /* Force iaoq to userspace, as the use << 805 * context via sigcontext. Also Filter << 806 */ << 807 LDREG PT_IAOQ0(%r16),%r19 << 808 depi PRIV_USER,31,2,%r19 << 809 STREG %r19,PT_IAOQ0(%r16) << 810 LDREG PT_IAOQ1(%r16),%r19 << 811 depi PRIV_USER,31,2,%r19 << 812 STREG %r19,PT_IAOQ1(%r16) << 813 LDREG PT_PSW(%r16),%r19 << 814 load32 USER_PSW_MASK,%r1 << 815 #ifdef CONFIG_64BIT << 816 load32 USER_PSW_HI_MASK,%r20 << 817 depd %r20,31,32,%r1 << 818 #endif << 819 and %r19,%r1,%r19 /* Mask out bits << 820 load32 USER_PSW,%r1 << 821 or %r19,%r1,%r19 /* Make sure def << 822 STREG %r19,PT_PSW(%r16) << 823 << 824 /* << 825 * If we aren't being traced, we never << 826 * (we don't store them in the sigcont << 827 * to "proper" values now (otherwise w << 828 * whatever was last stored in the tas << 829 * be inconsistent if an interrupt occ << 830 * page). Note that we may be "trashin << 831 * them, but we don't support the user << 832 */ << 833 << 834 STREG %r0,PT_SR2(%r16) << 835 mfsp %sr3,%r19 << 836 STREG %r19,PT_SR0(%r16) << 837 STREG %r19,PT_SR1(%r16) << 838 STREG %r19,PT_SR3(%r16) << 839 STREG %r19,PT_SR4(%r16) << 840 STREG %r19,PT_SR5(%r16) << 841 STREG %r19,PT_SR6(%r16) << 842 STREG %r19,PT_SR7(%r16) << 843 << 844 ENTRY(intr_return) << 845 /* check for reschedule */ << 846 mfctl %cr30,%r1 << 847 LDREG TASK_TI_FLAGS(%r1),%r19 /* sch << 848 bb,<,n %r19,31-TIF_NEED_RESCHED,intr_ << 849 << 850 .import do_notify_resume,code << 851 intr_check_sig: << 852 /* As above */ << 853 mfctl %cr30,%r1 << 854 LDREG TASK_TI_FLAGS(%r1),%r19 << 855 ldi (_TIF_USER_WORK_MASK & ~_TIF_N << 856 and,COND(<>) %r19, %r20, %r0 << 857 b,n intr_restore /* skip past i << 858 << 859 /* This check is critical to having LW << 860 * working. The IASQ is zero on the ga << 861 * page and we cannot deliver any sign << 862 * we get off the gateway page. << 863 * 830 * 864 * Only do signals if we are returning !! 831 * value 1) Full 64-bits of AFAR 865 */ !! 832 * value 2) Low 33-bits of AFSR, then bits 33-->42 866 LDREG PT_IASQ0(%r16), %r20 !! 833 * are UDBL error status and bits 43-->52 867 cmpib,COND(=),n LINUX_GATEWAY_SPACE, % !! 834 * are UDBH error status 868 LDREG PT_IASQ1(%r16), %r20 !! 835 */ 869 cmpib,COND(=),n LINUX_GATEWAY_SPACE, % !! 836 .align 64 870 !! 837 .globl cee_trap 871 copy %r0, %r25 !! 838 cee_trap: 872 #ifdef CONFIG_64BIT !! 839 ldxa [%g0] ASI_AFSR, %g1 ! Read AFSR 873 ldo -16(%r30),%r29 !! 840 ldxa [%g0] ASI_AFAR, %g2 ! Read AFAR 874 #endif !! 841 sllx %g1, 31, %g1 ! Clear reserved bits 875 !! 842 srlx %g1, 31, %g1 ! in AFSR 876 /* NOTE: We need to enable interrupts !! 843 877 * signals. We used to do this earlier !! 844 /* NOTE: UltraSparc-I/II have high and low UDB error 878 * stack overflows. */ !! 845 * registers, corresponding to the two UDB units 879 ssm PSW_SM_I, %r0 !! 846 * present on those chips. UltraSparc-IIi only 880 !! 847 * has a single UDB, called "SDB" in the manual. 881 BL do_notify_resume,%r2 !! 848 * For IIi the upper UDB register always reads 882 copy %r16, %r26 !! 849 * as zero so for our purposes things will just 883 !! 850 * work with the checks below. 884 b,n intr_check_sig !! 851 */ 885 !! 852 ldxa [%g0] ASI_UDBL_ERROR_R, %g3 ! Read UDB-Low error status 886 intr_restore: !! 853 andcc %g3, (1 << 8), %g4 ! Check CE bit 887 copy %r16,%r29 !! 854 sllx %g3, (64 - 10), %g3 ! Clear reserved bits 888 ldo PT_FR31(%r29),%r1 !! 855 srlx %g3, (64 - 10), %g3 ! in UDB-Low error status 889 rest_fp %r1 !! 856 890 rest_general %r29 !! 857 sllx %g3, (33 + 0), %g3 ! Shift up to encoding area 891 !! 858 or %g1, %g3, %g1 ! Or it in 892 /* inverse of virt_map */ !! 859 be,pn %xcc, 1f ! Branch if CE bit was clear 893 pcxt_ssm_bug !! 860 nop 894 rsm PSW_SM_QUIET,%r0 !! 861 stxa %g4, [%g0] ASI_UDB_ERROR_W ! Clear CE sticky bit in UDBL 895 tophys_r1 %r29 !! 862 membar #Sync ! Synchronize ASI stores 896 !! 863 1: mov 0x18, %g5 ! Addr of UDB-High error status 897 /* Restore space id's and special cr's !! 864 ldxa [%g5] ASI_UDBH_ERROR_R, %g3 ! Read it 898 * structure pointed to by r29 !! 865 899 */ !! 866 andcc %g3, (1 << 8), %g4 ! Check CE bit 900 rest_specials %r29 !! 867 sllx %g3, (64 - 10), %g3 ! Clear reserved bits 901 !! 868 srlx %g3, (64 - 10), %g3 ! in UDB-High error status 902 /* IMPORTANT: rest_stack restores r29 !! 869 sllx %g3, (33 + 10), %g3 ! Shift up to encoding area 903 * It also restores r1 and r30. !! 870 or %g1, %g3, %g1 ! Or it in 904 */ !! 871 be,pn %xcc, 1f ! Branch if CE bit was clear 905 rest_stack !! 872 nop 906 !! 873 nop 907 rfi !! 874 908 nop !! 875 stxa %g4, [%g5] ASI_UDB_ERROR_W ! Clear CE sticky bit in UDBH 909 !! 876 membar #Sync ! Synchronize ASI stores 910 #ifndef CONFIG_PREEMPTION !! 877 1: mov 1, %g5 ! AFSR CE bit is 911 # define intr_do_preempt intr_restore !! 878 sllx %g5, 20, %g5 ! bit 20 912 #endif /* !CONFIG_PREEMPTION */ !! 879 stxa %g5, [%g0] ASI_AFSR ! Clear CE sticky bit in AFSR 913 !! 880 membar #Sync ! Synchronize ASI stores 914 .import schedule,code !! 881 sllx %g2, (64 - 41), %g2 ! Clear reserved bits 915 intr_do_resched: !! 882 srlx %g2, (64 - 41), %g2 ! in latched AFAR 916 /* Only call schedule on return to use !! 883 917 * to kernel space, we may schedule if !! 884 andn %g2, 0x0f, %g2 ! Finish resv bit clearing 918 * we jump back to intr_restore. !! 885 mov %g1, %g4 ! Move AFSR+UDB* into save reg 919 */ !! 886 mov %g2, %g5 ! Move AFAR into save reg 920 LDREG PT_IASQ0(%r16), %r20 !! 887 rdpr %pil, %g2 921 cmpib,COND(=) 0, %r20, intr_do_preem !! 888 wrpr %g0, 15, %pil 922 nop !! 889 ba,pt %xcc, etrap_irq 923 LDREG PT_IASQ1(%r16), %r20 !! 890 rd %pc, %g7 924 cmpib,COND(=) 0, %r20, intr_do_preem !! 891 mov %l4, %o0 925 nop !! 892 926 !! 893 mov %l5, %o1 927 /* NOTE: We need to enable interrupts !! 894 call cee_log 928 * to do this earlier but it caused ke !! 895 add %sp, PTREGS_OFF, %o2 929 ssm PSW_SM_I, %r0 !! 896 ba,a,pt %xcc, rtrap_irq 930 << 931 #ifdef CONFIG_64BIT << 932 ldo -16(%r30),%r29 /* Ref << 933 #endif << 934 << 935 ldil L%intr_check_sig, %r2 << 936 #ifndef CONFIG_64BIT << 937 b schedule << 938 #else << 939 load32 schedule, %r20 << 940 bv %r0(%r20) << 941 #endif << 942 ldo R%intr_check_sig(%r2), %r2 << 943 << 944 /* preempt the current task on returni << 945 * mode from an interrupt, iff need_re << 946 * and preempt_count is 0. otherwise, << 947 * our merry way back to the current r << 948 */ << 949 #ifdef CONFIG_PREEMPTION << 950 .import preempt_schedule_irq,code << 951 intr_do_preempt: << 952 rsm PSW_SM_I, %r0 /* dis << 953 << 954 /* current_thread_info()->preempt_coun << 955 mfctl %cr30, %r1 << 956 ldw TI_PRE_COUNT(%r1), %r19 << 957 cmpib,<> 0, %r19, intr_restore << 958 nop /* pre << 959 << 960 /* check if we interrupted a critical << 961 LDREG PT_PSW(%r16), %r20 << 962 bb,<,n %r20, 31 - PSW_SM_I, intr_rest << 963 nop << 964 << 965 /* ssm PSW_SM_I done later in intr_res << 966 #ifdef CONFIG_MLONGCALLS << 967 ldil L%intr_restore, %r2 << 968 load32 preempt_schedule_irq, %r1 << 969 bv %r0(%r1) << 970 ldo R%intr_restore(%r2), %r2 << 971 #else << 972 ldil L%intr_restore, %r1 << 973 BL preempt_schedule_irq, %r2 << 974 ldo R%intr_restore(%r1), %r2 << 975 #endif << 976 #endif /* CONFIG_PREEMPTION */ << 977 << 978 /* << 979 * External interrupts. << 980 */ << 981 << 982 intr_extint: << 983 cmpib,COND(=),n 0,%r16,1f << 984 << 985 get_stack_use_cr30 << 986 b,n 2f << 987 << 988 1: << 989 get_stack_use_r30 << 990 2: << 991 save_specials %r29 << 992 virt_map << 993 save_general %r29 << 994 897 995 ldo PT_FR0(%r29), %r24 !! 898 /* Capture I/D/E-cache state into per-cpu error scoreboard. 996 save_fp %r24 << 997 << 998 loadgp << 999 << 1000 copy %r29, %r26 /* arg0 is pt << 1001 copy %r29, %r16 /* save pt_re << 1002 << 1003 ldil L%intr_return, %r2 << 1004 << 1005 #ifdef CONFIG_64BIT << 1006 ldo -16(%r30),%r29 /* Reference << 1007 #endif << 1008 << 1009 b do_cpu_irq_mask << 1010 ldo R%intr_return(%r2), %r2 /* re << 1011 ENDPROC_CFI(syscall_exit_rfi) << 1012 << 1013 << 1014 /* Generic interruptions (illegal ins << 1015 << 1016 ENTRY_CFI(intr_save) /* for os_hpm << 1017 mfsp %sr7,%r16 << 1018 cmpib,COND(=),n 0,%r16,1f << 1019 get_stack_use_cr30 << 1020 b 2f << 1021 copy %r8,%r26 << 1022 << 1023 1: << 1024 get_stack_use_r30 << 1025 copy %r8,%r26 << 1026 << 1027 2: << 1028 save_specials %r29 << 1029 << 1030 /* If this trap is a itlb miss, skip << 1031 cmpib,COND(=),n PARISC_ITLB_TR << 1032 << 1033 << 1034 mfctl %isr, %r16 << 1035 nop /* serialize mfctl on << 1036 mfctl %ior, %r17 << 1037 << 1038 << 1039 #ifdef CONFIG_64BIT << 1040 /* << 1041 * If the interrupted code was runnin << 1042 * clear the b bits (bits 0 & 1) in t << 1043 * save_specials left ipsw value in r << 1044 */ << 1045 extrd,u,*<> %r8,PSW_W_BIT,1,%r0 << 1046 depdi 0,1,2,%r17 << 1047 << 1048 /* adjust isr/ior: get high bits from << 1049 space_adjust %r16,%r17,%r1 << 1050 #endif << 1051 STREG %r16, PT_ISR(%r29) << 1052 STREG %r17, PT_IOR(%r29) << 1053 << 1054 #if defined(CONFIG_64BIT) << 1055 b,n intr_save2 << 1056 << 1057 skip_save_ior: << 1058 /* We have a itlb miss, and when exec << 1059 * need to adjust iasq/iaoq here in t << 1060 * above. << 1061 */ << 1062 bb,COND(>=),n %r8,PSW_W_BIT,intr_sa << 1063 LDREG PT_IASQ0(%r29), %r16 << 1064 LDREG PT_IAOQ0(%r29), %r17 << 1065 /* adjust iasq/iaoq */ << 1066 space_adjust %r16,%r17,%r1 << 1067 STREG %r16, PT_IASQ0(%r29) << 1068 STREG %r17, PT_IAOQ0(%r29) << 1069 #else << 1070 skip_save_ior: << 1071 #endif << 1072 << 1073 intr_save2: << 1074 virt_map << 1075 save_general %r29 << 1076 << 1077 ldo PT_FR0(%r29), %r25 << 1078 save_fp %r25 << 1079 << 1080 loadgp << 1081 << 1082 copy %r29, %r25 /* ar << 1083 #ifdef CONFIG_64BIT << 1084 ldo -16(%r30),%r29 /* Re << 1085 #endif << 1086 << 1087 ldil L%intr_check_sig, %r2 << 1088 copy %r25, %r16 /* sa << 1089 << 1090 b handle_interruption << 1091 ldo R%intr_check_sig(%r2) << 1092 ENDPROC_CFI(intr_save) << 1093 << 1094 << 1095 /* << 1096 * Note for all tlb miss handlers: << 1097 * << 1098 * cr24 contains a pointer to the ker << 1099 * page directory. << 1100 * 899 * 1101 * cr25 contains a pointer to the cur !! 900 * %g1: (TL>=0) ? 1 : 0 1102 * space page directory. !! 901 * %g2: scratch >> 902 * %g3: scratch >> 903 * %g4: AFSR >> 904 * %g5: AFAR >> 905 * %g6: current thread ptr >> 906 * %g7: scratch >> 907 */ >> 908 #define CHEETAH_LOG_ERROR \ >> 909 /* Put "TL1" software bit into AFSR. */ \ >> 910 and %g1, 0x1, %g1; \ >> 911 sllx %g1, 63, %g2; \ >> 912 or %g4, %g2, %g4; \ >> 913 /* Get log entry pointer for this cpu at this trap level. */ \ >> 914 BRANCH_IF_JALAPENO(g2,g3,50f) \ >> 915 ldxa [%g0] ASI_SAFARI_CONFIG, %g2; \ >> 916 srlx %g2, 17, %g2; \ >> 917 ba,pt %xcc, 60f; \ >> 918 and %g2, 0x3ff, %g2; \ >> 919 50: ldxa [%g0] ASI_JBUS_CONFIG, %g2; \ >> 920 srlx %g2, 17, %g2; \ >> 921 and %g2, 0x1f, %g2; \ >> 922 60: sllx %g2, 9, %g2; \ >> 923 sethi %hi(cheetah_error_log), %g3; \ >> 924 ldx [%g3 + %lo(cheetah_error_log)], %g3; \ >> 925 brz,pn %g3, 80f; \ >> 926 nop; \ >> 927 add %g3, %g2, %g3; \ >> 928 sllx %g1, 8, %g1; \ >> 929 add %g3, %g1, %g1; \ >> 930 /* %g1 holds pointer to the top of the logging scoreboard */ \ >> 931 ldx [%g1 + 0x0], %g7; \ >> 932 cmp %g7, -1; \ >> 933 bne,pn %xcc, 80f; \ >> 934 nop; \ >> 935 stx %g4, [%g1 + 0x0]; \ >> 936 stx %g5, [%g1 + 0x8]; \ >> 937 add %g1, 0x10, %g1; \ >> 938 /* %g1 now points to D-cache logging area */ \ >> 939 set 0x3ff8, %g2; /* DC_addr mask */ \ >> 940 and %g5, %g2, %g2; /* DC_addr bits of AFAR */ \ >> 941 srlx %g5, 12, %g3; \ >> 942 or %g3, 1, %g3; /* PHYS tag + valid */ \ >> 943 10: ldxa [%g2] ASI_DCACHE_TAG, %g7; \ >> 944 cmp %g3, %g7; /* TAG match? */ \ >> 945 bne,pt %xcc, 13f; \ >> 946 nop; \ >> 947 /* Yep, what we want, capture state. */ \ >> 948 stx %g2, [%g1 + 0x20]; \ >> 949 stx %g7, [%g1 + 0x28]; \ >> 950 /* A membar Sync is required before and after utag access. */ \ >> 951 membar #Sync; \ >> 952 ldxa [%g2] ASI_DCACHE_UTAG, %g7; \ >> 953 membar #Sync; \ >> 954 stx %g7, [%g1 + 0x30]; \ >> 955 ldxa [%g2] ASI_DCACHE_SNOOP_TAG, %g7; \ >> 956 stx %g7, [%g1 + 0x38]; \ >> 957 clr %g3; \ >> 958 12: ldxa [%g2 + %g3] ASI_DCACHE_DATA, %g7; \ >> 959 stx %g7, [%g1]; \ >> 960 add %g3, (1 << 5), %g3; \ >> 961 cmp %g3, (4 << 5); \ >> 962 bl,pt %xcc, 12b; \ >> 963 add %g1, 0x8, %g1; \ >> 964 ba,pt %xcc, 20f; \ >> 965 add %g1, 0x20, %g1; \ >> 966 13: sethi %hi(1 << 14), %g7; \ >> 967 add %g2, %g7, %g2; \ >> 968 srlx %g2, 14, %g7; \ >> 969 cmp %g7, 4; \ >> 970 bl,pt %xcc, 10b; \ >> 971 nop; \ >> 972 add %g1, 0x40, %g1; \ >> 973 20: /* %g1 now points to I-cache logging area */ \ >> 974 set 0x1fe0, %g2; /* IC_addr mask */ \ >> 975 and %g5, %g2, %g2; /* IC_addr bits of AFAR */ \ >> 976 sllx %g2, 1, %g2; /* IC_addr[13:6]==VA[12:5] */ \ >> 977 srlx %g5, (13 - 8), %g3; /* Make PTAG */ \ >> 978 andn %g3, 0xff, %g3; /* Mask off undefined bits */ \ >> 979 21: ldxa [%g2] ASI_IC_TAG, %g7; \ >> 980 andn %g7, 0xff, %g7; \ >> 981 cmp %g3, %g7; \ >> 982 bne,pt %xcc, 23f; \ >> 983 nop; \ >> 984 /* Yep, what we want, capture state. */ \ >> 985 stx %g2, [%g1 + 0x40]; \ >> 986 stx %g7, [%g1 + 0x48]; \ >> 987 add %g2, (1 << 3), %g2; \ >> 988 ldxa [%g2] ASI_IC_TAG, %g7; \ >> 989 add %g2, (1 << 3), %g2; \ >> 990 stx %g7, [%g1 + 0x50]; \ >> 991 ldxa [%g2] ASI_IC_TAG, %g7; \ >> 992 add %g2, (1 << 3), %g2; \ >> 993 stx %g7, [%g1 + 0x60]; \ >> 994 ldxa [%g2] ASI_IC_TAG, %g7; \ >> 995 stx %g7, [%g1 + 0x68]; \ >> 996 sub %g2, (3 << 3), %g2; \ >> 997 ldxa [%g2] ASI_IC_STAG, %g7; \ >> 998 stx %g7, [%g1 + 0x58]; \ >> 999 clr %g3; \ >> 1000 srlx %g2, 2, %g2; \ >> 1001 22: ldxa [%g2 + %g3] ASI_IC_INSTR, %g7; \ >> 1002 stx %g7, [%g1]; \ >> 1003 add %g3, (1 << 3), %g3; \ >> 1004 cmp %g3, (8 << 3); \ >> 1005 bl,pt %xcc, 22b; \ >> 1006 add %g1, 0x8, %g1; \ >> 1007 ba,pt %xcc, 30f; \ >> 1008 add %g1, 0x30, %g1; \ >> 1009 23: sethi %hi(1 << 14), %g7; \ >> 1010 add %g2, %g7, %g2; \ >> 1011 srlx %g2, 14, %g7; \ >> 1012 cmp %g7, 4; \ >> 1013 bl,pt %xcc, 21b; \ >> 1014 nop; \ >> 1015 add %g1, 0x70, %g1; \ >> 1016 30: /* %g1 now points to E-cache logging area */ \ >> 1017 andn %g5, (32 - 1), %g2; /* E-cache subblock */ \ >> 1018 stx %g2, [%g1 + 0x20]; \ >> 1019 ldxa [%g2] ASI_EC_TAG_DATA, %g7; \ >> 1020 stx %g7, [%g1 + 0x28]; \ >> 1021 ldxa [%g2] ASI_EC_R, %g0; \ >> 1022 clr %g3; \ >> 1023 31: ldxa [%g3] ASI_EC_DATA, %g7; \ >> 1024 stx %g7, [%g1 + %g3]; \ >> 1025 add %g3, 0x8, %g3; \ >> 1026 cmp %g3, 0x20; \ >> 1027 bl,pt %xcc, 31b; \ >> 1028 nop; \ >> 1029 80: /* DONE */ >> 1030 >> 1031 /* These get patched into the trap table at boot time >> 1032 * once we know we have a cheetah processor. >> 1033 */ >> 1034 .globl cheetah_fecc_trap_vector, cheetah_fecc_trap_vector_tl1 >> 1035 cheetah_fecc_trap_vector: >> 1036 membar #Sync >> 1037 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1 >> 1038 andn %g1, DCU_DC | DCU_IC, %g1 >> 1039 stxa %g1, [%g0] ASI_DCU_CONTROL_REG >> 1040 membar #Sync >> 1041 sethi %hi(cheetah_fast_ecc), %g2 >> 1042 jmpl %g2 + %lo(cheetah_fast_ecc), %g0 >> 1043 mov 0, %g1 >> 1044 cheetah_fecc_trap_vector_tl1: >> 1045 membar #Sync >> 1046 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1 >> 1047 andn %g1, DCU_DC | DCU_IC, %g1 >> 1048 stxa %g1, [%g0] ASI_DCU_CONTROL_REG >> 1049 membar #Sync >> 1050 sethi %hi(cheetah_fast_ecc), %g2 >> 1051 jmpl %g2 + %lo(cheetah_fast_ecc), %g0 >> 1052 mov 1, %g1 >> 1053 .globl cheetah_cee_trap_vector, cheetah_cee_trap_vector_tl1 >> 1054 cheetah_cee_trap_vector: >> 1055 membar #Sync >> 1056 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1 >> 1057 andn %g1, DCU_IC, %g1 >> 1058 stxa %g1, [%g0] ASI_DCU_CONTROL_REG >> 1059 membar #Sync >> 1060 sethi %hi(cheetah_cee), %g2 >> 1061 jmpl %g2 + %lo(cheetah_cee), %g0 >> 1062 mov 0, %g1 >> 1063 cheetah_cee_trap_vector_tl1: >> 1064 membar #Sync >> 1065 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1 >> 1066 andn %g1, DCU_IC, %g1 >> 1067 stxa %g1, [%g0] ASI_DCU_CONTROL_REG >> 1068 membar #Sync >> 1069 sethi %hi(cheetah_cee), %g2 >> 1070 jmpl %g2 + %lo(cheetah_cee), %g0 >> 1071 mov 1, %g1 >> 1072 .globl cheetah_deferred_trap_vector, cheetah_deferred_trap_vector_tl1 >> 1073 cheetah_deferred_trap_vector: >> 1074 membar #Sync >> 1075 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1; >> 1076 andn %g1, DCU_DC | DCU_IC, %g1; >> 1077 stxa %g1, [%g0] ASI_DCU_CONTROL_REG; >> 1078 membar #Sync; >> 1079 sethi %hi(cheetah_deferred_trap), %g2 >> 1080 jmpl %g2 + %lo(cheetah_deferred_trap), %g0 >> 1081 mov 0, %g1 >> 1082 cheetah_deferred_trap_vector_tl1: >> 1083 membar #Sync; >> 1084 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1; >> 1085 andn %g1, DCU_DC | DCU_IC, %g1; >> 1086 stxa %g1, [%g0] ASI_DCU_CONTROL_REG; >> 1087 membar #Sync; >> 1088 sethi %hi(cheetah_deferred_trap), %g2 >> 1089 jmpl %g2 + %lo(cheetah_deferred_trap), %g0 >> 1090 mov 1, %g1 >> 1091 >> 1092 /* Cheetah+ specific traps. These are for the new I/D cache parity >> 1093 * error traps. The first argument to cheetah_plus_parity_handler >> 1094 * is encoded as follows: 1103 * 1095 * 1104 * sr3 will contain the space id of t !! 1096 * Bit0: 0=dcache,1=icache 1105 * of the current running thread whil !! 1097 * Bit1: 0=recoverable,1=unrecoverable 1106 * running in the kernel. << 1107 */ << 1108 << 1109 /* << 1110 * register number allocations. Note << 1111 * in the shadowed registers << 1112 */ 1098 */ 1113 !! 1099 .globl cheetah_plus_dcpe_trap_vector, cheetah_plus_dcpe_trap_vector_tl1 1114 t0 = r1 /* temporary register !! 1100 cheetah_plus_dcpe_trap_vector: 1115 va = r8 /* virtual address fo !! 1101 membar #Sync 1116 t1 = r9 /* temporary register !! 1102 sethi %hi(do_cheetah_plus_data_parity), %g7 1117 pte = r16 /* pte/phys page # */ !! 1103 jmpl %g7 + %lo(do_cheetah_plus_data_parity), %g0 1118 prot = r17 /* prot bits */ !! 1104 nop 1119 spc = r24 /* space for which th << 1120 ptp = r25 /* page directory/pag << 1121 << 1122 #ifdef CONFIG_64BIT << 1123 << 1124 dtlb_miss_20w: << 1125 space_adjust spc,va,t0 << 1126 get_pgd spc,ptp << 1127 space_check spc,t0,dtlb_fault << 1128 << 1129 L3_ptep ptp,pte,t0,va,dtlb_ch << 1130 << 1131 ptl_lock spc,ptp,pte,t0,t1,dtl << 1132 update_accessed ptp,pte,t0,t1 << 1133 << 1134 make_insert_tlb spc,pte,prot,t1 << 1135 << 1136 idtlbt pte,prot << 1137 << 1138 ptl_unlock spc,t0,t1 << 1139 rfir << 1140 nop 1105 nop 1141 << 1142 dtlb_check_alias_20w: << 1143 do_alias spc,t0,t1,va,pte,prot << 1144 << 1145 idtlbt pte,prot << 1146 << 1147 insert_nops NUM_PIPELINE_INSNS - << 1148 rfir << 1149 nop 1106 nop 1150 << 1151 nadtlb_miss_20w: << 1152 space_adjust spc,va,t0 << 1153 get_pgd spc,ptp << 1154 space_check spc,t0,nadtlb_fault << 1155 << 1156 L3_ptep ptp,pte,t0,va,nadtlb_ << 1157 << 1158 ptl_lock spc,ptp,pte,t0,t1,nad << 1159 update_accessed ptp,pte,t0,t1 << 1160 << 1161 make_insert_tlb spc,pte,prot,t1 << 1162 << 1163 idtlbt pte,prot << 1164 << 1165 ptl_unlock spc,t0,t1 << 1166 rfir << 1167 nop 1107 nop 1168 << 1169 nadtlb_check_alias_20w: << 1170 do_alias spc,t0,t1,va,pte,prot << 1171 << 1172 idtlbt pte,prot << 1173 << 1174 insert_nops NUM_PIPELINE_INSNS - << 1175 rfir << 1176 nop 1108 nop 1177 1109 1178 #else !! 1110 do_cheetah_plus_data_parity: 1179 !! 1111 ba,pt %xcc, etrap 1180 dtlb_miss_11: !! 1112 rd %pc, %g7 1181 get_pgd spc,ptp !! 1113 mov 0x0, %o0 1182 !! 1114 call cheetah_plus_parity_error 1183 space_check spc,t0,dtlb_fault !! 1115 add %sp, PTREGS_OFF, %o1 1184 !! 1116 ba,pt %xcc, rtrap 1185 L2_ptep ptp,pte,t0,va,dtlb_ch !! 1117 clr %l6 1186 !! 1118 1187 ptl_lock spc,ptp,pte,t0,t1,dtl !! 1119 cheetah_plus_dcpe_trap_vector_tl1: 1188 update_accessed ptp,pte,t0,t1 !! 1120 membar #Sync 1189 !! 1121 wrpr PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate 1190 make_insert_tlb_11 spc,pte,prot !! 1122 sethi %hi(do_dcpe_tl1), %g3 1191 !! 1123 jmpl %g3 + %lo(do_dcpe_tl1), %g0 1192 mfsp %sr1,t1 /* Save sr1 !! 1124 nop 1193 mtsp spc,%sr1 !! 1125 nop 1194 !! 1126 nop 1195 idtlba pte,(%sr1,va) !! 1127 nop 1196 idtlbp prot,(%sr1,va) !! 1128 1197 !! 1129 .globl cheetah_plus_icpe_trap_vector, cheetah_plus_icpe_trap_vector_tl1 1198 mtsp t1, %sr1 /* Re !! 1130 cheetah_plus_icpe_trap_vector: 1199 !! 1131 membar #Sync 1200 ptl_unlock spc,t0,t1 !! 1132 sethi %hi(do_cheetah_plus_insn_parity), %g7 1201 rfir !! 1133 jmpl %g7 + %lo(do_cheetah_plus_insn_parity), %g0 1202 nop !! 1134 nop 1203 << 1204 dtlb_check_alias_11: << 1205 do_alias spc,t0,t1,va,pte,prot << 1206 << 1207 idtlba pte,(va) << 1208 idtlbp prot,(va) << 1209 << 1210 insert_nops NUM_PIPELINE_INSNS - << 1211 rfir << 1212 nop << 1213 << 1214 nadtlb_miss_11: << 1215 get_pgd spc,ptp << 1216 << 1217 space_check spc,t0,nadtlb_fault << 1218 << 1219 L2_ptep ptp,pte,t0,va,nadtlb_ << 1220 << 1221 ptl_lock spc,ptp,pte,t0,t1,nad << 1222 update_accessed ptp,pte,t0,t1 << 1223 << 1224 make_insert_tlb_11 spc,pte,prot << 1225 << 1226 mfsp %sr1,t1 /* Save sr1 << 1227 mtsp spc,%sr1 << 1228 << 1229 idtlba pte,(%sr1,va) << 1230 idtlbp prot,(%sr1,va) << 1231 << 1232 mtsp t1, %sr1 /* Re << 1233 << 1234 ptl_unlock spc,t0,t1 << 1235 rfir << 1236 nop << 1237 << 1238 nadtlb_check_alias_11: << 1239 do_alias spc,t0,t1,va,pte,prot << 1240 << 1241 idtlba pte,(va) << 1242 idtlbp prot,(va) << 1243 << 1244 insert_nops NUM_PIPELINE_INSNS - << 1245 rfir << 1246 nop << 1247 << 1248 dtlb_miss_20: << 1249 space_adjust spc,va,t0 << 1250 get_pgd spc,ptp << 1251 space_check spc,t0,dtlb_fault << 1252 << 1253 L2_ptep ptp,pte,t0,va,dtlb_ch << 1254 << 1255 ptl_lock spc,ptp,pte,t0,t1,dtl << 1256 update_accessed ptp,pte,t0,t1 << 1257 << 1258 make_insert_tlb spc,pte,prot,t1 << 1259 << 1260 f_extend pte,t1 << 1261 << 1262 idtlbt pte,prot << 1263 << 1264 ptl_unlock spc,t0,t1 << 1265 rfir << 1266 nop << 1267 << 1268 dtlb_check_alias_20: << 1269 do_alias spc,t0,t1,va,pte,prot << 1270 << 1271 idtlbt pte,prot << 1272 << 1273 insert_nops NUM_PIPELINE_INSNS - << 1274 rfir << 1275 nop << 1276 << 1277 nadtlb_miss_20: << 1278 get_pgd spc,ptp << 1279 << 1280 space_check spc,t0,nadtlb_fault << 1281 << 1282 L2_ptep ptp,pte,t0,va,nadtlb_ << 1283 << 1284 ptl_lock spc,ptp,pte,t0,t1,nad << 1285 update_accessed ptp,pte,t0,t1 << 1286 << 1287 make_insert_tlb spc,pte,prot,t1 << 1288 << 1289 f_extend pte,t1 << 1290 << 1291 idtlbt pte,prot << 1292 << 1293 ptl_unlock spc,t0,t1 << 1294 rfir << 1295 nop << 1296 << 1297 nadtlb_check_alias_20: << 1298 do_alias spc,t0,t1,va,pte,prot << 1299 << 1300 idtlbt pte,prot << 1301 << 1302 insert_nops NUM_PIPELINE_INSNS - << 1303 rfir << 1304 nop << 1305 << 1306 #endif << 1307 << 1308 nadtlb_emulate: << 1309 << 1310 /* << 1311 * Non-access misses can be caused by << 1312 * probei instructions. The kernel no << 1313 * Use of lpa and probe instructions << 1314 * with shadow registers, we defer ev << 1315 */ << 1316 b,n nadtlb_fault << 1317 << 1318 #ifdef CONFIG_64BIT << 1319 itlb_miss_20w: << 1320 << 1321 /* << 1322 * I miss is a little different, sinc << 1323 * on the gateway page which is in th << 1324 */ << 1325 << 1326 space_adjust spc,va,t0 << 1327 get_pgd spc,ptp << 1328 space_check spc,t0,itlb_fault << 1329 << 1330 L3_ptep ptp,pte,t0,va,itlb_fa << 1331 << 1332 ptl_lock spc,ptp,pte,t0,t1,itl << 1333 update_accessed ptp,pte,t0,t1 << 1334 << 1335 make_insert_tlb spc,pte,prot,t1 << 1336 << 1337 iitlbt pte,prot << 1338 << 1339 ptl_unlock spc,t0,t1 << 1340 rfir << 1341 nop << 1342 << 1343 naitlb_miss_20w: << 1344 << 1345 /* << 1346 * I miss is a little different, sinc << 1347 * on the gateway page which is in th << 1348 */ << 1349 << 1350 space_adjust spc,va,t0 << 1351 get_pgd spc,ptp << 1352 space_check spc,t0,naitlb_fault << 1353 << 1354 L3_ptep ptp,pte,t0,va,naitlb_ << 1355 << 1356 ptl_lock spc,ptp,pte,t0,t1,nai << 1357 update_accessed ptp,pte,t0,t1 << 1358 << 1359 make_insert_tlb spc,pte,prot,t1 << 1360 << 1361 iitlbt pte,prot << 1362 << 1363 ptl_unlock spc,t0,t1 << 1364 rfir << 1365 nop << 1366 << 1367 naitlb_check_alias_20w: << 1368 do_alias spc,t0,t1,va,pte,prot << 1369 << 1370 iitlbt pte,prot << 1371 << 1372 insert_nops NUM_PIPELINE_INSNS - << 1373 rfir << 1374 nop << 1375 << 1376 #else << 1377 << 1378 itlb_miss_11: << 1379 get_pgd spc,ptp << 1380 << 1381 space_check spc,t0,itlb_fault << 1382 << 1383 L2_ptep ptp,pte,t0,va,itlb_fa << 1384 << 1385 ptl_lock spc,ptp,pte,t0,t1,itl << 1386 update_accessed ptp,pte,t0,t1 << 1387 << 1388 make_insert_tlb_11 spc,pte,prot << 1389 << 1390 mfsp %sr1,t1 /* Save sr1 << 1391 mtsp spc,%sr1 << 1392 << 1393 iitlba pte,(%sr1,va) << 1394 iitlbp prot,(%sr1,va) << 1395 << 1396 mtsp t1, %sr1 /* Re << 1397 << 1398 ptl_unlock spc,t0,t1 << 1399 rfir << 1400 nop << 1401 << 1402 naitlb_miss_11: << 1403 get_pgd spc,ptp << 1404 << 1405 space_check spc,t0,naitlb_fault << 1406 << 1407 L2_ptep ptp,pte,t0,va,naitlb_ << 1408 << 1409 ptl_lock spc,ptp,pte,t0,t1,nai << 1410 update_accessed ptp,pte,t0,t1 << 1411 << 1412 make_insert_tlb_11 spc,pte,prot << 1413 << 1414 mfsp %sr1,t1 /* Save sr1 << 1415 mtsp spc,%sr1 << 1416 << 1417 iitlba pte,(%sr1,va) << 1418 iitlbp prot,(%sr1,va) << 1419 << 1420 mtsp t1, %sr1 /* Re << 1421 << 1422 ptl_unlock spc,t0,t1 << 1423 rfir << 1424 nop << 1425 << 1426 naitlb_check_alias_11: << 1427 do_alias spc,t0,t1,va,pte,prot << 1428 << 1429 iitlba pte,(%sr0, va) << 1430 iitlbp prot,(%sr0, va) << 1431 << 1432 insert_nops NUM_PIPELINE_INSNS - << 1433 rfir << 1434 nop << 1435 << 1436 << 1437 itlb_miss_20: << 1438 get_pgd spc,ptp << 1439 << 1440 space_check spc,t0,itlb_fault << 1441 << 1442 L2_ptep ptp,pte,t0,va,itlb_fa << 1443 << 1444 ptl_lock spc,ptp,pte,t0,t1,itl << 1445 update_accessed ptp,pte,t0,t1 << 1446 << 1447 make_insert_tlb spc,pte,prot,t1 << 1448 << 1449 f_extend pte,t1 << 1450 << 1451 iitlbt pte,prot << 1452 << 1453 ptl_unlock spc,t0,t1 << 1454 rfir << 1455 nop 1135 nop 1456 << 1457 naitlb_miss_20: << 1458 get_pgd spc,ptp << 1459 << 1460 space_check spc,t0,naitlb_fault << 1461 << 1462 L2_ptep ptp,pte,t0,va,naitlb_ << 1463 << 1464 ptl_lock spc,ptp,pte,t0,t1,nai << 1465 update_accessed ptp,pte,t0,t1 << 1466 << 1467 make_insert_tlb spc,pte,prot,t1 << 1468 << 1469 f_extend pte,t1 << 1470 << 1471 iitlbt pte,prot << 1472 << 1473 ptl_unlock spc,t0,t1 << 1474 rfir << 1475 nop 1136 nop 1476 << 1477 naitlb_check_alias_20: << 1478 do_alias spc,t0,t1,va,pte,prot << 1479 << 1480 iitlbt pte,prot << 1481 << 1482 insert_nops NUM_PIPELINE_INSNS - << 1483 rfir << 1484 nop << 1485 << 1486 #endif << 1487 << 1488 #ifdef CONFIG_64BIT << 1489 << 1490 dbit_trap_20w: << 1491 space_adjust spc,va,t0 << 1492 get_pgd spc,ptp << 1493 space_check spc,t0,dbit_fault << 1494 << 1495 L3_ptep ptp,pte,t0,va,dbit_fa << 1496 << 1497 ptl_lock spc,ptp,pte,t0,t1,dbi << 1498 update_dirty ptp,pte,t1 << 1499 << 1500 make_insert_tlb spc,pte,prot,t1 << 1501 << 1502 idtlbt pte,prot << 1503 << 1504 ptl_unlock spc,t0,t1 << 1505 rfir << 1506 nop 1137 nop 1507 #else << 1508 << 1509 dbit_trap_11: << 1510 << 1511 get_pgd spc,ptp << 1512 << 1513 space_check spc,t0,dbit_fault << 1514 << 1515 L2_ptep ptp,pte,t0,va,dbit_fa << 1516 << 1517 ptl_lock spc,ptp,pte,t0,t1,dbi << 1518 update_dirty ptp,pte,t1 << 1519 << 1520 make_insert_tlb_11 spc,pte,prot << 1521 << 1522 mfsp %sr1,t1 /* Save sr1 << 1523 mtsp spc,%sr1 << 1524 << 1525 idtlba pte,(%sr1,va) << 1526 idtlbp prot,(%sr1,va) << 1527 << 1528 mtsp t1, %sr1 /* Resto << 1529 << 1530 ptl_unlock spc,t0,t1 << 1531 rfir << 1532 nop 1138 nop 1533 1139 1534 dbit_trap_20: !! 1140 do_cheetah_plus_insn_parity: 1535 get_pgd spc,ptp !! 1141 ba,pt %xcc, etrap 1536 !! 1142 rd %pc, %g7 1537 space_check spc,t0,dbit_fault !! 1143 mov 0x1, %o0 1538 !! 1144 call cheetah_plus_parity_error 1539 L2_ptep ptp,pte,t0,va,dbit_fa !! 1145 add %sp, PTREGS_OFF, %o1 1540 !! 1146 ba,pt %xcc, rtrap 1541 ptl_lock spc,ptp,pte,t0,t1,dbi !! 1147 clr %l6 1542 update_dirty ptp,pte,t1 !! 1148 1543 !! 1149 cheetah_plus_icpe_trap_vector_tl1: 1544 make_insert_tlb spc,pte,prot,t1 !! 1150 membar #Sync 1545 !! 1151 wrpr PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate 1546 f_extend pte,t1 !! 1152 sethi %hi(do_icpe_tl1), %g3 >> 1153 jmpl %g3 + %lo(do_icpe_tl1), %g0 >> 1154 nop >> 1155 nop >> 1156 nop >> 1157 nop >> 1158 >> 1159 /* If we take one of these traps when tl >= 1, then we >> 1160 * jump to interrupt globals. If some trap level above us >> 1161 * was also using interrupt globals, we cannot recover. >> 1162 * We may use all interrupt global registers except %g6. >> 1163 */ >> 1164 .globl do_dcpe_tl1, do_icpe_tl1 >> 1165 do_dcpe_tl1: >> 1166 rdpr %tl, %g1 ! Save original trap level >> 1167 mov 1, %g2 ! Setup TSTATE checking loop >> 1168 sethi %hi(TSTATE_IG), %g3 ! TSTATE mask bit >> 1169 1: wrpr %g2, %tl ! Set trap level to check >> 1170 rdpr %tstate, %g4 ! Read TSTATE for this level >> 1171 andcc %g4, %g3, %g0 ! Interrupt globals in use? >> 1172 bne,a,pn %xcc, do_dcpe_tl1_fatal ! Yep, irrecoverable >> 1173 wrpr %g1, %tl ! Restore original trap level >> 1174 add %g2, 1, %g2 ! Next trap level >> 1175 cmp %g2, %g1 ! Hit them all yet? >> 1176 ble,pt %icc, 1b ! Not yet >> 1177 nop >> 1178 wrpr %g1, %tl ! Restore original trap level >> 1179 do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ >> 1180 /* Reset D-cache parity */ >> 1181 sethi %hi(1 << 16), %g1 ! D-cache size >> 1182 mov (1 << 5), %g2 ! D-cache line size >> 1183 sub %g1, %g2, %g1 ! Move down 1 cacheline >> 1184 1: srl %g1, 14, %g3 ! Compute UTAG >> 1185 membar #Sync >> 1186 stxa %g3, [%g1] ASI_DCACHE_UTAG >> 1187 membar #Sync >> 1188 sub %g2, 8, %g3 ! 64-bit data word within line >> 1189 2: membar #Sync >> 1190 stxa %g0, [%g1 + %g3] ASI_DCACHE_DATA >> 1191 membar #Sync >> 1192 subcc %g3, 8, %g3 ! Next 64-bit data word >> 1193 bge,pt %icc, 2b >> 1194 nop >> 1195 subcc %g1, %g2, %g1 ! Next cacheline >> 1196 bge,pt %icc, 1b >> 1197 nop >> 1198 ba,pt %xcc, dcpe_icpe_tl1_common >> 1199 nop >> 1200 >> 1201 do_dcpe_tl1_fatal: >> 1202 sethi %hi(1f), %g7 >> 1203 ba,pt %xcc, etraptl1 >> 1204 1: or %g7, %lo(1b), %g7 >> 1205 mov 0x2, %o0 >> 1206 call cheetah_plus_parity_error >> 1207 add %sp, PTREGS_OFF, %o1 >> 1208 ba,pt %xcc, rtrap >> 1209 clr %l6 >> 1210 >> 1211 do_icpe_tl1: >> 1212 rdpr %tl, %g1 ! Save original trap level >> 1213 mov 1, %g2 ! Setup TSTATE checking loop >> 1214 sethi %hi(TSTATE_IG), %g3 ! TSTATE mask bit >> 1215 1: wrpr %g2, %tl ! Set trap level to check >> 1216 rdpr %tstate, %g4 ! Read TSTATE for this level >> 1217 andcc %g4, %g3, %g0 ! Interrupt globals in use? >> 1218 bne,a,pn %xcc, do_icpe_tl1_fatal ! Yep, irrecoverable >> 1219 wrpr %g1, %tl ! Restore original trap level >> 1220 add %g2, 1, %g2 ! Next trap level >> 1221 cmp %g2, %g1 ! Hit them all yet? >> 1222 ble,pt %icc, 1b ! Not yet >> 1223 nop >> 1224 wrpr %g1, %tl ! Restore original trap level >> 1225 do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ >> 1226 /* Flush I-cache */ >> 1227 sethi %hi(1 << 15), %g1 ! I-cache size >> 1228 mov (1 << 5), %g2 ! I-cache line size >> 1229 sub %g1, %g2, %g1 >> 1230 1: or %g1, (2 << 3), %g3 >> 1231 stxa %g0, [%g3] ASI_IC_TAG >> 1232 membar #Sync >> 1233 subcc %g1, %g2, %g1 >> 1234 bge,pt %icc, 1b >> 1235 nop >> 1236 ba,pt %xcc, dcpe_icpe_tl1_common >> 1237 nop >> 1238 >> 1239 do_icpe_tl1_fatal: >> 1240 sethi %hi(1f), %g7 >> 1241 ba,pt %xcc, etraptl1 >> 1242 1: or %g7, %lo(1b), %g7 >> 1243 mov 0x3, %o0 >> 1244 call cheetah_plus_parity_error >> 1245 add %sp, PTREGS_OFF, %o1 >> 1246 ba,pt %xcc, rtrap >> 1247 clr %l6 1547 1248 1548 idtlbt pte,prot !! 1249 dcpe_icpe_tl1_common: 1549 !! 1250 /* Flush D-cache, re-enable D/I caches in DCU and finally 1550 ptl_unlock spc,t0,t1 !! 1251 * retry the trapping instruction. 1551 rfir !! 1252 */ 1552 nop !! 1253 sethi %hi(1 << 16), %g1 ! D-cache size 1553 #endif !! 1254 mov (1 << 5), %g2 ! D-cache line size 1554 !! 1255 sub %g1, %g2, %g1 1555 .import handle_interruption,code !! 1256 1: stxa %g0, [%g1] ASI_DCACHE_TAG 1556 !! 1257 membar #Sync 1557 kernel_bad_space: !! 1258 subcc %g1, %g2, %g1 1558 b intr_save !! 1259 bge,pt %icc, 1b 1559 ldi 31,%r8 /* Use an unu !! 1260 nop 1560 !! 1261 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1 1561 dbit_fault: !! 1262 or %g1, (DCU_DC | DCU_IC), %g1 1562 b intr_save !! 1263 stxa %g1, [%g0] ASI_DCU_CONTROL_REG 1563 ldi 20,%r8 !! 1264 membar #Sync 1564 !! 1265 retry 1565 itlb_fault: !! 1266 1566 b intr_save !! 1267 /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc 1567 ldi PARISC_ITLB_TRAP,%r8 !! 1268 * in the trap table. That code has done a memory barrier 1568 !! 1269 * and has disabled both the I-cache and D-cache in the DCU 1569 nadtlb_fault: !! 1270 * control register. The I-cache is disabled so that we may 1570 b intr_save !! 1271 * capture the corrupted cache line, and the D-cache is disabled 1571 ldi 17,%r8 !! 1272 * because corrupt data may have been placed there and we don't 1572 !! 1273 * want to reference it. 1573 naitlb_fault: << 1574 b intr_save << 1575 ldi 16,%r8 << 1576 << 1577 dtlb_fault: << 1578 b intr_save << 1579 ldi 15,%r8 << 1580 << 1581 /* Register saving semantics for syst << 1582 << 1583 %r1 clobbered by syste << 1584 %r2 saved in PT_REGS b << 1585 %r3 - %r18 preserved by C cod << 1586 %r19 - %r20 saved in PT_REGS b << 1587 %r21 - %r22 non-standard sysca << 1588 stored in kernel s << 1589 %r23 - %r26 arg3-arg0, saved i << 1590 %r27 - %r30 saved in PT_REGS b << 1591 %r31 syscall return poi << 1592 */ << 1593 << 1594 /* Floating point registers (FIXME: w << 1595 << 1596 %fr0 - %fr3 status/exception, << 1597 %fr4 - %fr7 arguments << 1598 %fr8 - %fr11 not preserved by C << 1599 %fr12 - %fr21 preserved by C cod << 1600 %fr22 - %fr31 not preserved by C << 1601 */ << 1602 << 1603 .macro reg_save regs << 1604 STREG %r3, PT_GR3(\regs) << 1605 STREG %r4, PT_GR4(\regs) << 1606 STREG %r5, PT_GR5(\regs) << 1607 STREG %r6, PT_GR6(\regs) << 1608 STREG %r7, PT_GR7(\regs) << 1609 STREG %r8, PT_GR8(\regs) << 1610 STREG %r9, PT_GR9(\regs) << 1611 STREG %r10,PT_GR10(\regs) << 1612 STREG %r11,PT_GR11(\regs) << 1613 STREG %r12,PT_GR12(\regs) << 1614 STREG %r13,PT_GR13(\regs) << 1615 STREG %r14,PT_GR14(\regs) << 1616 STREG %r15,PT_GR15(\regs) << 1617 STREG %r16,PT_GR16(\regs) << 1618 STREG %r17,PT_GR17(\regs) << 1619 STREG %r18,PT_GR18(\regs) << 1620 .endm << 1621 << 1622 .macro reg_restore regs << 1623 LDREG PT_GR3(\regs), %r3 << 1624 LDREG PT_GR4(\regs), %r4 << 1625 LDREG PT_GR5(\regs), %r5 << 1626 LDREG PT_GR6(\regs), %r6 << 1627 LDREG PT_GR7(\regs), %r7 << 1628 LDREG PT_GR8(\regs), %r8 << 1629 LDREG PT_GR9(\regs), %r9 << 1630 LDREG PT_GR10(\regs),%r10 << 1631 LDREG PT_GR11(\regs),%r11 << 1632 LDREG PT_GR12(\regs),%r12 << 1633 LDREG PT_GR13(\regs),%r13 << 1634 LDREG PT_GR14(\regs),%r14 << 1635 LDREG PT_GR15(\regs),%r15 << 1636 LDREG PT_GR16(\regs),%r16 << 1637 LDREG PT_GR17(\regs),%r17 << 1638 LDREG PT_GR18(\regs),%r18 << 1639 .endm << 1640 << 1641 .macro fork_like name << 1642 ENTRY_CFI(sys_\name\()_wrapper) << 1643 mfctl %cr30,%r1 << 1644 ldo TASK_REGS(%r1),%r1 << 1645 reg_save %r1 << 1646 mfctl %cr27, %r28 << 1647 ldil L%sys_\name, %r31 << 1648 be R%sys_\name(%sr4,%r31) << 1649 STREG %r28, PT_CR27(%r1) << 1650 ENDPROC_CFI(sys_\name\()_wrapper) << 1651 .endm << 1652 << 1653 fork_like clone << 1654 fork_like clone3 << 1655 fork_like fork << 1656 fork_like vfork << 1657 << 1658 /* Set the return value for the child << 1659 ENTRY(child_return) << 1660 BL schedule_tail, %r2 << 1661 nop << 1662 finish_child_return: << 1663 mfctl %cr30,%r1 << 1664 ldo TASK_REGS(%r1),%r1 /* g << 1665 << 1666 LDREG PT_CR27(%r1), %r3 << 1667 mtctl %r3, %cr27 << 1668 reg_restore %r1 << 1669 b syscall_exit << 1670 copy %r0,%r28 << 1671 END(child_return) << 1672 << 1673 ENTRY_CFI(sys_rt_sigreturn_wrapper) << 1674 mfctl %cr30,%r26 << 1675 ldo TASK_REGS(%r26),%r26 /* ge << 1676 /* Don't save regs, we are going to r << 1677 STREG %r2, -RP_OFFSET(%r30) << 1678 #ifdef CONFIG_64BIT << 1679 ldo FRAME_SIZE(%r30), %r30 << 1680 BL sys_rt_sigreturn,%r2 << 1681 ldo -16(%r30),%r29 /* Re << 1682 #else << 1683 BL sys_rt_sigreturn,%r2 << 1684 ldo FRAME_SIZE(%r30), %r30 << 1685 #endif << 1686 << 1687 ldo -FRAME_SIZE(%r30), %r30 << 1688 LDREG -RP_OFFSET(%r30), %r2 << 1689 << 1690 /* FIXME: I think we need to restore << 1691 mfctl %cr30,%r1 << 1692 ldo TASK_REGS(%r1),%r1 /* ge << 1693 reg_restore %r1 << 1694 << 1695 /* If the signal was received while t << 1696 * syscall, then r2 will take us to s << 1697 * take us to syscall_exit_rfi and on << 1698 */ << 1699 bv %r0(%r2) << 1700 LDREG PT_GR28(%r1),%r28 /* reload << 1701 ENDPROC_CFI(sys_rt_sigreturn_wrapper) << 1702 << 1703 ENTRY(syscall_exit) << 1704 /* NOTE: Not all syscalls exit this w << 1705 * via syscall_exit_rfi if the signal << 1706 * was running. << 1707 */ << 1708 << 1709 /* save return value now */ << 1710 mfctl %cr30, %r1 << 1711 STREG %r28,TASK_PT_GR28(%r1) << 1712 << 1713 /* Seems to me that dp could be wrong << 1714 * calling a module, and nothing got << 1715 */ << 1716 loadgp << 1717 << 1718 syscall_check_resched: << 1719 << 1720 /* check for reschedule */ << 1721 mfctl %cr30,%r19 << 1722 LDREG TASK_TI_FLAGS(%r19),%r19 << 1723 bb,<,n %r19, 31-TIF_NEED_RESCHED, sy << 1724 << 1725 .import do_signal,code << 1726 syscall_check_sig: << 1727 mfctl %cr30,%r19 << 1728 LDREG TASK_TI_FLAGS(%r19),%r19 << 1729 ldi (_TIF_USER_WORK_MASK & ~_TIF_ << 1730 and,COND(<>) %r19, %r26, %r0 << 1731 b,n syscall_restore /* skip past << 1732 << 1733 syscall_do_signal: << 1734 /* Save callee-save registers (for si << 1735 * FIXME: After this point the proces << 1736 * consistent with all the relevant s << 1737 * before the syscall. We need to ve << 1738 */ << 1739 mfctl %cr30,%r1 << 1740 ldo TASK_REGS(%r1), %r26 << 1741 reg_save %r26 << 1742 << 1743 #ifdef CONFIG_64BIT << 1744 ldo -16(%r30),%r29 << 1745 #endif << 1746 << 1747 BL do_notify_resume,%r2 << 1748 ldi 1, %r25 << 1749 << 1750 mfctl %cr30,%r1 << 1751 ldo TASK_REGS(%r1), %r20 << 1752 reg_restore %r20 << 1753 << 1754 b,n syscall_check_sig << 1755 << 1756 syscall_restore: << 1757 mfctl %cr30,%r1 << 1758 << 1759 /* Are we being ptraced? */ << 1760 LDREG TASK_TI_FLAGS(%r1),%r19 << 1761 ldi _TIF_SINGLESTEP|_TIF_BLOCKSTE << 1762 and,COND(=) %r19,%r2,%r0 << 1763 b,n syscall_restore_rfi << 1764 << 1765 ldo TASK_PT_FR31(%r1),%r19 << 1766 rest_fp %r19 << 1767 << 1768 LDREG TASK_PT_SAR(%r1),%r19 << 1769 mtsar %r19 << 1770 << 1771 LDREG TASK_PT_GR2(%r1),%r2 << 1772 LDREG TASK_PT_GR19(%r1),%r19 << 1773 LDREG TASK_PT_GR20(%r1),%r20 << 1774 LDREG TASK_PT_GR21(%r1),%r21 << 1775 LDREG TASK_PT_GR22(%r1),%r22 << 1776 LDREG TASK_PT_GR23(%r1),%r23 << 1777 LDREG TASK_PT_GR24(%r1),%r24 << 1778 LDREG TASK_PT_GR25(%r1),%r25 << 1779 LDREG TASK_PT_GR26(%r1),%r26 << 1780 LDREG TASK_PT_GR27(%r1),%r27 /* << 1781 LDREG TASK_PT_GR28(%r1),%r28 /* << 1782 LDREG TASK_PT_GR29(%r1),%r29 << 1783 LDREG TASK_PT_GR31(%r1),%r31 /* << 1784 << 1785 /* NOTE: We use rsm/ssm pair to make << 1786 LDREG TASK_PT_GR30(%r1),%r1 << 1787 rsm PSW_SM_I, %r0 << 1788 copy %r1,%r30 << 1789 mfsp %sr3,%r1 << 1790 mtsp %r1,%sr7 << 1791 ssm PSW_SM_I, %r0 << 1792 << 1793 /* Set sr2 to zero for userspace sysc << 1794 mtsp %r0,%sr2 << 1795 mtsp %r1,%sr4 << 1796 mtsp %r1,%sr5 << 1797 mtsp %r1,%sr6 << 1798 << 1799 depi PRIV_USER,31,2,%r31 /* en << 1800 << 1801 #ifdef CONFIG_64BIT << 1802 /* decide whether to reset the wide m << 1803 * 1274 * 1804 * For a syscall, the W bit is stored !! 1275 * %g1 is one if this trap occurred at %tl >= 1. 1805 * of sp. Extract it and reset W if !! 1276 * 1806 extrd,u,*<> %r30,63,1,%r1 !! 1277 * Next, we turn off error reporting so that we don't recurse. 1807 rsm PSW_SM_W, %r0 << 1808 /* now reset the lowest bit of sp if << 1809 xor %r30,%r1,%r30 << 1810 #endif << 1811 be,n 0(%sr3,%r31) << 1812 << 1813 /* We have to return via an RFI, so t << 1814 * appropriately. << 1815 * This sets up pt_regs so we can ret << 1816 * the most efficient way of doing th << 1817 */ << 1818 syscall_restore_rfi: << 1819 ldo -1(%r0),%r2 << 1820 mtctl %r2,%cr0 << 1821 LDREG TASK_PT_PSW(%r1),%r2 << 1822 ldi 0x0b,%r20 << 1823 depi -1,13,1,%r20 << 1824 << 1825 /* The values of SINGLESTEP_BIT and B << 1826 * set in thread_info.h and converted << 1827 * numbers in asm-offsets.c */ << 1828 << 1829 /* if ((%r19.SINGLESTEP_BIT)) { %r20. << 1830 extru,= %r19,TIF_SINGLESTEP_PA_BIT,1, << 1831 depi -1,27,1,%r20 << 1832 << 1833 /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7 << 1834 extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,% << 1835 depi -1,7,1,%r20 << 1836 << 1837 STREG %r20,TASK_PT_PSW(%r1) << 1838 << 1839 /* Always store space registers, sinc << 1840 << 1841 mfsp %sr3,%r25 << 1842 STREG %r25,TASK_PT_SR3(%r1) << 1843 STREG %r25,TASK_PT_SR4(%r1) << 1844 STREG %r25,TASK_PT_SR5(%r1) << 1845 STREG %r25,TASK_PT_SR6(%r1) << 1846 STREG %r25,TASK_PT_SR7(%r1) << 1847 STREG %r25,TASK_PT_IASQ0(%r1) << 1848 STREG %r25,TASK_PT_IASQ1(%r1) << 1849 << 1850 /* XXX W bit??? */ << 1851 /* Now if old D bit is clear, it mean << 1852 * on syscall entry, so do that now. << 1853 * calls, or if someone attached to u << 1854 * We could make this more efficient << 1855 * then we wouldn't be able to use th << 1856 * It is only for traced processes an << 1857 * an issue. << 1858 */ 1278 */ 1859 bb,< %r2,30,pt_regs_ok !! 1279 .globl cheetah_fast_ecc 1860 ldo TASK_REGS(%r1),%r25 !! 1280 cheetah_fast_ecc: 1861 reg_save %r25 !! 1281 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2 1862 !! 1282 andn %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2 1863 /* Save the current sr */ !! 1283 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN 1864 mfsp %sr0,%r2 !! 1284 membar #Sync 1865 STREG %r2,TASK_PT_SR0(%r1) !! 1285 1866 !! 1286 /* Fetch and clear AFSR/AFAR */ 1867 /* Save the scratch sr */ !! 1287 ldxa [%g0] ASI_AFSR, %g4 1868 mfsp %sr1,%r2 !! 1288 ldxa [%g0] ASI_AFAR, %g5 1869 STREG %r2,TASK_PT_SR1(%r1) !! 1289 stxa %g4, [%g0] ASI_AFSR 1870 !! 1290 membar #Sync 1871 /* sr2 should be set to zero for user !! 1291 1872 STREG %r0,TASK_PT_SR2(%r1) !! 1292 CHEETAH_LOG_ERROR 1873 !! 1293 1874 LDREG TASK_PT_GR31(%r1),%r2 !! 1294 rdpr %pil, %g2 1875 depi PRIV_USER,31,2,%r2 /* en !! 1295 wrpr %g0, 15, %pil 1876 STREG %r2,TASK_PT_IAOQ0(%r1) !! 1296 ba,pt %xcc, etrap_irq 1877 ldo 4(%r2),%r2 !! 1297 rd %pc, %g7 1878 STREG %r2,TASK_PT_IAOQ1(%r1) !! 1298 mov %l4, %o1 1879 b intr_restore !! 1299 mov %l5, %o2 1880 copy %r25,%r16 !! 1300 call cheetah_fecc_handler 1881 !! 1301 add %sp, PTREGS_OFF, %o0 1882 pt_regs_ok: !! 1302 ba,a,pt %xcc, rtrap_irq 1883 LDREG TASK_PT_IAOQ0(%r1),%r2 !! 1303 1884 depi PRIV_USER,31,2,%r2 /* en !! 1304 /* Our caller has disabled I-cache and performed membar Sync. */ 1885 STREG %r2,TASK_PT_IAOQ0(%r1) !! 1305 .globl cheetah_cee 1886 LDREG TASK_PT_IAOQ1(%r1),%r2 !! 1306 cheetah_cee: 1887 depi PRIV_USER,31,2,%r2 !! 1307 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2 1888 STREG %r2,TASK_PT_IAOQ1(%r1) !! 1308 andn %g2, ESTATE_ERROR_CEEN, %g2 1889 b intr_restore !! 1309 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN 1890 copy %r25,%r16 !! 1310 membar #Sync 1891 !! 1311 1892 syscall_do_resched: !! 1312 /* Fetch and clear AFSR/AFAR */ 1893 load32 syscall_check_resched,%r2 /* !! 1313 ldxa [%g0] ASI_AFSR, %g4 1894 load32 schedule,%r19 !! 1314 ldxa [%g0] ASI_AFAR, %g5 1895 bv %r0(%r19) /* ju !! 1315 stxa %g4, [%g0] ASI_AFSR 1896 #ifdef CONFIG_64BIT !! 1316 membar #Sync 1897 ldo -16(%r30),%r29 /* Re !! 1317 1898 #else !! 1318 CHEETAH_LOG_ERROR 1899 nop !! 1319 1900 #endif !! 1320 rdpr %pil, %g2 1901 END(syscall_exit) !! 1321 wrpr %g0, 15, %pil 1902 !! 1322 ba,pt %xcc, etrap_irq >> 1323 rd %pc, %g7 >> 1324 mov %l4, %o1 >> 1325 mov %l5, %o2 >> 1326 call cheetah_cee_handler >> 1327 add %sp, PTREGS_OFF, %o0 >> 1328 ba,a,pt %xcc, rtrap_irq >> 1329 >> 1330 /* Our caller has disabled I-cache+D-cache and performed membar Sync. */ >> 1331 .globl cheetah_deferred_trap >> 1332 cheetah_deferred_trap: >> 1333 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2 >> 1334 andn %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2 >> 1335 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN >> 1336 membar #Sync >> 1337 >> 1338 /* Fetch and clear AFSR/AFAR */ >> 1339 ldxa [%g0] ASI_AFSR, %g4 >> 1340 ldxa [%g0] ASI_AFAR, %g5 >> 1341 stxa %g4, [%g0] ASI_AFSR >> 1342 membar #Sync >> 1343 >> 1344 CHEETAH_LOG_ERROR >> 1345 >> 1346 rdpr %pil, %g2 >> 1347 wrpr %g0, 15, %pil >> 1348 ba,pt %xcc, etrap_irq >> 1349 rd %pc, %g7 >> 1350 mov %l4, %o1 >> 1351 mov %l5, %o2 >> 1352 call cheetah_deferred_handler >> 1353 add %sp, PTREGS_OFF, %o0 >> 1354 ba,a,pt %xcc, rtrap_irq >> 1355 >> 1356 .globl __do_privact >> 1357 __do_privact: >> 1358 mov TLB_SFSR, %g3 >> 1359 stxa %g0, [%g3] ASI_DMMU ! Clear FaultValid bit >> 1360 membar #Sync >> 1361 sethi %hi(109f), %g7 >> 1362 ba,pt %xcc, etrap >> 1363 109: or %g7, %lo(109b), %g7 >> 1364 call do_privact >> 1365 add %sp, PTREGS_OFF, %o0 >> 1366 ba,pt %xcc, rtrap >> 1367 clr %l6 >> 1368 >> 1369 .globl do_mna >> 1370 do_mna: >> 1371 rdpr %tl, %g3 >> 1372 cmp %g3, 1 >> 1373 >> 1374 /* Setup %g4/%g5 now as they are used in the >> 1375 * winfixup code. >> 1376 */ >> 1377 mov TLB_SFSR, %g3 >> 1378 mov DMMU_SFAR, %g4 >> 1379 ldxa [%g4] ASI_DMMU, %g4 >> 1380 ldxa [%g3] ASI_DMMU, %g5 >> 1381 stxa %g0, [%g3] ASI_DMMU ! Clear FaultValid bit >> 1382 membar #Sync >> 1383 bgu,pn %icc, winfix_mna >> 1384 rdpr %tpc, %g3 >> 1385 >> 1386 1: sethi %hi(109f), %g7 >> 1387 ba,pt %xcc, etrap >> 1388 109: or %g7, %lo(109b), %g7 >> 1389 mov %l4, %o1 >> 1390 mov %l5, %o2 >> 1391 call mem_address_unaligned >> 1392 add %sp, PTREGS_OFF, %o0 >> 1393 ba,pt %xcc, rtrap >> 1394 clr %l6 >> 1395 >> 1396 .globl do_lddfmna >> 1397 do_lddfmna: >> 1398 sethi %hi(109f), %g7 >> 1399 mov TLB_SFSR, %g4 >> 1400 ldxa [%g4] ASI_DMMU, %g5 >> 1401 stxa %g0, [%g4] ASI_DMMU ! Clear FaultValid bit >> 1402 membar #Sync >> 1403 mov DMMU_SFAR, %g4 >> 1404 ldxa [%g4] ASI_DMMU, %g4 >> 1405 ba,pt %xcc, etrap >> 1406 109: or %g7, %lo(109b), %g7 >> 1407 mov %l4, %o1 >> 1408 mov %l5, %o2 >> 1409 call handle_lddfmna >> 1410 add %sp, PTREGS_OFF, %o0 >> 1411 ba,pt %xcc, rtrap >> 1412 clr %l6 >> 1413 >> 1414 .globl do_stdfmna >> 1415 do_stdfmna: >> 1416 sethi %hi(109f), %g7 >> 1417 mov TLB_SFSR, %g4 >> 1418 ldxa [%g4] ASI_DMMU, %g5 >> 1419 stxa %g0, [%g4] ASI_DMMU ! Clear FaultValid bit >> 1420 membar #Sync >> 1421 mov DMMU_SFAR, %g4 >> 1422 ldxa [%g4] ASI_DMMU, %g4 >> 1423 ba,pt %xcc, etrap >> 1424 109: or %g7, %lo(109b), %g7 >> 1425 mov %l4, %o1 >> 1426 mov %l5, %o2 >> 1427 call handle_stdfmna >> 1428 add %sp, PTREGS_OFF, %o0 >> 1429 ba,pt %xcc, rtrap >> 1430 clr %l6 >> 1431 >> 1432 .globl breakpoint_trap >> 1433 breakpoint_trap: >> 1434 call sparc_breakpoint >> 1435 add %sp, PTREGS_OFF, %o0 >> 1436 ba,pt %xcc, rtrap >> 1437 nop >> 1438 >> 1439 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ >> 1440 defined(CONFIG_SOLARIS_EMUL_MODULE) >> 1441 /* SunOS uses syscall zero as the 'indirect syscall' it looks >> 1442 * like indir_syscall(scall_num, arg0, arg1, arg2...); etc. >> 1443 * This is complete brain damage. >> 1444 */ >> 1445 .globl sunos_indir >> 1446 sunos_indir: >> 1447 srl %o0, 0, %o0 >> 1448 mov %o7, %l4 >> 1449 cmp %o0, NR_SYSCALLS >> 1450 blu,a,pt %icc, 1f >> 1451 sll %o0, 0x2, %o0 >> 1452 sethi %hi(sunos_nosys), %l6 >> 1453 b,pt %xcc, 2f >> 1454 or %l6, %lo(sunos_nosys), %l6 >> 1455 1: sethi %hi(sunos_sys_table), %l7 >> 1456 or %l7, %lo(sunos_sys_table), %l7 >> 1457 lduw [%l7 + %o0], %l6 >> 1458 2: mov %o1, %o0 >> 1459 mov %o2, %o1 >> 1460 mov %o3, %o2 >> 1461 mov %o4, %o3 >> 1462 mov %o5, %o4 >> 1463 call %l6 >> 1464 mov %l4, %o7 >> 1465 >> 1466 .globl sunos_getpid >> 1467 sunos_getpid: >> 1468 call sys_getppid >> 1469 nop >> 1470 call sys_getpid >> 1471 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] >> 1472 b,pt %xcc, ret_sys_call >> 1473 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] >> 1474 >> 1475 /* SunOS getuid() returns uid in %o0 and euid in %o1 */ >> 1476 .globl sunos_getuid >> 1477 sunos_getuid: >> 1478 call sys32_geteuid16 >> 1479 nop >> 1480 call sys32_getuid16 >> 1481 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] >> 1482 b,pt %xcc, ret_sys_call >> 1483 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] >> 1484 >> 1485 /* SunOS getgid() returns gid in %o0 and egid in %o1 */ >> 1486 .globl sunos_getgid >> 1487 sunos_getgid: >> 1488 call sys32_getegid16 >> 1489 nop >> 1490 call sys32_getgid16 >> 1491 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] >> 1492 b,pt %xcc, ret_sys_call >> 1493 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] >> 1494 #endif >> 1495 >> 1496 /* SunOS's execv() call only specifies the argv argument, the >> 1497 * environment settings are the same as the calling processes. >> 1498 */ >> 1499 .globl sunos_execv, sys_execve, sys32_execve >> 1500 sys_execve: >> 1501 sethi %hi(sparc_execve), %g1 >> 1502 ba,pt %xcc, execve_merge >> 1503 or %g1, %lo(sparc_execve), %g1 >> 1504 sunos_execv: >> 1505 stx %g0, [%sp + PTREGS_OFF + PT_V9_I2] >> 1506 sys32_execve: >> 1507 sethi %hi(sparc32_execve), %g1 >> 1508 or %g1, %lo(sparc32_execve), %g1 >> 1509 execve_merge: >> 1510 flushw >> 1511 jmpl %g1, %g0 >> 1512 add %sp, PTREGS_OFF, %o0 >> 1513 >> 1514 .globl sys_pipe, sys_sigpause, sys_nis_syscall >> 1515 .globl sys_sigsuspend, sys_rt_sigsuspend, sys32_rt_sigsuspend >> 1516 .globl sys_rt_sigreturn >> 1517 .globl sys32_sigreturn, sys32_rt_sigreturn >> 1518 .globl sys32_execve, sys_ptrace >> 1519 .globl sys_sigaltstack, sys32_sigaltstack >> 1520 .globl sys32_sigstack >> 1521 .align 32 >> 1522 sys_pipe: ba,pt %xcc, sparc_pipe >> 1523 add %sp, PTREGS_OFF, %o0 >> 1524 sys_nis_syscall:ba,pt %xcc, c_sys_nis_syscall >> 1525 add %sp, PTREGS_OFF, %o0 >> 1526 sys_memory_ordering: >> 1527 ba,pt %xcc, sparc_memory_ordering >> 1528 add %sp, PTREGS_OFF, %o1 >> 1529 sys_sigaltstack:ba,pt %xcc, do_sigaltstack >> 1530 add %i6, STACK_BIAS, %o2 >> 1531 sys32_sigstack: ba,pt %xcc, do_sys32_sigstack >> 1532 mov %i6, %o2 >> 1533 sys32_sigaltstack: >> 1534 ba,pt %xcc, do_sys32_sigaltstack >> 1535 mov %i6, %o2 >> 1536 >> 1537 .align 32 >> 1538 sys_sigsuspend: add %sp, PTREGS_OFF, %o0 >> 1539 call do_sigsuspend >> 1540 add %o7, 1f-.-4, %o7 >> 1541 nop >> 1542 sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */ >> 1543 add %sp, PTREGS_OFF, %o2 >> 1544 call do_rt_sigsuspend >> 1545 add %o7, 1f-.-4, %o7 >> 1546 nop >> 1547 sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */ >> 1548 srl %o0, 0, %o0 >> 1549 add %sp, PTREGS_OFF, %o2 >> 1550 call do_rt_sigsuspend32 >> 1551 add %o7, 1f-.-4, %o7 >> 1552 /* NOTE: %o0 has a correct value already */ >> 1553 sys_sigpause: add %sp, PTREGS_OFF, %o1 >> 1554 call do_sigpause >> 1555 add %o7, 1f-.-4, %o7 >> 1556 nop >> 1557 sys32_sigreturn: >> 1558 add %sp, PTREGS_OFF, %o0 >> 1559 call do_sigreturn32 >> 1560 add %o7, 1f-.-4, %o7 >> 1561 nop >> 1562 sys_rt_sigreturn: >> 1563 add %sp, PTREGS_OFF, %o0 >> 1564 call do_rt_sigreturn >> 1565 add %o7, 1f-.-4, %o7 >> 1566 nop >> 1567 sys32_rt_sigreturn: >> 1568 add %sp, PTREGS_OFF, %o0 >> 1569 call do_rt_sigreturn32 >> 1570 add %o7, 1f-.-4, %o7 >> 1571 nop >> 1572 sys_ptrace: add %sp, PTREGS_OFF, %o0 >> 1573 call do_ptrace >> 1574 add %o7, 1f-.-4, %o7 >> 1575 nop >> 1576 .align 32 >> 1577 1: ldx [%curptr + TI_FLAGS], %l5 >> 1578 andcc %l5, _TIF_SYSCALL_TRACE, %g0 >> 1579 be,pt %icc, rtrap >> 1580 clr %l6 >> 1581 call syscall_trace >> 1582 nop 1903 1583 1904 #ifdef CONFIG_FUNCTION_TRACER !! 1584 ba,pt %xcc, rtrap >> 1585 clr %l6 1905 1586 1906 .import ftrace_function_trampoline,co !! 1587 /* This is how fork() was meant to be done, 8 instruction entry. 1907 .align L1_CACHE_BYTES !! 1588 * 1908 ENTRY_CFI(mcount, caller) !! 1589 * I questioned the following code briefly, let me clear things 1909 _mcount: !! 1590 * up so you must not reason on it like I did. 1910 .export _mcount,data !! 1591 * 1911 /* !! 1592 * Know the fork_kpsr etc. we use in the sparc32 port? We don't 1912 * The 64bit mcount() function pointe !! 1593 * need it here because the only piece of window state we copy to 1913 * first two are free. We optimize i !! 1594 * the child is the CWP register. Even if the parent sleeps, 1914 * calling mcount(), and 2 instructio !! 1595 * we are safe because we stuck it into pt_regs of the parent 1915 * have all on one L1 cacheline. !! 1596 * so it will not change. >> 1597 * >> 1598 * XXX This raises the question, whether we can do the same on >> 1599 * XXX sparc32 to get rid of fork_kpsr _and_ fork_kwim. The >> 1600 * XXX answer is yes. We stick fork_kpsr in UREG_G0 and >> 1601 * XXX fork_kwim in UREG_G1 (global registers are considered >> 1602 * XXX volatile across a system call in the sparc ABI I think >> 1603 * XXX if it isn't we can use regs->y instead, anyone who depends >> 1604 * XXX upon the Y register being preserved across a fork deserves >> 1605 * XXX to lose). >> 1606 * >> 1607 * In fact we should take advantage of that fact for other things >> 1608 * during system calls... 1916 */ 1609 */ 1917 ldi 0, %arg3 !! 1610 .globl sys_fork, sys_vfork, sys_clone, sparc_exit 1918 b ftrace_function_trampoline !! 1611 .globl ret_from_syscall 1919 copy %r3, %arg2 /* caller ori !! 1612 .align 32 1920 ftrace_stub: !! 1613 sys_vfork: /* Under Linux, vfork and fork are just special cases of clone. */ 1921 .globl ftrace_stub !! 1614 sethi %hi(0x4000 | 0x0100 | SIGCHLD), %o0 1922 .type ftrace_stub, @function !! 1615 or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0 1923 #ifdef CONFIG_64BIT !! 1616 ba,pt %xcc, sys_clone 1924 bve (%rp) !! 1617 sys_fork: clr %o1 1925 #else !! 1618 mov SIGCHLD, %o0 1926 bv %r0(%rp) !! 1619 sys_clone: flushw 1927 #endif !! 1620 movrz %o1, %fp, %o1 1928 nop !! 1621 mov 0, %o3 1929 #ifdef CONFIG_64BIT !! 1622 ba,pt %xcc, sparc_do_fork 1930 .dword mcount !! 1623 add %sp, PTREGS_OFF, %o2 1931 .dword 0 /* code in head.S puts value !! 1624 ret_from_syscall: 1932 #endif !! 1625 /* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in 1933 ENDPROC_CFI(mcount) !! 1626 * %o7 for us. Check performance counter stuff too. 1934 !! 1627 */ 1935 #ifdef CONFIG_DYNAMIC_FTRACE !! 1628 andn %o7, _TIF_NEWCHILD, %l0 1936 !! 1629 stx %l0, [%g6 + TI_FLAGS] 1937 #ifdef CONFIG_64BIT !! 1630 call schedule_tail 1938 #define FTRACE_FRAME_SIZE (2*FRAME_SIZE) !! 1631 mov %g5, %o0 1939 #else !! 1632 andcc %l0, _TIF_PERFCTR, %g0 1940 #define FTRACE_FRAME_SIZE FRAME_SIZE !! 1633 be,pt %icc, 1f 1941 #endif !! 1634 nop 1942 ENTRY_CFI(ftrace_caller, caller,frame=FTRACE_ !! 1635 ldx [%g6 + TI_PCR], %o7 1943 ftrace_caller: !! 1636 wr %g0, %o7, %pcr 1944 .global ftrace_caller !! 1637 1945 !! 1638 /* Blackbird errata workaround. See commentary in 1946 STREG %r3, -FTRACE_FRAME_SIZE+1*REG !! 1639 * smp.c:smp_percpu_timer_interrupt() for more 1947 ldo -FTRACE_FRAME_SIZE(%sp), %r3 !! 1640 * information. 1948 STREG %rp, -RP_OFFSET(%r3) !! 1641 */ 1949 !! 1642 ba,pt %xcc, 99f 1950 /* Offset 0 is already allocated for !! 1643 nop 1951 STREG %r23, 2*REG_SZ(%r3) !! 1644 .align 64 1952 STREG %r24, 3*REG_SZ(%r3) !! 1645 99: wr %g0, %g0, %pic 1953 STREG %r25, 4*REG_SZ(%r3) !! 1646 rd %pic, %g0 1954 STREG %r26, 5*REG_SZ(%r3) !! 1647 1955 STREG %r28, 6*REG_SZ(%r3) !! 1648 1: b,pt %xcc, ret_sys_call 1956 STREG %r29, 7*REG_SZ(%r3) !! 1649 ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 1957 #ifdef CONFIG_64BIT !! 1650 sparc_exit: wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate 1958 STREG %r19, 8*REG_SZ(%r3) !! 1651 rdpr %otherwin, %g1 1959 STREG %r20, 9*REG_SZ(%r3) !! 1652 rdpr %cansave, %g3 1960 STREG %r21, 10*REG_SZ(%r3) !! 1653 add %g3, %g1, %g3 1961 STREG %r22, 11*REG_SZ(%r3) !! 1654 wrpr %g3, 0x0, %cansave 1962 STREG %r27, 12*REG_SZ(%r3) !! 1655 wrpr %g0, 0x0, %otherwin 1963 STREG %r31, 13*REG_SZ(%r3) !! 1656 wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE), %pstate 1964 loadgp !! 1657 ba,pt %xcc, sys_exit 1965 ldo -16(%sp),%r29 !! 1658 stb %g0, [%g6 + TI_WSAVED] 1966 #endif !! 1659 1967 LDREG 0(%r3), %r25 !! 1660 linux_sparc_ni_syscall: 1968 copy %rp, %r26 !! 1661 sethi %hi(sys_ni_syscall), %l7 1969 ldo -8(%r25), %r25 !! 1662 b,pt %xcc, 4f 1970 ldi 0, %r23 /* no pt_regs !! 1663 or %l7, %lo(sys_ni_syscall), %l7 1971 b,l ftrace_function_trampoline, % !! 1664 1972 copy %r3, %r24 !! 1665 linux_syscall_trace32: 1973 !! 1666 call syscall_trace 1974 LDREG -RP_OFFSET(%r3), %rp !! 1667 nop 1975 LDREG 2*REG_SZ(%r3), %r23 !! 1668 srl %i0, 0, %o0 1976 LDREG 3*REG_SZ(%r3), %r24 !! 1669 mov %i4, %o4 1977 LDREG 4*REG_SZ(%r3), %r25 !! 1670 srl %i1, 0, %o1 1978 LDREG 5*REG_SZ(%r3), %r26 !! 1671 srl %i2, 0, %o2 1979 LDREG 6*REG_SZ(%r3), %r28 !! 1672 b,pt %xcc, 2f 1980 LDREG 7*REG_SZ(%r3), %r29 !! 1673 srl %i3, 0, %o3 1981 #ifdef CONFIG_64BIT !! 1674 1982 LDREG 8*REG_SZ(%r3), %r19 !! 1675 linux_syscall_trace: 1983 LDREG 9*REG_SZ(%r3), %r20 !! 1676 call syscall_trace 1984 LDREG 10*REG_SZ(%r3), %r21 !! 1677 nop 1985 LDREG 11*REG_SZ(%r3), %r22 !! 1678 mov %i0, %o0 1986 LDREG 12*REG_SZ(%r3), %r27 !! 1679 mov %i1, %o1 1987 LDREG 13*REG_SZ(%r3), %r31 !! 1680 mov %i2, %o2 1988 #endif !! 1681 mov %i3, %o3 1989 LDREG 1*REG_SZ(%r3), %r3 !! 1682 b,pt %xcc, 2f 1990 !! 1683 mov %i4, %o4 1991 LDREGM -FTRACE_FRAME_SIZE(%sp), %r1 << 1992 /* Adjust return point to jump back t << 1993 ldo -4(%r1), %r1 << 1994 bv,n (%r1) << 1995 << 1996 ENDPROC_CFI(ftrace_caller) << 1997 << 1998 #ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS << 1999 ENTRY_CFI(ftrace_regs_caller,caller,frame=FTR << 2000 CALLS,SAVE_RP,SAVE_SP) << 2001 ftrace_regs_caller: << 2002 .global ftrace_regs_caller << 2003 << 2004 ldo -FTRACE_FRAME_SIZE(%sp), %r1 << 2005 STREG %rp, -RP_OFFSET(%r1) << 2006 << 2007 copy %sp, %r1 << 2008 ldo PT_SZ_ALGN(%sp), %sp << 2009 << 2010 STREG %rp, PT_GR2(%r1) << 2011 STREG %r3, PT_GR3(%r1) << 2012 STREG %r4, PT_GR4(%r1) << 2013 STREG %r5, PT_GR5(%r1) << 2014 STREG %r6, PT_GR6(%r1) << 2015 STREG %r7, PT_GR7(%r1) << 2016 STREG %r8, PT_GR8(%r1) << 2017 STREG %r9, PT_GR9(%r1) << 2018 STREG %r10, PT_GR10(%r1) << 2019 STREG %r11, PT_GR11(%r1) << 2020 STREG %r12, PT_GR12(%r1) << 2021 STREG %r13, PT_GR13(%r1) << 2022 STREG %r14, PT_GR14(%r1) << 2023 STREG %r15, PT_GR15(%r1) << 2024 STREG %r16, PT_GR16(%r1) << 2025 STREG %r17, PT_GR17(%r1) << 2026 STREG %r18, PT_GR18(%r1) << 2027 STREG %r19, PT_GR19(%r1) << 2028 STREG %r20, PT_GR20(%r1) << 2029 STREG %r21, PT_GR21(%r1) << 2030 STREG %r22, PT_GR22(%r1) << 2031 STREG %r23, PT_GR23(%r1) << 2032 STREG %r24, PT_GR24(%r1) << 2033 STREG %r25, PT_GR25(%r1) << 2034 STREG %r26, PT_GR26(%r1) << 2035 STREG %r27, PT_GR27(%r1) << 2036 STREG %r28, PT_GR28(%r1) << 2037 STREG %r29, PT_GR29(%r1) << 2038 STREG %r30, PT_GR30(%r1) << 2039 STREG %r31, PT_GR31(%r1) << 2040 mfctl %cr11, %r26 << 2041 STREG %r26, PT_SAR(%r1) << 2042 << 2043 copy %rp, %r26 << 2044 LDREG -FTRACE_FRAME_SIZE-PT_SZ_ALGN << 2045 ldo -8(%r25), %r25 << 2046 ldo -FTRACE_FRAME_SIZE(%r1), %arg << 2047 b,l ftrace_function_trampoline, % << 2048 copy %r1, %arg3 /* struct pt_regs << 2049 << 2050 ldo -PT_SZ_ALGN(%sp), %r1 << 2051 << 2052 LDREG PT_SAR(%r1), %rp << 2053 mtctl %rp, %cr11 << 2054 << 2055 LDREG PT_GR2(%r1), %rp << 2056 LDREG PT_GR3(%r1), %r3 << 2057 LDREG PT_GR4(%r1), %r4 << 2058 LDREG PT_GR5(%r1), %r5 << 2059 LDREG PT_GR6(%r1), %r6 << 2060 LDREG PT_GR7(%r1), %r7 << 2061 LDREG PT_GR8(%r1), %r8 << 2062 LDREG PT_GR9(%r1), %r9 << 2063 LDREG PT_GR10(%r1),%r10 << 2064 LDREG PT_GR11(%r1),%r11 << 2065 LDREG PT_GR12(%r1),%r12 << 2066 LDREG PT_GR13(%r1),%r13 << 2067 LDREG PT_GR14(%r1),%r14 << 2068 LDREG PT_GR15(%r1),%r15 << 2069 LDREG PT_GR16(%r1),%r16 << 2070 LDREG PT_GR17(%r1),%r17 << 2071 LDREG PT_GR18(%r1),%r18 << 2072 LDREG PT_GR19(%r1),%r19 << 2073 LDREG PT_GR20(%r1),%r20 << 2074 LDREG PT_GR21(%r1),%r21 << 2075 LDREG PT_GR22(%r1),%r22 << 2076 LDREG PT_GR23(%r1),%r23 << 2077 LDREG PT_GR24(%r1),%r24 << 2078 LDREG PT_GR25(%r1),%r25 << 2079 LDREG PT_GR26(%r1),%r26 << 2080 LDREG PT_GR27(%r1),%r27 << 2081 LDREG PT_GR28(%r1),%r28 << 2082 LDREG PT_GR29(%r1),%r29 << 2083 LDREG PT_GR30(%r1),%r30 << 2084 LDREG PT_GR31(%r1),%r31 << 2085 << 2086 ldo -PT_SZ_ALGN(%sp), %sp << 2087 LDREGM -FTRACE_FRAME_SIZE(%sp), %r1 << 2088 /* Adjust return point to jump back t << 2089 ldo -4(%r1), %r1 << 2090 bv,n (%r1) << 2091 << 2092 ENDPROC_CFI(ftrace_regs_caller) << 2093 << 2094 #endif << 2095 #endif << 2096 << 2097 #ifdef CONFIG_FUNCTION_GRAPH_TRACER << 2098 .align 8 << 2099 ENTRY_CFI(return_to_handler, caller,frame=FRA << 2100 .export parisc_return_to_handler,data << 2101 parisc_return_to_handler: << 2102 copy %r3,%r1 << 2103 STREG %r0,-RP_OFFSET(%sp) /* st << 2104 copy %sp,%r3 << 2105 STREGM %r1,FRAME_SIZE(%sp) << 2106 STREG %ret0,8(%r3) << 2107 STREG %ret1,16(%r3) << 2108 1684 2109 #ifdef CONFIG_64BIT << 2110 loadgp << 2111 #endif << 2112 1685 2113 /* call ftrace_return_to_handler(0) * !! 1686 /* Linux 32-bit and SunOS system calls enter here... */ 2114 .import ftrace_return_to_handler,code !! 1687 .align 32 2115 load32 ftrace_return_to_handler,%ret0 !! 1688 .globl linux_sparc_syscall32 2116 load32 .Lftrace_ret,%r2 !! 1689 linux_sparc_syscall32: 2117 #ifdef CONFIG_64BIT !! 1690 /* Direct access to user regs, much faster. */ 2118 ldo -16(%sp),%ret1 /* Re !! 1691 cmp %g1, NR_SYSCALLS ! IEU1 Group 2119 bve (%ret0) !! 1692 bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI 2120 #else !! 1693 srl %i0, 0, %o0 ! IEU0 2121 bv %r0(%ret0) !! 1694 sll %g1, 2, %l4 ! IEU0 Group 2122 #endif !! 1695 #ifdef SYSCALL_TRACING 2123 ldi 0,%r26 !! 1696 call syscall_trace_entry 2124 .Lftrace_ret: !! 1697 add %sp, PTREGS_OFF, %o0 2125 copy %ret0,%rp !! 1698 srl %i0, 0, %o0 2126 !! 1699 #endif 2127 /* restore original return values */ !! 1700 mov %i4, %o4 ! IEU1 2128 LDREG 8(%r3),%ret0 !! 1701 lduw [%l7 + %l4], %l7 ! Load 2129 LDREG 16(%r3),%ret1 !! 1702 srl %i1, 0, %o1 ! IEU0 Group 2130 !! 1703 ldx [%curptr + TI_FLAGS], %l0 ! Load 2131 /* return from function */ !! 1704 2132 #ifdef CONFIG_64BIT !! 1705 mov %i5, %o5 ! IEU1 2133 bve (%rp) !! 1706 srl %i2, 0, %o2 ! IEU0 Group 2134 #else !! 1707 andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU0 Group 2135 bv %r0(%rp) !! 1708 bne,pn %icc, linux_syscall_trace32 ! CTI 2136 #endif !! 1709 mov %i0, %l5 ! IEU1 2137 LDREGM -FRAME_SIZE(%sp),%r3 !! 1710 call %l7 ! CTI Group brk forced 2138 ENDPROC_CFI(return_to_handler) !! 1711 srl %i3, 0, %o3 ! IEU0 2139 !! 1712 ba,a,pt %xcc, 3f 2140 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ << 2141 1713 2142 #endif /* CONFIG_FUNCTION_TRACER */ !! 1714 /* Linux native and SunOS system calls enter here... */ >> 1715 .align 32 >> 1716 .globl linux_sparc_syscall, ret_sys_call >> 1717 linux_sparc_syscall: >> 1718 /* Direct access to user regs, much faster. */ >> 1719 cmp %g1, NR_SYSCALLS ! IEU1 Group >> 1720 bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI >> 1721 mov %i0, %o0 ! IEU0 >> 1722 sll %g1, 2, %l4 ! IEU0 Group >> 1723 #ifdef SYSCALL_TRACING >> 1724 call syscall_trace_entry >> 1725 add %sp, PTREGS_OFF, %o0 >> 1726 mov %i0, %o0 >> 1727 #endif >> 1728 mov %i1, %o1 ! IEU1 >> 1729 lduw [%l7 + %l4], %l7 ! Load >> 1730 4: mov %i2, %o2 ! IEU0 Group >> 1731 ldx [%curptr + TI_FLAGS], %l0 ! Load >> 1732 >> 1733 mov %i3, %o3 ! IEU1 >> 1734 mov %i4, %o4 ! IEU0 Group >> 1735 andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU1 Group+1 bubble >> 1736 bne,pn %icc, linux_syscall_trace ! CTI Group >> 1737 mov %i0, %l5 ! IEU0 >> 1738 2: call %l7 ! CTI Group brk forced >> 1739 mov %i5, %o5 ! IEU0 >> 1740 nop >> 1741 >> 1742 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] >> 1743 ret_sys_call: >> 1744 #ifdef SYSCALL_TRACING >> 1745 mov %o0, %o1 >> 1746 call syscall_trace_exit >> 1747 add %sp, PTREGS_OFF, %o0 >> 1748 mov %o1, %o0 >> 1749 #endif >> 1750 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 >> 1751 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc >> 1752 sra %o0, 0, %o0 >> 1753 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 >> 1754 cmp %o0, -ENOIOCTLCMD >> 1755 sllx %g2, 32, %g2 >> 1756 bgeu,pn %xcc, 1f >> 1757 andcc %l0, _TIF_SYSCALL_TRACE, %l6 >> 1758 80: >> 1759 andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ >> 1760 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] >> 1761 bne,pn %icc, linux_syscall_trace2 >> 1762 add %l1, 0x4, %l2 ! npc = npc+4 >> 1763 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] >> 1764 ba,pt %xcc, rtrap_clr_l6 >> 1765 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 2143 1766 2144 #ifdef CONFIG_IRQSTACKS << 2145 /* void call_on_stack(unsigned long param1, v << 2146 unsigned long new_stack << 2147 ENTRY_CFI(call_on_stack, FRAME=2*FRAME_SIZE,C << 2148 ENTRY(_call_on_stack) << 2149 copy %sp, %r1 << 2150 << 2151 /* Regarding the HPPA calling convent << 2152 we assume the PIC register is not << 2153 CONFIG_64BIT, the argument pointer << 2154 argument region allocated for the << 2155 << 2156 /* Switch to new stack. We allocate << 2157 ldo 2*FRAME_SIZE(%arg2), %sp << 2158 # ifdef CONFIG_64BIT << 2159 /* Save previous stack pointer and re << 2160 STREG %rp, -FRAME_SIZE-RP_OFFSET(%s << 2161 /* Calls always use function descript << 2162 LDREG 16(%arg1), %arg1 << 2163 bve,l (%arg1), %rp << 2164 STREG %r1, -FRAME_SIZE-REG_SZ(%sp) << 2165 LDREG -FRAME_SIZE-RP_OFFSET(%sp), % << 2166 bve (%rp) << 2167 LDREG -FRAME_SIZE-REG_SZ(%sp), %sp << 2168 # else << 2169 /* Save previous stack pointer and re << 2170 STREG %r1, -FRAME_SIZE-REG_SZ(%sp) << 2171 STREG %rp, -FRAME_SIZE-RP_OFFSET(%s << 2172 /* Calls use function descriptor if P << 2173 bb,>=,n %arg1, 30, 1f << 2174 depwi 0,31,2, %arg1 << 2175 LDREG 0(%arg1), %arg1 << 2176 1: 1767 1: 2177 be,l 0(%sr4,%arg1), %sr0, %r31 !! 1768 /* Really a failure? Check if force_successful_syscall_return() 2178 copy %r31, %rp !! 1769 * was invoked. 2179 LDREG -FRAME_SIZE-RP_OFFSET(%sp), % << 2180 bv (%rp) << 2181 LDREG -FRAME_SIZE-REG_SZ(%sp), %sp << 2182 # endif /* CONFIG_64BIT */ << 2183 ENDPROC_CFI(call_on_stack) << 2184 #endif /* CONFIG_IRQSTACKS */ << 2185 << 2186 ENTRY_CFI(get_register) << 2187 /* << 2188 * get_register is used by the non ac << 2189 * copy the value of the general regi << 2190 * r1. This routine can't be used for << 2191 * the rfir will restore the original << 2192 * registers we put a -1 into r1 to i << 2193 * should not be used (the register b << 2194 * a -1 in it, but that is OK, it jus << 2195 * to use the slow path instead). << 2196 */ 1770 */ 2197 blr %r8,%r0 !! 1771 ldx [%curptr + TI_FLAGS], %l0 ! Load 2198 nop !! 1772 andcc %l0, _TIF_SYSCALL_SUCCESS, %g0 2199 bv %r0(%r25) /* r0 */ !! 1773 be,pt %icc, 1f 2200 copy %r0,%r1 !! 1774 andcc %l0, _TIF_SYSCALL_TRACE, %l6 2201 bv %r0(%r25) /* r1 - shadowed !! 1775 andn %l0, _TIF_SYSCALL_SUCCESS, %l0 2202 ldi -1,%r1 !! 1776 ba,pt %xcc, 80b 2203 bv %r0(%r25) /* r2 */ !! 1777 stx %l0, [%curptr + TI_FLAGS] 2204 copy %r2,%r1 !! 1778 2205 bv %r0(%r25) /* r3 */ !! 1779 /* System call failure, set Carry condition code. 2206 copy %r3,%r1 !! 1780 * Also, get abs(errno) to return to the process. 2207 bv %r0(%r25) /* r4 */ << 2208 copy %r4,%r1 << 2209 bv %r0(%r25) /* r5 */ << 2210 copy %r5,%r1 << 2211 bv %r0(%r25) /* r6 */ << 2212 copy %r6,%r1 << 2213 bv %r0(%r25) /* r7 */ << 2214 copy %r7,%r1 << 2215 bv %r0(%r25) /* r8 - shadowed << 2216 ldi -1,%r1 << 2217 bv %r0(%r25) /* r9 - shadowed << 2218 ldi -1,%r1 << 2219 bv %r0(%r25) /* r10 */ << 2220 copy %r10,%r1 << 2221 bv %r0(%r25) /* r11 */ << 2222 copy %r11,%r1 << 2223 bv %r0(%r25) /* r12 */ << 2224 copy %r12,%r1 << 2225 bv %r0(%r25) /* r13 */ << 2226 copy %r13,%r1 << 2227 bv %r0(%r25) /* r14 */ << 2228 copy %r14,%r1 << 2229 bv %r0(%r25) /* r15 */ << 2230 copy %r15,%r1 << 2231 bv %r0(%r25) /* r16 - shadowe << 2232 ldi -1,%r1 << 2233 bv %r0(%r25) /* r17 - shadowe << 2234 ldi -1,%r1 << 2235 bv %r0(%r25) /* r18 */ << 2236 copy %r18,%r1 << 2237 bv %r0(%r25) /* r19 */ << 2238 copy %r19,%r1 << 2239 bv %r0(%r25) /* r20 */ << 2240 copy %r20,%r1 << 2241 bv %r0(%r25) /* r21 */ << 2242 copy %r21,%r1 << 2243 bv %r0(%r25) /* r22 */ << 2244 copy %r22,%r1 << 2245 bv %r0(%r25) /* r23 */ << 2246 copy %r23,%r1 << 2247 bv %r0(%r25) /* r24 - shadowe << 2248 ldi -1,%r1 << 2249 bv %r0(%r25) /* r25 - shadowe << 2250 ldi -1,%r1 << 2251 bv %r0(%r25) /* r26 */ << 2252 copy %r26,%r1 << 2253 bv %r0(%r25) /* r27 */ << 2254 copy %r27,%r1 << 2255 bv %r0(%r25) /* r28 */ << 2256 copy %r28,%r1 << 2257 bv %r0(%r25) /* r29 */ << 2258 copy %r29,%r1 << 2259 bv %r0(%r25) /* r30 */ << 2260 copy %r30,%r1 << 2261 bv %r0(%r25) /* r31 */ << 2262 copy %r31,%r1 << 2263 ENDPROC_CFI(get_register) << 2264 << 2265 << 2266 ENTRY_CFI(set_register) << 2267 /* << 2268 * set_register is used by the non ac << 2269 * copy the value of r1 into the gene << 2270 * r8. << 2271 */ 1781 */ 2272 blr %r8,%r0 !! 1782 1: 2273 nop !! 1783 sub %g0, %o0, %o0 2274 bv %r0(%r25) /* r0 (silly, bu !! 1784 or %g3, %g2, %g3 2275 copy %r1,%r0 !! 1785 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] 2276 bv %r0(%r25) /* r1 */ !! 1786 mov 1, %l6 2277 copy %r1,%r1 !! 1787 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] 2278 bv %r0(%r25) /* r2 */ !! 1788 bne,pn %icc, linux_syscall_trace2 2279 copy %r1,%r2 !! 1789 add %l1, 0x4, %l2 !npc = npc+4 2280 bv %r0(%r25) /* r3 */ !! 1790 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] 2281 copy %r1,%r3 !! 1791 2282 bv %r0(%r25) /* r4 */ !! 1792 b,pt %xcc, rtrap 2283 copy %r1,%r4 !! 1793 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 2284 bv %r0(%r25) /* r5 */ !! 1794 linux_syscall_trace2: 2285 copy %r1,%r5 !! 1795 call syscall_trace 2286 bv %r0(%r25) /* r6 */ !! 1796 nop 2287 copy %r1,%r6 !! 1797 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] 2288 bv %r0(%r25) /* r7 */ !! 1798 ba,pt %xcc, rtrap 2289 copy %r1,%r7 !! 1799 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 2290 bv %r0(%r25) /* r8 */ << 2291 copy %r1,%r8 << 2292 bv %r0(%r25) /* r9 */ << 2293 copy %r1,%r9 << 2294 bv %r0(%r25) /* r10 */ << 2295 copy %r1,%r10 << 2296 bv %r0(%r25) /* r11 */ << 2297 copy %r1,%r11 << 2298 bv %r0(%r25) /* r12 */ << 2299 copy %r1,%r12 << 2300 bv %r0(%r25) /* r13 */ << 2301 copy %r1,%r13 << 2302 bv %r0(%r25) /* r14 */ << 2303 copy %r1,%r14 << 2304 bv %r0(%r25) /* r15 */ << 2305 copy %r1,%r15 << 2306 bv %r0(%r25) /* r16 */ << 2307 copy %r1,%r16 << 2308 bv %r0(%r25) /* r17 */ << 2309 copy %r1,%r17 << 2310 bv %r0(%r25) /* r18 */ << 2311 copy %r1,%r18 << 2312 bv %r0(%r25) /* r19 */ << 2313 copy %r1,%r19 << 2314 bv %r0(%r25) /* r20 */ << 2315 copy %r1,%r20 << 2316 bv %r0(%r25) /* r21 */ << 2317 copy %r1,%r21 << 2318 bv %r0(%r25) /* r22 */ << 2319 copy %r1,%r22 << 2320 bv %r0(%r25) /* r23 */ << 2321 copy %r1,%r23 << 2322 bv %r0(%r25) /* r24 */ << 2323 copy %r1,%r24 << 2324 bv %r0(%r25) /* r25 */ << 2325 copy %r1,%r25 << 2326 bv %r0(%r25) /* r26 */ << 2327 copy %r1,%r26 << 2328 bv %r0(%r25) /* r27 */ << 2329 copy %r1,%r27 << 2330 bv %r0(%r25) /* r28 */ << 2331 copy %r1,%r28 << 2332 bv %r0(%r25) /* r29 */ << 2333 copy %r1,%r29 << 2334 bv %r0(%r25) /* r30 */ << 2335 copy %r1,%r30 << 2336 bv %r0(%r25) /* r31 */ << 2337 copy %r1,%r31 << 2338 ENDPROC_CFI(set_register) << 2339 1800 >> 1801 .align 32 >> 1802 .globl __flushw_user >> 1803 __flushw_user: >> 1804 rdpr %otherwin, %g1 >> 1805 brz,pn %g1, 2f >> 1806 clr %g2 >> 1807 1: save %sp, -128, %sp >> 1808 rdpr %otherwin, %g1 >> 1809 brnz,pt %g1, 1b >> 1810 add %g2, 1, %g2 >> 1811 1: sub %g2, 1, %g2 >> 1812 brnz,pt %g2, 1b >> 1813 restore %g0, %g0, %g0 >> 1814 2: retl >> 1815 nop
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.