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

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

Accesses to memory mapped registers should use volatile pointers so that
the compiler doesn't even think of trying to be clever. Add memory barriers
and fixed cstyle.

  • Property mode set to 100644
File size: 8.9 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 <arch/arch.h>
39#include <arch/types.h>
40#include <typedefs.h>
41#include <align.h>
42#include <arch/register.h>
43#include <config.h>
44#include <arch/stack.h>
45#include <arch/barrier.h>
46
47static inline void outb(ioport_t port, uint8_t v)
48{
49 *((volatile uint8_t *)(port)) = v;
50 memory_barrier();
51}
52
53static inline void outw(ioport_t port, uint16_t v)
54{
55 *((volatile uint16_t *)(port)) = v;
56 memory_barrier();
57}
58
59static inline void outl(ioport_t port, uint32_t v)
60{
61 *((volatile uint32_t *)(port)) = v;
62 memory_barrier();
63}
64
65static inline uint8_t inb(ioport_t port)
66{
67 uint8_t rv;
68
69 rv = *((volatile uint8_t *)(port));
70 memory_barrier();
71
72 return rv;
73}
74
75static inline uint16_t inw(ioport_t port)
76{
77 uint16_t rv;
78
79 rv = *((volatile uint16_t *)(port));
80 memory_barrier();
81
82 return rv;
83}
84
85static inline uint32_t inl(ioport_t port)
86{
87 uint32_t rv;
88
89 rv = *((volatile uint32_t *)(port));
90 memory_barrier();
91
92 return rv;
93}
94
95/** Read Processor State register.
96 *
97 * @return Value of PSTATE register.
98 */
99static inline uint64_t pstate_read(void)
100{
101 uint64_t v;
102
103 asm volatile ("rdpr %%pstate, %0\n" : "=r" (v));
104
105 return v;
106}
107
108/** Write Processor State register.
109 *
110 * @param v New value of PSTATE register.
111 */
112static inline void pstate_write(uint64_t v)
113{
114 asm volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
115}
116
117/** Read TICK_compare Register.
118 *
119 * @return Value of TICK_comapre register.
120 */
121static inline uint64_t tick_compare_read(void)
122{
123 uint64_t v;
124
125 asm volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
126
127 return v;
128}
129
130/** Write TICK_compare Register.
131 *
132 * @param v New value of TICK_comapre register.
133 */
134static inline void tick_compare_write(uint64_t v)
135{
136 asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
137}
138
139/** Read TICK Register.
140 *
141 * @return Value of TICK register.
142 */
143static inline uint64_t tick_read(void)
144{
145 uint64_t v;
146
147 asm volatile ("rdpr %%tick, %0\n" : "=r" (v));
148
149 return v;
150}
151
152/** Write TICK Register.
153 *
154 * @param v New value of TICK register.
155 */
156static inline void tick_write(uint64_t v)
157{
158 asm volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
159}
160
161/** Read FPRS Register.
162 *
163 * @return Value of FPRS register.
164 */
165static inline uint64_t fprs_read(void)
166{
167 uint64_t v;
168
169 asm volatile ("rd %%fprs, %0\n" : "=r" (v));
170
171 return v;
172}
173
174/** Write FPRS Register.
175 *
176 * @param v New value of FPRS register.
177 */
178static inline void fprs_write(uint64_t v)
179{
180 asm volatile ("wr %0, %1, %%fprs\n" : : "r" (v), "i" (0));
181}
182
183/** Read SOFTINT Register.
184 *
185 * @return Value of SOFTINT register.
186 */
187static inline uint64_t softint_read(void)
188{
189 uint64_t v;
190
191 asm volatile ("rd %%softint, %0\n" : "=r" (v));
192
193 return v;
194}
195
196/** Write SOFTINT Register.
197 *
198 * @param v New value of SOFTINT register.
199 */
200static inline void softint_write(uint64_t v)
201{
202 asm volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
203}
204
205/** Write CLEAR_SOFTINT Register.
206 *
207 * Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
208 *
209 * @param v New value of CLEAR_SOFTINT register.
210 */
211static inline void clear_softint_write(uint64_t v)
212{
213 asm volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
214}
215
216/** Write SET_SOFTINT Register.
217 *
218 * Bits set in SET_SOFTINT register will be set in SOFTINT register.
219 *
220 * @param v New value of SET_SOFTINT register.
221 */
222static inline void set_softint_write(uint64_t v)
223{
224 asm volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
225}
226
227/** Enable interrupts.
228 *
229 * Enable interrupts and return previous
230 * value of IPL.
231 *
232 * @return Old interrupt priority level.
233 */
234static inline ipl_t interrupts_enable(void) {
235 pstate_reg_t pstate;
236 uint64_t value;
237
238 value = pstate_read();
239 pstate.value = value;
240 pstate.ie = true;
241 pstate_write(pstate.value);
242
243 return (ipl_t) value;
244}
245
246/** Disable interrupts.
247 *
248 * Disable interrupts and return previous
249 * value of IPL.
250 *
251 * @return Old interrupt priority level.
252 */
253static inline ipl_t interrupts_disable(void) {
254 pstate_reg_t pstate;
255 uint64_t value;
256
257 value = pstate_read();
258 pstate.value = value;
259 pstate.ie = false;
260 pstate_write(pstate.value);
261
262 return (ipl_t) value;
263}
264
265/** Restore interrupt priority level.
266 *
267 * Restore IPL.
268 *
269 * @param ipl Saved interrupt priority level.
270 */
271static inline void interrupts_restore(ipl_t ipl) {
272 pstate_reg_t pstate;
273
274 pstate.value = pstate_read();
275 pstate.ie = ((pstate_reg_t) ipl).ie;
276 pstate_write(pstate.value);
277}
278
279/** Return interrupt priority level.
280 *
281 * Return IPL.
282 *
283 * @return Current interrupt priority level.
284 */
285static inline ipl_t interrupts_read(void) {
286 return (ipl_t) pstate_read();
287}
288
289/** Return base address of current stack.
290 *
291 * Return the base address of the current stack.
292 * The stack is assumed to be STACK_SIZE bytes long.
293 * The stack must start on page boundary.
294 */
295static inline uintptr_t get_stack_base(void)
296{
297 uintptr_t unbiased_sp;
298
299 asm volatile ("add %%sp, %1, %0\n" : "=r" (unbiased_sp) : "i" (STACK_BIAS));
300
301 return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
302}
303
304/** Read Version Register.
305 *
306 * @return Value of VER register.
307 */
308static inline uint64_t ver_read(void)
309{
310 uint64_t v;
311
312 asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
313
314 return v;
315}
316
317/** Read Trap Program Counter register.
318 *
319 * @return Current value in TPC.
320 */
321static inline uint64_t tpc_read(void)
322{
323 uint64_t v;
324
325 asm volatile ("rdpr %%tpc, %0\n" : "=r" (v));
326
327 return v;
328}
329
330/** Read Trap Level register.
331 *
332 * @return Current value in TL.
333 */
334static inline uint64_t tl_read(void)
335{
336 uint64_t v;
337
338 asm volatile ("rdpr %%tl, %0\n" : "=r" (v));
339
340 return v;
341}
342
343/** Read Trap Base Address register.
344 *
345 * @return Current value in TBA.
346 */
347static inline uint64_t tba_read(void)
348{
349 uint64_t v;
350
351 asm volatile ("rdpr %%tba, %0\n" : "=r" (v));
352
353 return v;
354}
355
356/** Write Trap Base Address register.
357 *
358 * @param v New value of TBA.
359 */
360static inline void tba_write(uint64_t v)
361{
362 asm volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
363}
364
365/** Load uint64_t from alternate space.
366 *
367 * @param asi ASI determining the alternate space.
368 * @param va Virtual address within the ASI.
369 *
370 * @return Value read from the virtual address in the specified address space.
371 */
372static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
373{
374 uint64_t v;
375
376 asm volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" ((unsigned) asi));
377
378 return v;
379}
380
381/** Store uint64_t to alternate space.
382 *
383 * @param asi ASI determining the alternate space.
384 * @param va Virtual address within the ASI.
385 * @param v Value to be written.
386 */
387static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
388{
389 asm volatile ("stxa %0, [%1] %2\n" : : "r" (v), "r" (va), "i" ((unsigned) asi) : "memory");
390}
391
392/** Flush all valid register windows to memory. */
393static inline void flushw(void)
394{
395 asm volatile ("flushw\n");
396}
397
398/** Switch to nucleus by setting TL to 1. */
399static inline void nucleus_enter(void)
400{
401 asm volatile ("wrpr %g0, 1, %tl\n");
402}
403
404/** Switch from nucleus by setting TL to 0. */
405static inline void nucleus_leave(void)
406{
407 asm volatile ("wrpr %g0, %g0, %tl\n");
408}
409
410/** Read UPA_CONFIG register.
411 *
412 * @return Value of the UPA_CONFIG register.
413 */
414static inline uint64_t upa_config_read(void)
415{
416 return asi_u64_read(ASI_UPA_CONFIG, 0);
417}
418
419extern void cpu_halt(void);
420extern void cpu_sleep(void);
421extern void asm_delay_loop(const uint32_t usec);
422
423extern uint64_t read_from_ag_g7(void);
424extern void write_to_ag_g6(uint64_t val);
425extern void write_to_ag_g7(uint64_t val);
426extern void write_to_ig_g6(uint64_t val);
427
428extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg);
429
430#endif
431
432/** @}
433 */
Note: See TracBrowser for help on using the repository browser.