blob: 65e4561e7d5c817415b2f51f1bf7765d1fe5c509 [file] [log] [blame]
Daniel Hellstromc2f02da2008-03-28 09:47:00 +01001/*
2 * Added to U-boot,
3 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
4 * Copyright (C) 2007
5 *
6 * LEON2/3 LIBIO low-level routines
7 * Written by Jiri Gaisler.
8 * Copyright (C) 2004 Gaisler Research AB
Wolfgang Denk1a459662013-07-08 09:37:19 +02009 *
10 * SPDX-License-Identifier: GPL-2.0+
11 */
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010012
Wolfgang Denk1a459662013-07-08 09:37:19 +020013#ifndef __SPARC_WINMACRO_H__
14#define __SPARC_WINMACRO_H__
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010015
Wolfgang Denk1a459662013-07-08 09:37:19 +020016#include <asm/asmmacro.h>
17#include <asm/stack.h>
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010018
Wolfgang Denk1a459662013-07-08 09:37:19 +020019/* Store the register window onto the 8-byte aligned area starting
20 * at %reg. It might be %sp, it might not, we don't care.
21 */
22#define RW_STORE(reg) \
23 std %l0, [%reg + RW_L0]; \
24 std %l2, [%reg + RW_L2]; \
25 std %l4, [%reg + RW_L4]; \
26 std %l6, [%reg + RW_L6]; \
27 std %i0, [%reg + RW_I0]; \
28 std %i2, [%reg + RW_I2]; \
29 std %i4, [%reg + RW_I4]; \
30 std %i6, [%reg + RW_I6];
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010031
Wolfgang Denk1a459662013-07-08 09:37:19 +020032/* Load a register window from the area beginning at %reg. */
33#define RW_LOAD(reg) \
34 ldd [%reg + RW_L0], %l0; \
35 ldd [%reg + RW_L2], %l2; \
36 ldd [%reg + RW_L4], %l4; \
37 ldd [%reg + RW_L6], %l6; \
38 ldd [%reg + RW_I0], %i0; \
39 ldd [%reg + RW_I2], %i2; \
40 ldd [%reg + RW_I4], %i4; \
41 ldd [%reg + RW_I6], %i6;
42
43/* Loading and storing struct pt_reg trap frames. */
44#define PT_LOAD_INS(base_reg) \
45 ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
46 ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
47 ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
48 ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
49
50#define PT_LOAD_GLOBALS(base_reg) \
51 ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
52 ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
53 ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
54 ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
55
56#define PT_LOAD_YREG(base_reg, scratch) \
57 ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
58 wr %scratch, 0x0, %y;
59
60#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
61 ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
62 ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
63 ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
64
65#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
66 PT_LOAD_YREG(base_reg, scratch) \
67 PT_LOAD_INS(base_reg) \
68 PT_LOAD_GLOBALS(base_reg) \
69 PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
70
71#define PT_STORE_INS(base_reg) \
72 std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
73 std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
74 std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
75 std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
76
77#define PT_STORE_GLOBALS(base_reg) \
78 st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
79 std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
80 std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
81 std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
82
83#define PT_STORE_YREG(base_reg, scratch) \
84 rd %y, %scratch; \
85 st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
86
87#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
88 st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
89 st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
90 st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
91
92#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
93 PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
94 PT_STORE_GLOBALS(base_reg) \
95 PT_STORE_YREG(base_reg, g_scratch) \
96 PT_STORE_INS(base_reg)
97
98/* Store the fpu register window*/
99#define FW_STORE(reg) \
100 std %f0, [reg + FW_F0]; \
101 std %f2, [reg + FW_F2]; \
102 std %f4, [reg + FW_F4]; \
103 std %f6, [reg + FW_F6]; \
104 std %f8, [reg + FW_F8]; \
105 std %f10, [reg + FW_F10]; \
106 std %f12, [reg + FW_F12]; \
107 std %f14, [reg + FW_F14]; \
108 std %f16, [reg + FW_F16]; \
109 std %f18, [reg + FW_F18]; \
110 std %f20, [reg + FW_F20]; \
111 std %f22, [reg + FW_F22]; \
112 std %f24, [reg + FW_F24]; \
113 std %f26, [reg + FW_F26]; \
114 std %f28, [reg + FW_F28]; \
115 std %f30, [reg + FW_F30]; \
116 st %fsr, [reg + FW_FSR];
117
118/* Load a fpu register window from the area beginning at reg. */
119#define FW_LOAD(reg) \
120 ldd [reg + FW_F0], %f0; \
121 ldd [reg + FW_F2], %f2; \
122 ldd [reg + FW_F4], %f4; \
123 ldd [reg + FW_F6], %f6; \
124 ldd [reg + FW_F8], %f8; \
125 ldd [reg + FW_F10], %f10; \
126 ldd [reg + FW_F12], %f12; \
127 ldd [reg + FW_F14], %f14; \
128 ldd [reg + FW_F16], %f16; \
129 ldd [reg + FW_F18], %f18; \
130 ldd [reg + FW_F20], %f20; \
131 ldd [reg + FW_F22], %f22; \
132 ldd [reg + FW_F24], %f24; \
133 ldd [reg + FW_F26], %f26; \
134 ldd [reg + FW_F28], %f28; \
135 ldd [reg + FW_F30], %f30; \
136 ld [reg + FW_FSR], %fsr;
137
138#endif
Daniel Hellstromc2f02da2008-03-28 09:47:00 +0100139
140#ifndef __SPARC_WINMACRO_H__
141#define __SPARC_WINMACRO_H__
142
143#include <asm/asmmacro.h>
144#include <asm/stack.h>
145
146/* Store the register window onto the 8-byte aligned area starting
147 * at %reg. It might be %sp, it might not, we don't care.
148 */
149#define RW_STORE(reg) \
150 std %l0, [%reg + RW_L0]; \
151 std %l2, [%reg + RW_L2]; \
152 std %l4, [%reg + RW_L4]; \
153 std %l6, [%reg + RW_L6]; \
154 std %i0, [%reg + RW_I0]; \
155 std %i2, [%reg + RW_I2]; \
156 std %i4, [%reg + RW_I4]; \
157 std %i6, [%reg + RW_I6];
158
159/* Load a register window from the area beginning at %reg. */
160#define RW_LOAD(reg) \
161 ldd [%reg + RW_L0], %l0; \
162 ldd [%reg + RW_L2], %l2; \
163 ldd [%reg + RW_L4], %l4; \
164 ldd [%reg + RW_L6], %l6; \
165 ldd [%reg + RW_I0], %i0; \
166 ldd [%reg + RW_I2], %i2; \
167 ldd [%reg + RW_I4], %i4; \
168 ldd [%reg + RW_I6], %i6;
169
170/* Loading and storing struct pt_reg trap frames. */
171#define PT_LOAD_INS(base_reg) \
172 ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
173 ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
174 ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
175 ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
176
177#define PT_LOAD_GLOBALS(base_reg) \
178 ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
179 ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
180 ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
181 ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
182
183#define PT_LOAD_YREG(base_reg, scratch) \
184 ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
185 wr %scratch, 0x0, %y;
186
187#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
188 ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
189 ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
190 ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
191
192#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
193 PT_LOAD_YREG(base_reg, scratch) \
194 PT_LOAD_INS(base_reg) \
195 PT_LOAD_GLOBALS(base_reg) \
196 PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
197
198#define PT_STORE_INS(base_reg) \
199 std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
200 std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
201 std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
202 std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
203
204#define PT_STORE_GLOBALS(base_reg) \
205 st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
206 std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
207 std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
208 std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
209
210#define PT_STORE_YREG(base_reg, scratch) \
211 rd %y, %scratch; \
212 st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
213
214#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
215 st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
216 st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
217 st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
218
219#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
220 PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
221 PT_STORE_GLOBALS(base_reg) \
222 PT_STORE_YREG(base_reg, g_scratch) \
223 PT_STORE_INS(base_reg)
224
225/* Store the fpu register window*/
226#define FW_STORE(reg) \
227 std %f0, [reg + FW_F0]; \
228 std %f2, [reg + FW_F2]; \
229 std %f4, [reg + FW_F4]; \
230 std %f6, [reg + FW_F6]; \
231 std %f8, [reg + FW_F8]; \
232 std %f10, [reg + FW_F10]; \
233 std %f12, [reg + FW_F12]; \
234 std %f14, [reg + FW_F14]; \
235 std %f16, [reg + FW_F16]; \
236 std %f18, [reg + FW_F18]; \
237 std %f20, [reg + FW_F20]; \
238 std %f22, [reg + FW_F22]; \
239 std %f24, [reg + FW_F24]; \
240 std %f26, [reg + FW_F26]; \
241 std %f28, [reg + FW_F28]; \
242 std %f30, [reg + FW_F30]; \
243 st %fsr, [reg + FW_FSR];
244
245/* Load a fpu register window from the area beginning at reg. */
246#define FW_LOAD(reg) \
247 ldd [reg + FW_F0], %f0; \
248 ldd [reg + FW_F2], %f2; \
249 ldd [reg + FW_F4], %f4; \
250 ldd [reg + FW_F6], %f6; \
251 ldd [reg + FW_F8], %f8; \
252 ldd [reg + FW_F10], %f10; \
253 ldd [reg + FW_F12], %f12; \
254 ldd [reg + FW_F14], %f14; \
255 ldd [reg + FW_F16], %f16; \
256 ldd [reg + FW_F18], %f18; \
257 ldd [reg + FW_F20], %f20; \
258 ldd [reg + FW_F22], %f22; \
259 ldd [reg + FW_F24], %f24; \
260 ldd [reg + FW_F26], %f26; \
261 ldd [reg + FW_F28], %f28; \
262 ldd [reg + FW_F30], %f30; \
263 ld [reg + FW_FSR], %fsr;
264
265#endif