2
* Copyright (c) 2005 Jakub Jermar
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
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.
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.
29
/** @addtogroup sparc64
35
#ifndef KERN_sparc64_ASM_H_
36
#define KERN_sparc64_ASM_H_
38
#include <arch/arch.h>
39
#include <arch/types.h>
42
#include <arch/register.h>
44
#include <arch/stack.h>
45
#include <arch/barrier.h>
47
static inline void pio_write_8(ioport8_t *port, uint8_t v)
53
static inline void pio_write_16(ioport16_t *port, uint16_t v)
59
static inline void pio_write_32(ioport32_t *port, uint32_t v)
65
static inline uint8_t pio_read_8(ioport8_t *port)
75
static inline uint16_t pio_read_16(ioport16_t *port)
85
static inline uint32_t pio_read_32(ioport32_t *port)
95
/** Read Processor State register.
97
* @return Value of PSTATE register.
99
static inline uint64_t pstate_read(void)
103
asm volatile ("rdpr %%pstate, %0\n" : "=r" (v));
108
/** Write Processor State register.
110
* @param v New value of PSTATE register.
112
static inline void pstate_write(uint64_t v)
114
asm volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
117
/** Read TICK_compare Register.
119
* @return Value of TICK_comapre register.
121
static inline uint64_t tick_compare_read(void)
125
asm volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
130
/** Write TICK_compare Register.
132
* @param v New value of TICK_comapre register.
134
static inline void tick_compare_write(uint64_t v)
136
asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
139
/** Read STICK_compare Register.
141
* @return Value of STICK_compare register.
143
static inline uint64_t stick_compare_read(void)
147
asm volatile ("rd %%asr25, %0\n" : "=r" (v));
152
/** Write STICK_compare Register.
154
* @param v New value of STICK_comapre register.
156
static inline void stick_compare_write(uint64_t v)
158
asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0));
161
/** Read TICK Register.
163
* @return Value of TICK register.
165
static inline uint64_t tick_read(void)
169
asm volatile ("rdpr %%tick, %0\n" : "=r" (v));
174
/** Write TICK Register.
176
* @param v New value of TICK register.
178
static inline void tick_write(uint64_t v)
180
asm volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
183
/** Read FPRS Register.
185
* @return Value of FPRS register.
187
static inline uint64_t fprs_read(void)
191
asm volatile ("rd %%fprs, %0\n" : "=r" (v));
196
/** Write FPRS Register.
198
* @param v New value of FPRS register.
200
static inline void fprs_write(uint64_t v)
202
asm volatile ("wr %0, %1, %%fprs\n" : : "r" (v), "i" (0));
205
/** Read SOFTINT Register.
207
* @return Value of SOFTINT register.
209
static inline uint64_t softint_read(void)
213
asm volatile ("rd %%softint, %0\n" : "=r" (v));
218
/** Write SOFTINT Register.
220
* @param v New value of SOFTINT register.
222
static inline void softint_write(uint64_t v)
224
asm volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
227
/** Write CLEAR_SOFTINT Register.
229
* Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
231
* @param v New value of CLEAR_SOFTINT register.
233
static inline void clear_softint_write(uint64_t v)
235
asm volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
238
/** Write SET_SOFTINT Register.
240
* Bits set in SET_SOFTINT register will be set in SOFTINT register.
242
* @param v New value of SET_SOFTINT register.
244
static inline void set_softint_write(uint64_t v)
246
asm volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
249
/** Enable interrupts.
251
* Enable interrupts and return previous
254
* @return Old interrupt priority level.
256
static inline ipl_t interrupts_enable(void) {
260
value = pstate_read();
261
pstate.value = value;
263
pstate_write(pstate.value);
265
return (ipl_t) value;
268
/** Disable interrupts.
270
* Disable interrupts and return previous
273
* @return Old interrupt priority level.
275
static inline ipl_t interrupts_disable(void) {
279
value = pstate_read();
280
pstate.value = value;
282
pstate_write(pstate.value);
284
return (ipl_t) value;
287
/** Restore interrupt priority level.
291
* @param ipl Saved interrupt priority level.
293
static inline void interrupts_restore(ipl_t ipl) {
296
pstate.value = pstate_read();
297
pstate.ie = ((pstate_reg_t) ipl).ie;
298
pstate_write(pstate.value);
301
/** Return interrupt priority level.
305
* @return Current interrupt priority level.
307
static inline ipl_t interrupts_read(void) {
308
return (ipl_t) pstate_read();
311
/** Return base address of current stack.
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.
317
static inline uintptr_t get_stack_base(void)
319
uintptr_t unbiased_sp;
321
asm volatile ("add %%sp, %1, %0\n" : "=r" (unbiased_sp) : "i" (STACK_BIAS));
323
return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
326
/** Read Version Register.
328
* @return Value of VER register.
330
static inline uint64_t ver_read(void)
334
asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
339
/** Read Trap Program Counter register.
341
* @return Current value in TPC.
343
static inline uint64_t tpc_read(void)
347
asm volatile ("rdpr %%tpc, %0\n" : "=r" (v));
352
/** Read Trap Level register.
354
* @return Current value in TL.
356
static inline uint64_t tl_read(void)
360
asm volatile ("rdpr %%tl, %0\n" : "=r" (v));
365
/** Read Trap Base Address register.
367
* @return Current value in TBA.
369
static inline uint64_t tba_read(void)
373
asm volatile ("rdpr %%tba, %0\n" : "=r" (v));
378
/** Write Trap Base Address register.
380
* @param v New value of TBA.
382
static inline void tba_write(uint64_t v)
384
asm volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
387
/** Load uint64_t from alternate space.
389
* @param asi ASI determining the alternate space.
390
* @param va Virtual address within the ASI.
392
* @return Value read from the virtual address in the specified address space.
394
static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
398
asm volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" ((unsigned) asi));
403
/** Store uint64_t to alternate space.
405
* @param asi ASI determining the alternate space.
406
* @param va Virtual address within the ASI.
407
* @param v Value to be written.
409
static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
411
asm volatile ("stxa %0, [%1] %2\n" : : "r" (v), "r" (va), "i" ((unsigned) asi) : "memory");
414
/** Flush all valid register windows to memory. */
415
static inline void flushw(void)
417
asm volatile ("flushw\n");
420
/** Switch to nucleus by setting TL to 1. */
421
static inline void nucleus_enter(void)
423
asm volatile ("wrpr %g0, 1, %tl\n");
426
/** Switch from nucleus by setting TL to 0. */
427
static inline void nucleus_leave(void)
429
asm volatile ("wrpr %g0, %g0, %tl\n");
432
extern void cpu_halt(void);
433
extern void cpu_sleep(void);
434
extern void asm_delay_loop(const uint32_t usec);
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);
441
extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg);