source: mainline/kernel/arch/sparc64/include/asm.h@ ed166f7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ed166f7 was ed166f7, checked in by Jakub Jermar <jakub@…>, 19 years ago

A lot of untested sparc64 stuff:

  • Write ASID to hardware when a thread is about to run in userspace.
  • Add userspace() and switch_to_userspace() functions.
  • Handle special cases when the userspace spill/fill handler causes MMU trap.
  • Resolve some TODOs in the existing sparc64 code.
  • sparc64 has now C99 compliant header guards.
  • Formatting and indentation fixes.
  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * Copyright (C) 2005 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup sparc64
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_sparc64_ASM_H_
36#define KERN_sparc64_ASM_H_
37
38#include <typedefs.h>
39#include <arch/types.h>
40#include <arch/register.h>
41#include <config.h>
42
43/** Read Processor State register.
44 *
45 * @return Value of PSTATE register.
46 */
47static inline uint64_t pstate_read(void)
48{
49 uint64_t v;
50
51 __asm__ volatile ("rdpr %%pstate, %0\n" : "=r" (v));
52
53 return v;
54}
55
56/** Write Processor State register.
57 *
58 * @param v New value of PSTATE register.
59 */
60static inline void pstate_write(uint64_t v)
61{
62 __asm__ volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
63}
64
65/** Read TICK_compare Register.
66 *
67 * @return Value of TICK_comapre register.
68 */
69static inline uint64_t tick_compare_read(void)
70{
71 uint64_t v;
72
73 __asm__ volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
74
75 return v;
76}
77
78/** Write TICK_compare Register.
79 *
80 * @param v New value of TICK_comapre register.
81 */
82static inline void tick_compare_write(uint64_t v)
83{
84 __asm__ volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
85}
86
87/** Read TICK Register.
88 *
89 * @return Value of TICK register.
90 */
91static inline uint64_t tick_read(void)
92{
93 uint64_t v;
94
95 __asm__ volatile ("rdpr %%tick, %0\n" : "=r" (v));
96
97 return v;
98}
99
100/** Write TICK Register.
101 *
102 * @param v New value of TICK register.
103 */
104static inline void tick_write(uint64_t v)
105{
106 __asm__ volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
107}
108
109/** Read SOFTINT Register.
110 *
111 * @return Value of SOFTINT register.
112 */
113static inline uint64_t softint_read(void)
114{
115 uint64_t v;
116
117 __asm__ volatile ("rd %%softint, %0\n" : "=r" (v));
118
119 return v;
120}
121
122/** Write SOFTINT Register.
123 *
124 * @param v New value of SOFTINT register.
125 */
126static inline void softint_write(uint64_t v)
127{
128 __asm__ volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
129}
130
131/** Write CLEAR_SOFTINT Register.
132 *
133 * Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
134 *
135 * @param v New value of CLEAR_SOFTINT register.
136 */
137static inline void clear_softint_write(uint64_t v)
138{
139 __asm__ volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
140}
141
142/** Write SET_SOFTINT Register.
143 *
144 * Bits set in SET_SOFTINT register will be set in SOFTINT register.
145 *
146 * @param v New value of SET_SOFTINT register.
147 */
148static inline void set_softint_write(uint64_t v)
149{
150 __asm__ volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
151}
152
153/** Enable interrupts.
154 *
155 * Enable interrupts and return previous
156 * value of IPL.
157 *
158 * @return Old interrupt priority level.
159 */
160static inline ipl_t interrupts_enable(void) {
161 pstate_reg_t pstate;
162 uint64_t value;
163
164 value = pstate_read();
165 pstate.value = value;
166 pstate.ie = true;
167 pstate_write(pstate.value);
168
169 return (ipl_t) value;
170}
171
172/** Disable interrupts.
173 *
174 * Disable interrupts and return previous
175 * value of IPL.
176 *
177 * @return Old interrupt priority level.
178 */
179static inline ipl_t interrupts_disable(void) {
180 pstate_reg_t pstate;
181 uint64_t value;
182
183 value = pstate_read();
184 pstate.value = value;
185 pstate.ie = false;
186 pstate_write(pstate.value);
187
188 return (ipl_t) value;
189}
190
191/** Restore interrupt priority level.
192 *
193 * Restore IPL.
194 *
195 * @param ipl Saved interrupt priority level.
196 */
197static inline void interrupts_restore(ipl_t ipl) {
198 pstate_reg_t pstate;
199
200 pstate.value = pstate_read();
201 pstate.ie = ((pstate_reg_t) ipl).ie;
202 pstate_write(pstate.value);
203}
204
205/** Return interrupt priority level.
206 *
207 * Return IPL.
208 *
209 * @return Current interrupt priority level.
210 */
211static inline ipl_t interrupts_read(void) {
212 return (ipl_t) pstate_read();
213}
214
215/** Return base address of current stack.
216 *
217 * Return the base address of the current stack.
218 * The stack is assumed to be STACK_SIZE bytes long.
219 * The stack must start on page boundary.
220 */
221static inline uintptr_t get_stack_base(void)
222{
223 uintptr_t v;
224
225 __asm__ volatile ("and %%sp, %1, %0\n" : "=r" (v) : "r" (~(STACK_SIZE-1)));
226
227 return v;
228}
229
230/** Read Version Register.
231 *
232 * @return Value of VER register.
233 */
234static inline uint64_t ver_read(void)
235{
236 uint64_t v;
237
238 __asm__ volatile ("rdpr %%ver, %0\n" : "=r" (v));
239
240 return v;
241}
242
243/** Read Trap Base Address register.
244 *
245 * @return Current value in TBA.
246 */
247static inline uint64_t tba_read(void)
248{
249 uint64_t v;
250
251 __asm__ volatile ("rdpr %%tba, %0\n" : "=r" (v));
252
253 return v;
254}
255
256/** Read Trap Program Counter register.
257 *
258 * @return Current value in TPC.
259 */
260static inline uint64_t tpc_read(void)
261{
262 uint64_t v;
263
264 __asm__ volatile ("rdpr %%tpc, %0\n" : "=r" (v));
265
266 return v;
267}
268
269/** Read Trap Level register.
270 *
271 * @return Current value in TL.
272 */
273static inline uint64_t tl_read(void)
274{
275 uint64_t v;
276
277 __asm__ volatile ("rdpr %%tl, %0\n" : "=r" (v));
278
279 return v;
280}
281
282/** Write Trap Base Address register.
283 *
284 * @param v New value of TBA.
285 */
286static inline void tba_write(uint64_t v)
287{
288 __asm__ volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
289}
290
291/** Load uint64_t from alternate space.
292 *
293 * @param asi ASI determining the alternate space.
294 * @param va Virtual address within the ASI.
295 *
296 * @return Value read from the virtual address in the specified address space.
297 */
298static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
299{
300 uint64_t v;
301
302 __asm__ volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" (asi));
303
304 return v;
305}
306
307/** Store uint64_t to alternate space.
308 *
309 * @param asi ASI determining the alternate space.
310 * @param va Virtual address within the ASI.
311 * @param v Value to be written.
312 */
313static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
314{
315 __asm__ volatile ("stxa %0, [%1] %2\n" : : "r" (v), "r" (va), "i" (asi) : "memory");
316}
317
318/** Flush all valid register windows to memory. */
319static inline void flushw(void)
320{
321 __asm__ volatile ("flushw\n");
322}
323
324extern void cpu_halt(void);
325extern void cpu_sleep(void);
326extern void asm_delay_loop(uint32_t t);
327
328extern uint64_t read_from_ag_g7(void);
329extern void write_to_ag_g6(uint64_t val);
330extern void write_to_ag_g7(uint64_t val);
331extern void write_to_ig_g6(uint64_t val);
332
333extern void switch_to_userspace(uint64_t pc, uint64_t sp);
334
335#endif
336
337/** @}
338 */
Note: See TracBrowser for help on using the repository browser.