~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to kernel/arch/sparc64/include/asm.h

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
47
static inline void pio_write_8(ioport8_t *port, uint8_t v)
 
48
{
 
49
        *port = v;
 
50
        memory_barrier();
 
51
}
 
52
 
 
53
static inline void pio_write_16(ioport16_t *port, uint16_t v)
 
54
{
 
55
        *port = v;
 
56
        memory_barrier();
 
57
}
 
58
 
 
59
static inline void pio_write_32(ioport32_t *port, uint32_t v)
 
60
{
 
61
        *port = v;
 
62
        memory_barrier();
 
63
}
 
64
 
 
65
static 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
 
 
75
static 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
 
 
85
static 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
 */
 
99
static 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
 */
 
112
static 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
 */
 
121
static 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
 */
 
134
static 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
 */
 
143
static 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
 */
 
156
static 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
 */
 
165
static 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
 */
 
178
static 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
 */
 
187
static 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
 */
 
200
static 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
 */
 
209
static 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
 */
 
222
static 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
 */
 
233
static 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
 */
 
244
static 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
 */
 
256
static 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
 */
 
275
static 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
 */
 
293
static 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
 */
 
307
static 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
 */
 
317
static 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
 */
 
330
static 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
 */
 
343
static 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
 */
 
356
static 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
 */
 
369
static 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
 */
 
382
static 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
 */
 
394
static 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
 */
 
409
static 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. */
 
415
static inline void flushw(void)
 
416
{
 
417
        asm volatile ("flushw\n");
 
418
}
 
419
 
 
420
/** Switch to nucleus by setting TL to 1. */
 
421
static 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. */
 
427
static inline void nucleus_leave(void)
 
428
{
 
429
        asm volatile ("wrpr %g0, %g0, %tl\n");
 
430
}
 
431
 
 
432
extern void cpu_halt(void);
 
433
extern void cpu_sleep(void);
 
434
extern void asm_delay_loop(const uint32_t usec);
 
435
 
 
436
extern uint64_t read_from_ag_g7(void);
 
437
extern void write_to_ag_g6(uint64_t val);
 
438
extern void write_to_ag_g7(uint64_t val);
 
439
extern void write_to_ig_g6(uint64_t val);
 
440
 
 
441
extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg);
 
442
 
 
443
#endif
 
444
 
 
445
/** @}
 
446
 */