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)