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
RevLine 
[2a99fa8]1/*
[df4ed85]2 * Copyright (c) 2005 Jakub Jermar
[2a99fa8]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
[0ffa3ef5]29/** @addtogroup sparc64
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[0ffa3ef5]35#ifndef KERN_sparc64_ASM_H_
36#define KERN_sparc64_ASM_H_
[2a99fa8]37
[b3f8fb7]38#include <arch/arch.h>
[2a99fa8]39#include <arch/types.h>
[f4c2b6a]40#include <typedefs.h>
[b3f8fb7]41#include <align.h>
[75e1db0]42#include <arch/register.h>
[2a99fa8]43#include <config.h>
[b254b3b]44#include <arch/stack.h>
[ff3b7da7]45#include <arch/barrier.h>
[2a99fa8]46
[ff3b7da7]47static inline void outb(ioport_t port, uint8_t v)
[a2a5529]48{
[ff3b7da7]49 *((volatile uint8_t *)(port)) = v;
50 memory_barrier();
[a2a5529]51}
52
[ff3b7da7]53static inline void outw(ioport_t port, uint16_t v)
[a2a5529]54{
[ff3b7da7]55 *((volatile uint16_t *)(port)) = v;
56 memory_barrier();
[a2a5529]57}
58
[ff3b7da7]59static inline void outl(ioport_t port, uint32_t v)
[a2a5529]60{
[ff3b7da7]61 *((volatile uint32_t *)(port)) = v;
62 memory_barrier();
[a2a5529]63}
64
65static inline uint8_t inb(ioport_t port)
66{
[ff3b7da7]67 uint8_t rv;
68
69 rv = *((volatile uint8_t *)(port));
70 memory_barrier();
71
72 return rv;
[a2a5529]73}
74
75static inline uint16_t inw(ioport_t port)
76{
[ff3b7da7]77 uint16_t rv;
78
79 rv = *((volatile uint16_t *)(port));
80 memory_barrier();
81
82 return rv;
[a2a5529]83}
84
85static inline uint32_t inl(ioport_t port)
86{
[ff3b7da7]87 uint32_t rv;
[a2a5529]88
[ff3b7da7]89 rv = *((volatile uint32_t *)(port));
90 memory_barrier();
[a2a5529]91
[ff3b7da7]92 return rv;
93}
[a2a5529]94
[75e1db0]95/** Read Processor State register.
96 *
97 * @return Value of PSTATE register.
98 */
[7f1c620]99static inline uint64_t pstate_read(void)
[75e1db0]100{
[7f1c620]101 uint64_t v;
[75e1db0]102
[e7b7be3f]103 asm volatile ("rdpr %%pstate, %0\n" : "=r" (v));
[75e1db0]104
105 return v;
106}
107
108/** Write Processor State register.
109 *
[abbc16e]110 * @param v New value of PSTATE register.
[75e1db0]111 */
[7f1c620]112static inline void pstate_write(uint64_t v)
[75e1db0]113{
[e7b7be3f]114 asm volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
[75e1db0]115}
116
[096d11e5]117/** Read TICK_compare Register.
118 *
119 * @return Value of TICK_comapre register.
120 */
[7f1c620]121static inline uint64_t tick_compare_read(void)
[096d11e5]122{
[7f1c620]123 uint64_t v;
[096d11e5]124
[e7b7be3f]125 asm volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
[096d11e5]126
127 return v;
128}
129
130/** Write TICK_compare Register.
131 *
[abbc16e]132 * @param v New value of TICK_comapre register.
[096d11e5]133 */
[7f1c620]134static inline void tick_compare_write(uint64_t v)
[096d11e5]135{
[e7b7be3f]136 asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
[096d11e5]137}
138
139/** Read TICK Register.
140 *
141 * @return Value of TICK register.
142 */
[7f1c620]143static inline uint64_t tick_read(void)
[096d11e5]144{
[7f1c620]145 uint64_t v;
[096d11e5]146
[e7b7be3f]147 asm volatile ("rdpr %%tick, %0\n" : "=r" (v));
[096d11e5]148
149 return v;
150}
151
152/** Write TICK Register.
153 *
[abbc16e]154 * @param v New value of TICK register.
[096d11e5]155 */
[7f1c620]156static inline void tick_write(uint64_t v)
[096d11e5]157{
[e7b7be3f]158 asm volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
[096d11e5]159}
160
[6eabb6e6]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
[e7b7be3f]169 asm volatile ("rd %%fprs, %0\n" : "=r" (v));
[6eabb6e6]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{
[e7b7be3f]180 asm volatile ("wr %0, %1, %%fprs\n" : : "r" (v), "i" (0));
[6eabb6e6]181}
182
[39494010]183/** Read SOFTINT Register.
184 *
185 * @return Value of SOFTINT register.
186 */
[7f1c620]187static inline uint64_t softint_read(void)
[39494010]188{
[7f1c620]189 uint64_t v;
[39494010]190
[e7b7be3f]191 asm volatile ("rd %%softint, %0\n" : "=r" (v));
[39494010]192
193 return v;
194}
195
196/** Write SOFTINT Register.
197 *
[abbc16e]198 * @param v New value of SOFTINT register.
[39494010]199 */
[7f1c620]200static inline void softint_write(uint64_t v)
[39494010]201{
[e7b7be3f]202 asm volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
[39494010]203}
[75e1db0]204
[1120276]205/** Write CLEAR_SOFTINT Register.
206 *
207 * Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
208 *
[abbc16e]209 * @param v New value of CLEAR_SOFTINT register.
[1120276]210 */
[7f1c620]211static inline void clear_softint_write(uint64_t v)
[1120276]212{
[e7b7be3f]213 asm volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
[1120276]214}
215
[f9a56c0]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{
[e7b7be3f]224 asm volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
[f9a56c0]225}
226
[2a99fa8]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) {
[75e1db0]235 pstate_reg_t pstate;
[7f1c620]236 uint64_t value;
[75e1db0]237
238 value = pstate_read();
239 pstate.value = value;
240 pstate.ie = true;
241 pstate_write(pstate.value);
242
243 return (ipl_t) value;
[2a99fa8]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) {
[75e1db0]254 pstate_reg_t pstate;
[7f1c620]255 uint64_t value;
[75e1db0]256
257 value = pstate_read();
258 pstate.value = value;
259 pstate.ie = false;
260 pstate_write(pstate.value);
261
262 return (ipl_t) value;
[2a99fa8]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) {
[75e1db0]272 pstate_reg_t pstate;
273
274 pstate.value = pstate_read();
275 pstate.ie = ((pstate_reg_t) ipl).ie;
276 pstate_write(pstate.value);
[2a99fa8]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) {
[75e1db0]286 return (ipl_t) pstate_read();
[2a99fa8]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 */
[7f1c620]295static inline uintptr_t get_stack_base(void)
[2a99fa8]296{
[b254b3b]297 uintptr_t unbiased_sp;
[437ee6a4]298
[e7b7be3f]299 asm volatile ("add %%sp, %1, %0\n" : "=r" (unbiased_sp) : "i" (STACK_BIAS));
[437ee6a4]300
[b254b3b]301 return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
[2a99fa8]302}
303
[2cf87e50]304/** Read Version Register.
305 *
306 * @return Value of VER register.
307 */
[7f1c620]308static inline uint64_t ver_read(void)
[2cf87e50]309{
[7f1c620]310 uint64_t v;
[2cf87e50]311
[e7b7be3f]312 asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
[2cf87e50]313
314 return v;
315}
316
[d78d603]317/** Read Trap Program Counter register.
[8ac5fe7]318 *
[d78d603]319 * @return Current value in TPC.
[8ac5fe7]320 */
[d78d603]321static inline uint64_t tpc_read(void)
[8ac5fe7]322{
[7f1c620]323 uint64_t v;
[8ac5fe7]324
[e7b7be3f]325 asm volatile ("rdpr %%tpc, %0\n" : "=r" (v));
[8ac5fe7]326
327 return v;
328}
329
[d78d603]330/** Read Trap Level register.
[b6fba84]331 *
[d78d603]332 * @return Current value in TL.
[b6fba84]333 */
[d78d603]334static inline uint64_t tl_read(void)
[b6fba84]335{
[7f1c620]336 uint64_t v;
[b6fba84]337
[e7b7be3f]338 asm volatile ("rdpr %%tl, %0\n" : "=r" (v));
[b6fba84]339
340 return v;
341}
342
[d78d603]343/** Read Trap Base Address register.
[7cb53f62]344 *
[d78d603]345 * @return Current value in TBA.
[7cb53f62]346 */
[d78d603]347static inline uint64_t tba_read(void)
[7cb53f62]348{
[7f1c620]349 uint64_t v;
[7cb53f62]350
[e7b7be3f]351 asm volatile ("rdpr %%tba, %0\n" : "=r" (v));
[7cb53f62]352
353 return v;
354}
[b6fba84]355
[8ac5fe7]356/** Write Trap Base Address register.
357 *
[abbc16e]358 * @param v New value of TBA.
[8ac5fe7]359 */
[7f1c620]360static inline void tba_write(uint64_t v)
[8ac5fe7]361{
[e7b7be3f]362 asm volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
[8ac5fe7]363}
364
[7f1c620]365/** Load uint64_t from alternate space.
[b00fdde]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 */
[7f1c620]372static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
[b00fdde]373{
[7f1c620]374 uint64_t v;
[b00fdde]375
[e7b7be3f]376 asm volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" ((unsigned) asi));
[b00fdde]377
378 return v;
379}
380
[7f1c620]381/** Store uint64_t to alternate space.
[b00fdde]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 */
[7f1c620]387static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
[b00fdde]388{
[e7b7be3f]389 asm volatile ("stxa %0, [%1] %2\n" : : "r" (v), "r" (va), "i" ((unsigned) asi) : "memory");
[b00fdde]390}
391
[0fa6044]392/** Flush all valid register windows to memory. */
393static inline void flushw(void)
394{
[e7b7be3f]395 asm volatile ("flushw\n");
[0fa6044]396}
397
[fd85ae5]398/** Switch to nucleus by setting TL to 1. */
399static inline void nucleus_enter(void)
400{
[e7b7be3f]401 asm volatile ("wrpr %g0, 1, %tl\n");
[fd85ae5]402}
403
404/** Switch from nucleus by setting TL to 0. */
405static inline void nucleus_leave(void)
406{
[e7b7be3f]407 asm volatile ("wrpr %g0, %g0, %tl\n");
[fd85ae5]408}
409
[45b26dad]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
[e11ae91]419extern void cpu_halt(void);
420extern void cpu_sleep(void);
[9a5b556]421extern void asm_delay_loop(const uint32_t usec);
[e11ae91]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);
[2a99fa8]427
[cfa70add]428extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg);
[ed166f7]429
[2a99fa8]430#endif
[b45c443]431
[0ffa3ef5]432/** @}
[b45c443]433 */
Note: See TracBrowser for help on using the repository browser.