| 1 | /*	$OpenBSD: cpustate.h,v 1.11 2015/09/27 18:17:08 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 | #define	KERN_REG_SIZE		(NUMSAVEREGS * REGSZ) |
| 30 | #define	KERN_EXC_FRAME_SIZE	(CF_SZ + KERN_REG_SIZE + 16) |
| 31 | |
| 32 | #define	SAVE_REG(reg, offs, base, bo) \ |
| 33 | 	REG_S	reg, bo + (REGSZ * offs) (base) |
| 34 | |
| 35 | #define	RESTORE_REG(reg, offs, base, bo) \ |
| 36 | 	REG_L	reg, bo + (REGSZ * offs) (base) |
| 37 | |
| 38 | /* |
| 39 | * This macro saves the 'scratch' cpu state on stack. |
| 40 | * Macros are generic so no 'special' instructions! |
| 41 | * a0 will have a pointer to the 'frame' on return. |
| 42 | * a1 will have saved STATUS_REG on return. |
| 43 | * a3 will have the exception pc on 'return'. |
| 44 | * No traps, no interrupts if frame = k1 or k0! |
| 45 | * Temp regs are saved with their register number so |
| 46 | * branch emulation etc works properly. |
| 47 | */ |
| 48 | #define	SAVE_CPU(frame, bo)			 \ |
| 49 | 	SAVE_REG(AT, AST, frame, bo)		;\ |
| 50 | 	SAVE_REG(v0, V0, frame, bo)		;\ |
| 51 | 	SAVE_REG(v1, V1, frame, bo)		;\ |
| 52 | 	SAVE_REG(a0, A0, frame, bo)		;\ |
| 53 | 	SAVE_REG(a1, A1, frame, bo)		;\ |
| 54 | 	SAVE_REG(a2, A2, frame, bo)		;\ |
| 55 | 	SAVE_REG(a3, A3, frame, bo)		;\ |
| 56 | 	MFC0	a0, COP_0_CAUSE_REG		;\ |
| 57 | 	MFC0_HAZARD				;\ |
| 58 | 	SAVE_REG(a4, A4, frame, bo)		;\ |
| 59 | 	SAVE_REG(a5, A5, frame, bo)		;\ |
| 60 | 	MFC0	a1, COP_0_STATUS_REG		;\ |
| 61 | 	MFC0_HAZARD				;\ |
| 62 | 	SAVE_REG(a6, A6, frame, bo)		;\ |
| 63 | 	SAVE_REG(a7, A7, frame, bo)		;\ |
| 64 | 	PRE_MFC0_ADDR_HAZARD			;\ |
| 65 | 	DMFC0	a2, COP_0_BAD_VADDR		;\ |
| 66 | 	MFC0_HAZARD				;\ |
| 67 | 	SAVE_REG(t0, T0, frame, bo)		;\ |
| 68 | 	SAVE_REG(t1, T1, frame, bo)		;\ |
| 69 | 	DMFC0	a3, COP_0_EXC_PC		;\ |
| 70 | 	MFC0_HAZARD				;\ |
| 71 | 	SAVE_REG(t2, T2, frame, bo)		;\ |
| 72 | 	SAVE_REG(t3, T3, frame, bo)		;\ |
| 73 | 	SAVE_REG(t8, T8, frame, bo)		;\ |
| 74 | 	SAVE_REG(t9, T9, frame, bo)		;\ |
| 75 | 	SAVE_REG(gp, GP, frame, bo)		;\ |
| 76 | 	SAVE_REG(ra, RA, frame, bo)		;\ |
| 77 | 	mflo	v0				;\ |
| 78 | 	mfhi	v1				;\ |
| 79 | 	SAVE_REG(v0, MULLO, frame, bo)		;\ |
| 80 | 	SAVE_REG(v1, MULHI, frame, bo)		;\ |
| 81 | 	SAVE_REG(a0, CAUSE, frame, bo)		;\ |
| 82 | 	SAVE_REG(a1, SR, frame, bo)		;\ |
| 83 | 	SAVE_REG(a2, BADVADDR, frame, bo)	;\ |
| 84 | 	SAVE_REG(a3, PC, frame, bo)		;\ |
| 85 | 	SAVE_REG(sp, SP, frame, bo)		;\ |
| 86 | 	PTR_ADDU a0, frame, bo			;\ |
| 87 | 	GET_CPU_INFO(v0, v1)			;\ |
| 88 | 	lw	a2, CI_IPL(v0)			;\ |
| 89 | 	SAVE_REG(a2, CPL, frame, bo) |
| 90 | |
| 91 | /* |
| 92 | * Save 'callee save' registers in frame to aid DDB. |
| 93 | */ |
| 94 | #define	SAVE_CPU_SREG(frame, bo)		 \ |
| 95 | 	SAVE_REG(s0, S0, frame, bo)		;\ |
| 96 | 	SAVE_REG(s1, S1, frame, bo)		;\ |
| 97 | 	SAVE_REG(s2, S2, frame, bo)		;\ |
| 98 | 	SAVE_REG(s3, S3, frame, bo)		;\ |
| 99 | 	SAVE_REG(s4, S4, frame, bo)		;\ |
| 100 | 	SAVE_REG(s5, S5, frame, bo)		;\ |
| 101 | 	SAVE_REG(s6, S6, frame, bo)		;\ |
| 102 | 	SAVE_REG(s7, S7, frame, bo)		;\ |
| 103 | 	SAVE_REG(s8, S8, frame, bo) |
| 104 | |
| 105 | /* |
| 106 | * Restore cpu state. When called a0 = EXC_PC. |
| 107 | */ |
| 108 | #define	RESTORE_CPU(frame, bo)			 \ |
| 109 | 	RESTORE_REG(t1, SR, frame, bo)		;\ |
| 110 | 	RESTORE_REG(t2, MULLO, frame, bo)	;\ |
| 111 | 	RESTORE_REG(t3, MULHI, frame, bo)	;\ |
| 112 | 	MTC0	t1, COP_0_STATUS_REG		;\ |
| 113 | 	MTC0_SR_IE_HAZARD			;\ |
| 114 | 	mtlo	t2				;\ |
| 115 | 	mthi	t3				;\ |
| 116 | 	DMTC0	a0, COP_0_EXC_PC		;\ |
| 117 | 	MTC0_HAZARD				;\ |
| 118 | 	RESTORE_REG(AT, AST, frame, bo)		;\ |
| 119 | 	RESTORE_REG(v0, V0, frame, bo)		;\ |
| 120 | 	RESTORE_REG(v1, V1, frame, bo)		;\ |
| 121 | 	RESTORE_REG(a0, A0, frame, bo)		;\ |
| 122 | 	RESTORE_REG(a1, A1, frame, bo)		;\ |
| 123 | 	RESTORE_REG(a2, A2, frame, bo)		;\ |
| 124 | 	RESTORE_REG(a3, A3, frame, bo)		;\ |
| 125 | 	RESTORE_REG(a4, A4, frame, bo)		;\ |
| 126 | 	RESTORE_REG(a5, A5, frame, bo)		;\ |
| 127 | 	RESTORE_REG(a6, A6, frame, bo)		;\ |
| 128 | 	RESTORE_REG(a7, A7, frame, bo)		;\ |
| 129 | 	RESTORE_REG(t0, T0, frame, bo)		;\ |
| 130 | 	RESTORE_REG(t1, T1, frame, bo)		;\ |
| 131 | 	RESTORE_REG(t2, T2, frame, bo)		;\ |
| 132 | 	RESTORE_REG(t3, T3, frame, bo)		;\ |
| 133 | 	RESTORE_REG(t8, T8, frame, bo)		;\ |
| 134 | 	RESTORE_REG(t9, T9, frame, bo)		;\ |
| 135 | 	RESTORE_REG(gp, GP, frame, bo)		;\ |
| 136 | 	RESTORE_REG(ra, RA, frame, bo) |
| 137 | |
| 138 | /* |
| 139 | * Restore 'callee save' registers |
| 140 | */ |
| 141 | #define	RESTORE_CPU_SREG(frame, bo)		 \ |
| 142 | 	RESTORE_REG(s0, S0, frame, bo)		;\ |
| 143 | 	RESTORE_REG(s1, S1, frame, bo)		;\ |
| 144 | 	RESTORE_REG(s2, S2, frame, bo)		;\ |
| 145 | 	RESTORE_REG(s3, S3, frame, bo)		;\ |
| 146 | 	RESTORE_REG(s4, S4, frame, bo)		;\ |
| 147 | 	RESTORE_REG(s5, S5, frame, bo)		;\ |
| 148 | 	RESTORE_REG(s6, S6, frame, bo)		;\ |
| 149 | 	RESTORE_REG(s7, S7, frame, bo)		;\ |
| 150 | 	RESTORE_REG(s8, S8, frame, bo) |