Annotation of sys/arch/mips64/mips64/exception.S, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: exception.S,v 1.13 2007/05/25 20:47:19 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: * 1. Redistributions of source code must retain the above copyright
! 10: * notice, this list of conditions and the following disclaimer.
! 11: * 2. Redistributions in binary form must reproduce the above copyright
! 12: * notice, this list of conditions and the following disclaimer in the
! 13: * documentation and/or other materials provided with the distribution.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
! 16: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 18: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
! 19: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 20: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 21: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 23: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 24: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 25: * SUCH DAMAGE.
! 26: *
! 27: */
! 28:
! 29: /*
! 30: * This code handles exceptions and dispatches to the
! 31: * correct handler depending on the exception type.
! 32: *
! 33: * Exceptions are directed to the following addresses:
! 34: * 0xffffffffbfc00000 Reset, NMI etc. Not handled by the kernel.
! 35: * 0xffffffff80000000 TLB refill, not in exception.
! 36: * 0xffffffff80000080 XTLB refill, not in exception.
! 37: * 0xffffffffa0000100 Cache errors.
! 38: * 0xffffffff80000180 Interrupts. Same as next.
! 39: * 0xffffffff80000180 Everything else...
! 40: */
! 41:
! 42: #include <machine/param.h>
! 43: #include <machine/psl.h>
! 44: #include <machine/asm.h>
! 45: #include <machine/cpu.h>
! 46: #include <machine/regnum.h>
! 47: #include <machine/cpustate.h>
! 48:
! 49: #include "assym.h"
! 50:
! 51: .set mips3
! 52:
! 53: .data
! 54: .globl int_nest_cntr
! 55: int_nest_cntr:
! 56: .word -1
! 57: .text
! 58:
! 59: k_exception_table:
! 60: PTR_VAL k_intr
! 61: PTR_VAL k_general
! 62: PTR_VAL k_tlb_inv
! 63: PTR_VAL k_tlb_inv
! 64: PTR_VAL k_general
! 65: PTR_VAL k_general
! 66: PTR_VAL k_general
! 67: PTR_VAL k_general
! 68: PTR_VAL k_general
! 69: PTR_VAL k_general
! 70: PTR_VAL k_general
! 71: PTR_VAL k_general
! 72: PTR_VAL k_general
! 73: PTR_VAL k_general
! 74: PTR_VAL k_general
! 75: PTR_VAL k_general
! 76: PTR_VAL k_general
! 77: PTR_VAL k_general
! 78: PTR_VAL k_general
! 79: PTR_VAL k_general
! 80: PTR_VAL k_general
! 81: PTR_VAL k_general
! 82: PTR_VAL k_general
! 83: PTR_VAL k_general
! 84: PTR_VAL k_general
! 85: PTR_VAL k_general
! 86: PTR_VAL k_general
! 87: PTR_VAL k_general
! 88: PTR_VAL k_general
! 89: PTR_VAL k_general
! 90: PTR_VAL k_general
! 91: PTR_VAL k_general
! 92:
! 93: u_exception_table:
! 94: PTR_VAL u_intr
! 95: PTR_VAL u_general
! 96: PTR_VAL u_general
! 97: PTR_VAL u_general
! 98: PTR_VAL u_general
! 99: PTR_VAL u_general
! 100: PTR_VAL u_general
! 101: PTR_VAL u_general
! 102: PTR_VAL u_general
! 103: PTR_VAL u_general
! 104: PTR_VAL u_general
! 105: PTR_VAL u_general
! 106: PTR_VAL u_general
! 107: PTR_VAL u_general
! 108: PTR_VAL u_general
! 109: PTR_VAL u_general
! 110: PTR_VAL u_general
! 111: PTR_VAL u_general
! 112: PTR_VAL u_general
! 113: PTR_VAL u_general
! 114: PTR_VAL u_general
! 115: PTR_VAL u_general
! 116: PTR_VAL u_general
! 117: PTR_VAL u_general
! 118: PTR_VAL u_general
! 119: PTR_VAL u_general
! 120: PTR_VAL u_general
! 121: PTR_VAL u_general
! 122: PTR_VAL u_general
! 123: PTR_VAL u_general
! 124: PTR_VAL u_general
! 125: PTR_VAL u_general
! 126:
! 127: .set noreorder # Noreorder is default style!
! 128:
! 129: /*---------------------------------------------------------------- exception
! 130: * General exception handler dispatcher. This code is copied
! 131: * to the vector area and must thus be PIC and less than 128
! 132: * bytes long to fit. Only k0 and k1 may be used at this time.
! 133: */
! 134: .globl exception
! 135: exception:
! 136: .set noat
! 137: mfc0 k0, COP_0_STATUS_REG
! 138: mfc0 k1, COP_0_CAUSE_REG
! 139: and k0, k0, SR_KSU_USER
! 140: beqz k0, k_exception # Kernel mode mode
! 141: and k1, k1, CR_EXC_CODE
! 142:
! 143: LA k0, u_exception_table
! 144: PTR_ADDU k0, k0, k1
! 145: #ifdef __LP64__
! 146: PTR_ADDU k0, k0, k1 # yes, twice...
! 147: #endif
! 148: PTR_L k0, 0(k0)
! 149: j k0
! 150: nop
! 151:
! 152: k_exception:
! 153: LA k0, k_exception_table
! 154: PTR_ADDU k0, k0, k1
! 155: #ifdef __LP64__
! 156: PTR_ADDU k0, k0, k1 # yes, twice...
! 157: #endif
! 158: PTR_L k0, 0(k0)
! 159: j k0
! 160: nop
! 161: .set at
! 162: .globl e_exception
! 163: e_exception:
! 164:
! 165:
! 166: /*---------------------------------------------------------------- k_intr
! 167: * Handle an interrupt in kernel mode. This is easy since we
! 168: * just need to save away the 'save' registers and state.
! 169: * State is saved on kernel stack.
! 170: */
! 171:
! 172: NNON_LEAF(k_intr, FRAMESZ(KERN_EXC_FRAME_SIZE), ra)
! 173: .set noat
! 174: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(KERN_EXC_FRAME_SIZE))
! 175: PTR_SUB k0, sp, FRAMESZ(KERN_EXC_FRAME_SIZE)
! 176: SAVE_CPU(k0, CF_RA_OFFS)
! 177: #if 0
! 178: cfc0 v1, COP_0_ICR
! 179: SAVE_REG(v1, IC, k0, CF_RA_OFFS)
! 180: #endif
! 181: .set at
! 182: move sp, k0 # Already on kernel stack
! 183: LA gp, _gp
! 184: and t0, a1, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK)
! 185: mtc0 t0, COP_0_STATUS_REG
! 186: LA t1, int_nest_cntr
! 187: lw t2, (t1)
! 188: addiu t2, 1
! 189: sw t2, (t1)
! 190: ITLBNOPFIX
! 191: PTR_S a0, 0(sp)
! 192: jal interrupt
! 193: PTR_S a3, CF_RA_OFFS + KERN_REG_SIZE(sp)
! 194:
! 195: mfc0 t0, COP_0_STATUS_REG # dis int preserve settings.
! 196: li t1, ~SR_INT_ENAB
! 197: and t0, t0, t1
! 198: mtc0 t0, COP_0_STATUS_REG
! 199:
! 200: LA t1, int_nest_cntr
! 201: lw t2, (t1)
! 202: addiu t2, -1
! 203: sw t2, (t1)
! 204:
! 205: PTR_L a0, CF_RA_OFFS + KERN_REG_SIZE(sp)
! 206: .set noat
! 207: #if 0
! 208: RESTORE_REG(t0, IC, sp, CF_RA_OFFS)
! 209: ctc0 t0, COP_0_ICR
! 210: #endif
! 211: RESTORE_CPU(sp, CF_RA_OFFS)
! 212: PTR_ADDU sp, sp, FRAMESZ(KERN_EXC_FRAME_SIZE)
! 213: sync
! 214: eret
! 215: .set at
! 216: END(k_intr)
! 217:
! 218: /*---------------------------------------------------------------- u_intr
! 219: * Handle an interrupt in user mode. Save the relevant user
! 220: * registers into the u.u_pcb struct. This will allow us
! 221: * to preempt the interrupted process. Full save is held
! 222: * off though until a switch() really is requiered.
! 223: */
! 224: NNON_LEAF(u_intr, FRAMESZ(CF_SZ), ra)
! 225: .set noat
! 226: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
! 227: PTR_L k0, curprocpaddr
! 228: SAVE_CPU(k0, 0)
! 229: #if 0
! 230: cfc0 v1, COP_0_ICR
! 231: SAVE_REG(v1, IC, k0, 0)
! 232: #endif
! 233: PTR_ADDU sp, k0, USPACE-FRAMESZ(CF_SZ)
! 234: LA gp, _gp
! 235: .set at
! 236: and t0, a1, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK)
! 237: mtc0 t0, COP_0_STATUS_REG
! 238: LA t1, int_nest_cntr
! 239: lw t2, (t1)
! 240: addiu t2, 1
! 241: sw t2, (t1)
! 242: ITLBNOPFIX
! 243: PTR_S a0, 0(sp)
! 244: jal interrupt
! 245: PTR_S a3, CF_RA_OFFS(sp) # for debugging
! 246:
! 247: lw v0, astpending # any pending interrupts?
! 248: beq v0, zero, 4f
! 249: nop
! 250:
! 251: PTR_L t0, curprocpaddr
! 252: SAVE_CPU_SREG(t0, 0)
! 253:
! 254: #ifdef PERFCNTRS
! 255: lw t0, cpu_is_rm7k
! 256: beqz t0, 1f # not an RM7K. Don't do perf save.
! 257:
! 258: mfc0 v0, COP_0_PC_CTRL
! 259: PTR_L t0, curproc
! 260: sw v0, P_PC_CTRL(t0)
! 261: dmfc0 v0, COP_0_WATCH_1
! 262: dmfc0 v1, COP_0_WATCH_2
! 263: sd v0, P_WATCH_1(t0)
! 264: sd v1, P_WATCH_2(t0)
! 265: mfc0 v0, COP_0_WATCH_M
! 266: mfc0 v1, COP_0_PC_COUNT
! 267: sw v0, P_WATCH_M(t0)
! 268: sw v1, P_PC_COUNT(t0)
! 269: mtc0 zero, COP_0_PC_CTRL
! 270: dmtc0 zero, COP_0_WATCH_1
! 271: dmtc0 zero, COP_0_WATCH_2
! 272: nop;nop;nop;nop
! 273: 1:
! 274: #endif
! 275: jal softintr
! 276: nop
! 277: /*
! 278: * Restore user registers and return. NOTE: interrupts are enabled.
! 279: */
! 280: #ifdef PERFCNTRS
! 281: lw t0, cpu_is_rm7k
! 282: beqz t0, 1f # not an RM7K. Don't do perf setup.
! 283:
! 284: PTR_L t1, curproc # set up rm7k.
! 285: ld v0, P_WATCH_1(t1)
! 286: dmtc0 v0, COP_0_WATCH_1
! 287: ld v0, P_WATCH_2(t1)
! 288: dmtc0 v0, COP_0_WATCH_2
! 289: lw v0, P_WATCH_M(t1)
! 290: mtc0 v0, COP_0_WATCH_M
! 291: lw v0, P_PC_CTRL(t1)
! 292: lw v1, P_PC_COUNT(t1)
! 293: nop;nop
! 294: mtc0 v0, COP_0_PC_CTRL
! 295: nop;nop;nop;nop
! 296: mtc0 v1, COP_0_PC_COUNT
! 297: nop;nop;nop;nop
! 298: 1:
! 299: #endif
! 300: PTR_L t0, curprocpaddr
! 301: RESTORE_CPU_SREG(t0, 0)
! 302:
! 303: 4:
! 304: mfc0 t0, COP_0_STATUS_REG # dis int preserve settings.
! 305: li t1, ~SR_INT_ENAB
! 306: and t0, t0, t1
! 307: mtc0 t0, COP_0_STATUS_REG
! 308:
! 309: LA t1, int_nest_cntr
! 310: lw t2, (t1)
! 311: addiu t2, -1
! 312: sw t2, (t1)
! 313:
! 314: ori t0, SR_EXL # restoring to user mode.
! 315: mtc0 t0, COP_0_STATUS_REG # must set exception level bit.
! 316:
! 317: PTR_L k0, curprocpaddr
! 318: RESTORE_REG(a3, CPL, k0, 0)
! 319: sw a3, cpl
! 320: .set noat
! 321: RESTORE_REG(a0, PC, k0, 0)
! 322: #if 0
! 323: RESTORE_REG(t0, IC, k0, 0)
! 324: ctc0 t0, COP_0_ICR
! 325: #endif
! 326: RESTORE_CPU(k0, 0)
! 327: RESTORE_REG(sp, SP, k0, 0)
! 328: LI k0, 0
! 329: LI k1, 0
! 330: sync
! 331: eret
! 332: .set at
! 333: END(u_intr)
! 334:
! 335: /*---------------------------------------------------------------- k_general
! 336: * Handle a kernel general trap. This is very much like
! 337: * k_intr except that we call ktrap instead of interrupt.
! 338: */
! 339:
! 340: NNON_LEAF(k_general, FRAMESZ(KERN_EXC_FRAME_SIZE), ra)
! 341: .set noat
! 342: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(KERN_EXC_FRAME_SIZE))
! 343: PTR_SUB k0, sp, FRAMESZ(KERN_EXC_FRAME_SIZE)
! 344: SAVE_CPU(k0, CF_RA_OFFS)
! 345: #if 0
! 346: cfc0 v1, COP_0_ICR
! 347: SAVE_REG(v1, IC, k0, CF_RA_OFFS)
! 348: #endif
! 349: #if defined(DDB)
! 350: SAVE_CPU_SREG(k0, CF_RA_OFFS)
! 351: #endif
! 352: .set at
! 353: move sp, k0 # Already on kernel stack
! 354: LA gp, _gp
! 355: and t0, a1, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK)
! 356: mtc0 t0, COP_0_STATUS_REG
! 357: ITLBNOPFIX
! 358: PTR_S a0, 0(sp)
! 359: jal trap
! 360: PTR_S a3, CF_RA_OFFS + KERN_REG_SIZE(sp)
! 361:
! 362: mfc0 t0, COP_0_STATUS_REG # dis int preserve settings.
! 363: li t1, ~SR_INT_ENAB
! 364: and t0, t0, t1
! 365: mtc0 t0, COP_0_STATUS_REG
! 366:
! 367: .set noat
! 368: #if 0
! 369: RESTORE_REG(t0, IC, sp, CF_RA_OFFS)
! 370: ctc0 t0, COP_0_ICR
! 371: #endif
! 372: RESTORE_REG(a0, PC, sp, CF_RA_OFFS)
! 373: RESTORE_CPU(sp, CF_RA_OFFS)
! 374: PTR_ADDU sp, sp, FRAMESZ(KERN_EXC_FRAME_SIZE)
! 375: sync
! 376: eret
! 377: .set at
! 378: END(k_general)
! 379:
! 380: /*---------------------------------------------------------------- u_general
! 381: * Handle a user general trap.
! 382: */
! 383: NNON_LEAF(u_general, FRAMESZ(CF_SZ), ra)
! 384: .set noat
! 385: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
! 386:
! 387: PTR_L k0, curprocpaddr
! 388: SAVE_CPU(k0, 0)
! 389: #if 0
! 390: cfc0 v1, COP_0_ICR
! 391: SAVE_REG(v1, IC, k0, 0)
! 392: #endif
! 393: SAVE_CPU_SREG(k0, 0)
! 394: PTR_ADDU sp, k0, USPACE-FRAMESZ(CF_SZ)
! 395: LA gp, _gp
! 396: .set at
! 397: and t0, a1, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK)
! 398: mtc0 t0, COP_0_STATUS_REG
! 399: ITLBNOPFIX
! 400:
! 401: #ifdef PERFCNTRS
! 402: lw t0, cpu_is_rm7k
! 403: beqz t0, 1f # not an RM7K. Don't do perf save.
! 404:
! 405: mfc0 v0, COP_0_PC_CTRL
! 406: PTR_L t0, curproc
! 407: sw v0, P_PC_CTRL(t0)
! 408: dmfc0 v0, COP_0_WATCH_1
! 409: dmfc0 v1, COP_0_WATCH_2
! 410: sd v0, P_WATCH_1(t0)
! 411: sd v1, P_WATCH_2(t0)
! 412: mfc0 v0, COP_0_WATCH_M
! 413: mfc0 v1, COP_0_PC_COUNT
! 414: sw v0, P_WATCH_M(t0)
! 415: sw v1, P_PC_COUNT(t0)
! 416: mtc0 zero, COP_0_PC_CTRL
! 417: nop;nop;nop;nop
! 418: 1:
! 419: #endif
! 420:
! 421: jal trap
! 422: PTR_S a3, CF_RA_OFFS(sp) # for debugging
! 423:
! 424: lw v0, astpending
! 425: beq v0, zero, 4f
! 426: nop
! 427:
! 428: PTR_L t0, curprocpaddr
! 429: SAVE_CPU_SREG(t0, 0)
! 430:
! 431: jal softintr
! 432: nop
! 433:
! 434: PTR_L t0, curprocpaddr
! 435: RESTORE_CPU_SREG(t0, 0)
! 436:
! 437: 4:
! 438: #ifdef PERFCNTRS
! 439: lw t0, cpu_is_rm7k
! 440: beqz t0, 1f # not an RM7K. Don't do perf setup.
! 441:
! 442: LOAD t0, curproc # set up rm7k.
! 443: ld v0, P_WATCH_1(t0)
! 444: dmtc0 v0, COP_0_WATCH_1
! 445: ld v0, P_WATCH_2(t0)
! 446: dmtc0 v0, COP_0_WATCH_2
! 447: lw v0, P_WATCH_M(t0)
! 448: mtc0 v0, COP_0_WATCH_M
! 449: lw v0, P_PC_CTRL(t0)
! 450: lw v1, P_PC_COUNT(t0)
! 451: nop;nop
! 452: mtc0 v0, COP_0_PC_CTRL
! 453: nop;nop;nop;nop
! 454: mtc0 v1, COP_0_PC_COUNT
! 455: nop;nop;nop;nop
! 456: 1:
! 457: #endif
! 458: mfc0 t0, COP_0_STATUS_REG # dis int preserve settings.
! 459: li t1, ~SR_INT_ENAB
! 460: and t0, t0, t1
! 461: mtc0 t0, COP_0_STATUS_REG
! 462: ITLBNOPFIX
! 463:
! 464: ori t0, SR_EXL # restoring to user mode.
! 465: mtc0 t0, COP_0_STATUS_REG # must set exception level bit.
! 466: ITLBNOPFIX
! 467:
! 468: PTR_L k0, curprocpaddr
! 469: RESTORE_REG(a3, CPL, k0, 0)
! 470: sw a3, cpl
! 471: .set noat
! 472: RESTORE_CPU_SREG(k0, 0)
! 473: RESTORE_REG(a0, PC, k0, 0)
! 474: #if 0
! 475: RESTORE_REG(t0, IC, k0, 0)
! 476: ctc0 t0, COP_0_ICR
! 477: #endif
! 478: RESTORE_CPU(k0, 0)
! 479: RESTORE_REG(sp, SP, k0, 0)
! 480: LI k0, 0
! 481: LI k1, 0
! 482: sync
! 483: eret
! 484: .set at
! 485: END(u_general)
! 486:
! 487: #ifdef notyet
! 488: /*---------------------------------------------------------------- u_syscall
! 489: * Syscall exceptions are special such that they can be
! 490: * optimized by not saving more than what is really needed.
! 491: * Syscalls are actually 'function calls' from the user
! 492: * programs point of view and thus it does not expect us to
! 493: * save away all temporary registers etc. Just save state and
! 494: * args to avoid a lot of overhead.
! 495: */
! 496: NNON_LEAF(u_syscall, FRAMESZ(CF_SZ), ra)
! 497: .set noat
! 498: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
! 499:
! 500: REG_S a0, UADDR+PCB_REGS+(A0 * REGSZ)
! 501: REG_S a1, UADDR+PCB_REGS+(A1 * REGSZ)
! 502: REG_S a2, UADDR+PCB_REGS+(A2 * REGSZ)
! 503: REG_S a3, UADDR+PCB_REGS+(A3 * REGSZ)
! 504: mfc0 a0, COP_0_STATUS_REG # First arg is the status reg.
! 505: mfc0 a1, COP_0_CAUSE_REG # Second arg is the cause reg.
! 506: dmfc0 a3, COP_0_EXC_PC # Fourth arg is the pc.
! 507: REG_S sp, UADDR+PCB_REGS+(SP * REGSZ)
! 508: LA sp, KERNELSTACK - FRAMESZ(CF_SZ) # switch to kernel SP
! 509: REG_S ra, UADDR+PCB_REGS+(RA * REGSZ)
! 510: REG_S a0, UADDR+PCB_REGS+(SR * REGSZ)
! 511: REG_S a1, UADDR+PCB_REGS+(CAUSE * REGSZ)
! 512: REG_S a3, UADDR+PCB_REGS+(PC * REGSZ)
! 513: REG_S a3, CF_RA_OFFS(sp) # for debugging
! 514: LA gp, _gp # switch to kernel GP
! 515: lw a3, cpl
! 516: sw a3, UADDR+PCB_REGS+(CPL * REGSZ)
! 517: .set at
! 518: # Turn off fpu and enter kernel mode
! 519: and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_KSU_MASK | SR_INT_ENAB)
! 520: mtc0 t0, COP_0_STATUS_REG
! 521: li a0, UADDR+PCB_REGS
! 522: ITLBNOPFIX
! 523: /*
! 524: * If CPU is a RM7000 save away performance stuff.
! 525: */
! 526: #if 0
! 527: lw t0, cpu_is_rm7k
! 528: beqz t0, 1f # not an RM7K. Don't do perf save.
! 529: mfc0 v0, COP_0_PC_CTRL
! 530: lw t0, curproc
! 531: sw v0, P_PC_CTRL(t0)
! 532: dmfc0 v0, COP_0_WATCH_1
! 533: dmfc0 v1, COP_0_WATCH_2
! 534: sd v0, P_WATCH_1(t0)
! 535: sd v1, P_WATCH_2(t0)
! 536: mfc0 v0, COP_0_WATCH_M
! 537: mfc0 v1, COP_0_PC_COUNT
! 538: sw v0, P_WATCH_M(t0)
! 539: sw v1, P_PC_COUNT(t0)
! 540: mtc0 zero, COP_0_PC_CTRL
! 541: dmtc0 zero, COP_0_WATCH_1
! 542: dmtc0 zero, COP_0_WATCH_2
! 543: 1:
! 544: #endif
! 545:
! 546: jal trap
! 547: nop
! 548:
! 549: mfc0 t0, COP_0_STATUS_REG # dis int preserve settings.
! 550: li t1, ~SR_INT_ENAB
! 551: and t0, t0, t1
! 552: mtc0 t0, COP_0_STATUS_REG
! 553: ITLBNOPFIX
! 554:
! 555: ori t0, SR_EXL
! 556: mtc0 t0, COP_0_STATUS_REG # set exception level
! 557: ITLBNOPFIX
! 558:
! 559: #if 0
! 560: lw t0, cpu_is_rm7k
! 561: beqz t0, 1f # not an RM7K. Don't do perf setup.
! 562:
! 563: PTR_L t0, curproc # set up rm7k.
! 564: ld v0, P_WATCH_1(t0)
! 565: dmtc0 v0, COP_0_WATCH_1
! 566: ld v0, P_WATCH_2(t0)
! 567: dmtc0 v0, COP_0_WATCH_2
! 568: lw v0, P_WATCH_M(t0)
! 569: mtc0 v0, COP_0_WATCH_M
! 570: lw v0, P_PC_CTRL(t0)
! 571: lw v1, P_PC_COUNT(t0)
! 572: nop;nop
! 573: mtc0 v0, COP_0_PC_CTRL
! 574: nop;nop;nop;nop
! 575: mtc0 v1, COP_0_PC_COUNT
! 576: nop;nop;nop;nop
! 577: 1:
! 578: #endif
! 579: lw a3, UADDR+PCB_REGS+(CPL * REGSZ)
! 580: sw a3, cpl
! 581:
! 582: .set noat
! 583:
! 584: REG_L a0, UADDR+PCB_REGS+(SR * REGSZ)
! 585: mtc0 a0, COP_0_STATUS_REG # still exception level
! 586: REG_L a0, UADDR+PCB_REGS+(PC * REGSZ)
! 587: REG_L v0, UADDR+PCB_REGS+(V0 * REGSZ)
! 588: dmtc0 a0, COP_0_EXC_PC # set return address
! 589: REG_L v1, UADDR+PCB_REGS+(V1 * REGSZ)
! 590: REG_L gp, UADDR+PCB_REGS+(GP * REGSZ)
! 591: REG_L sp, UADDR+PCB_REGS+(SP * REGSZ)
! 592: REG_L ra, UADDR+PCB_REGS+(RA * REGSZ)
! 593: sync
! 594: eret
! 595: .set at
! 596: END(u_syscall)
! 597: #endif
! 598:
! 599:
! 600: /*-------------------------------------------------------------- proc_trampoline
! 601: * Setup for and return to user.
! 602: */
! 603: LEAF(proc_trampoline, 0)
! 604: sw zero, cpl # lower to spl0
! 605: lw t0, ipending
! 606: beq t0, zero, 0f
! 607: nop
! 608:
! 609: jal setsoftintr0 # process any pending ints
! 610: nop
! 611: 0:
! 612: jal s0
! 613: move a0,s1 # set up for return to user.
! 614:
! 615: #if 0
! 616: lw t0, cpu_is_rm7k
! 617: beqz t0, 1f # not an RM7K. Don't do IC reg.
! 618:
! 619: LOAD t0, curproc # set up rm7k.
! 620: ld v0, P_WATCH_1(t0)
! 621: dmtc0 v0, COP_0_WATCH_1
! 622: ld v0, P_WATCH_2(t0)
! 623: dmtc0 v0, COP_0_WATCH_2
! 624: lw v0, P_WATCH_M(t0)
! 625: mtc0 v0, COP_0_WATCH_M
! 626: lw v0, P_PC_CTRL(t0)
! 627: lw v1, P_PC_COUNT(t0)
! 628: nop;nop
! 629: mtc0 v0, COP_0_PC_CTRL
! 630: nop;nop;nop;nop
! 631: mtc0 v1, COP_0_PC_COUNT
! 632: nop;nop;nop;nop
! 633: li v0, IC_INT_PERF
! 634: ctc0 v0, COP_0_ICR # enable perfcntr interrupt.
! 635: 1:
! 636: #endif
! 637: mfc0 t0, COP_0_STATUS_REG # dis int preserve settings.
! 638: li t1, ~SR_INT_ENAB
! 639: and t0, t0, t1
! 640: mtc0 t0, COP_0_STATUS_REG
! 641: ITLBNOPFIX
! 642:
! 643: ori t0, SR_EXL # restoring to user mode.
! 644: mtc0 t0, COP_0_STATUS_REG # must set exception level bit.
! 645: ITLBNOPFIX
! 646:
! 647: .set noat
! 648: PTR_L k0, curprocpaddr
! 649: RESTORE_CPU_SREG(k0, 0)
! 650: RESTORE_REG(a0, PC, k0, 0)
! 651: #if 0
! 652: RESTORE_REG(t0, IC, k0, 0)
! 653: ctc0 t0, COP_0_ICR
! 654: #endif
! 655: RESTORE_CPU(k0, 0)
! 656: RESTORE_REG(sp, SP, k0, 0)
! 657: LI k0, 0
! 658: LI k1, 0
! 659: sync
! 660: eret
! 661: .set at
! 662: END(proc_trampoline)
CVSweb