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

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

Introduce ioport8_t, ioport16_t and ioport32_t. These types are to be used with
pio_read_n() and pio_write_n() functions. This breaks everything.

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