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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3412e844 was 7a0359b, checked in by Martin Decky <martin@…>, 15 years ago

improve kernel function tracing

  • add support for more generic kernel sources
  • replace attribute((no_instrument_function)) with NO_TRACE macro (shorter and for future compatibility with different compilers)
  • to be on the safe side, do not instrument most of the inline and static functions (plus some specific non-static functions)

collateral code cleanup (no change in functionality)

  • Property mode set to 100644
File size: 10.2 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
[7a0359b]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>
[f4c2b6a]39#include <typedefs.h>
[b3f8fb7]40#include <align.h>
[75e1db0]41#include <arch/register.h>
[2a99fa8]42#include <config.h>
[b254b3b]43#include <arch/stack.h>
[ff3b7da7]44#include <arch/barrier.h>
[7a0359b]45#include <trace.h>
[2a99fa8]46
[7a0359b]47NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
[a2a5529]48{
[7d60cf5]49 *port = v;
[ff3b7da7]50 memory_barrier();
[a2a5529]51}
52
[7a0359b]53NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
[a2a5529]54{
[7d60cf5]55 *port = v;
[ff3b7da7]56 memory_barrier();
[a2a5529]57}
58
[7a0359b]59NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
[a2a5529]60{
[7d60cf5]61 *port = v;
[ff3b7da7]62 memory_barrier();
[a2a5529]63}
64
[7a0359b]65NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
[a2a5529]66{
[7a0359b]67 uint8_t rv = *port;
[ff3b7da7]68 memory_barrier();
69 return rv;
[a2a5529]70}
71
[7a0359b]72NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
[a2a5529]73{
[7a0359b]74 uint16_t rv = *port;
[ff3b7da7]75 memory_barrier();
76 return rv;
[a2a5529]77}
78
[7a0359b]79NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
[a2a5529]80{
[7a0359b]81 uint32_t rv = *port;
[ff3b7da7]82 memory_barrier();
83 return rv;
84}
[a2a5529]85
[75e1db0]86/** Read Processor State register.
87 *
88 * @return Value of PSTATE register.
[7a0359b]89 *
[75e1db0]90 */
[7a0359b]91NO_TRACE static inline uint64_t pstate_read(void)
[75e1db0]92{
[7f1c620]93 uint64_t v;
[75e1db0]94
[7a0359b]95 asm volatile (
96 "rdpr %%pstate, %[v]\n"
97 : [v] "=r" (v)
98 );
[75e1db0]99
100 return v;
101}
102
103/** Write Processor State register.
104 *
[abbc16e]105 * @param v New value of PSTATE register.
[7a0359b]106 *
[75e1db0]107 */
[7a0359b]108NO_TRACE static inline void pstate_write(uint64_t v)
[75e1db0]109{
[7a0359b]110 asm volatile (
111 "wrpr %[v], %[zero], %%pstate\n"
112 :: [v] "r" (v),
113 [zero] "i" (0)
114 );
[75e1db0]115}
116
[096d11e5]117/** Read TICK_compare Register.
118 *
119 * @return Value of TICK_comapre register.
[7a0359b]120 *
[096d11e5]121 */
[7a0359b]122NO_TRACE static inline uint64_t tick_compare_read(void)
[096d11e5]123{
[7f1c620]124 uint64_t v;
[096d11e5]125
[7a0359b]126 asm volatile (
127 "rd %%tick_cmpr, %[v]\n"
128 : [v] "=r" (v)
129 );
[096d11e5]130
131 return v;
132}
133
134/** Write TICK_compare Register.
135 *
[abbc16e]136 * @param v New value of TICK_comapre register.
[7a0359b]137 *
[096d11e5]138 */
[7a0359b]139NO_TRACE static inline void tick_compare_write(uint64_t v)
[096d11e5]140{
[7a0359b]141 asm volatile (
142 "wr %[v], %[zero], %%tick_cmpr\n"
143 :: [v] "r" (v),
144 [zero] "i" (0)
145 );
[096d11e5]146}
147
[965dc18]148/** Read STICK_compare Register.
149 *
150 * @return Value of STICK_compare register.
[7a0359b]151 *
[965dc18]152 */
[7a0359b]153NO_TRACE static inline uint64_t stick_compare_read(void)
[965dc18]154{
155 uint64_t v;
156
[7a0359b]157 asm volatile (
158 "rd %%asr25, %[v]\n"
159 : [v] "=r" (v)
160 );
[965dc18]161
162 return v;
163}
164
165/** Write STICK_compare Register.
166 *
167 * @param v New value of STICK_comapre register.
[7a0359b]168 *
[965dc18]169 */
[7a0359b]170NO_TRACE static inline void stick_compare_write(uint64_t v)
[965dc18]171{
[7a0359b]172 asm volatile (
173 "wr %[v], %[zero], %%asr25\n"
174 :: [v] "r" (v),
175 [zero] "i" (0)
176 );
[965dc18]177}
178
[096d11e5]179/** Read TICK Register.
180 *
181 * @return Value of TICK register.
[7a0359b]182 *
[096d11e5]183 */
[7a0359b]184NO_TRACE static inline uint64_t tick_read(void)
[096d11e5]185{
[7f1c620]186 uint64_t v;
[096d11e5]187
[7a0359b]188 asm volatile (
189 "rdpr %%tick, %[v]\n"
190 : [v] "=r" (v)
191 );
[096d11e5]192
193 return v;
194}
195
196/** Write TICK Register.
197 *
[abbc16e]198 * @param v New value of TICK register.
[7a0359b]199 *
[096d11e5]200 */
[7a0359b]201NO_TRACE static inline void tick_write(uint64_t v)
[096d11e5]202{
[7a0359b]203 asm volatile (
204 "wrpr %[v], %[zero], %%tick\n"
205 :: [v] "r" (v),
206 [zero] "i" (0)
207 );
[096d11e5]208}
209
[6eabb6e6]210/** Read FPRS Register.
211 *
212 * @return Value of FPRS register.
[7a0359b]213 *
[6eabb6e6]214 */
[7a0359b]215NO_TRACE static inline uint64_t fprs_read(void)
[6eabb6e6]216{
217 uint64_t v;
218
[7a0359b]219 asm volatile (
220 "rd %%fprs, %[v]\n"
221 : [v] "=r" (v)
222 );
[6eabb6e6]223
224 return v;
225}
226
227/** Write FPRS Register.
228 *
229 * @param v New value of FPRS register.
[7a0359b]230 *
[6eabb6e6]231 */
[7a0359b]232NO_TRACE static inline void fprs_write(uint64_t v)
[6eabb6e6]233{
[7a0359b]234 asm volatile (
235 "wr %[v], %[zero], %%fprs\n"
236 :: [v] "r" (v),
237 [zero] "i" (0)
238 );
[6eabb6e6]239}
240
[39494010]241/** Read SOFTINT Register.
242 *
243 * @return Value of SOFTINT register.
[7a0359b]244 *
[39494010]245 */
[7a0359b]246NO_TRACE static inline uint64_t softint_read(void)
[39494010]247{
[7f1c620]248 uint64_t v;
[7a0359b]249
250 asm volatile (
251 "rd %%softint, %[v]\n"
252 : [v] "=r" (v)
253 );
254
[39494010]255 return v;
256}
257
258/** Write SOFTINT Register.
259 *
[abbc16e]260 * @param v New value of SOFTINT register.
[7a0359b]261 *
[39494010]262 */
[7a0359b]263NO_TRACE static inline void softint_write(uint64_t v)
[39494010]264{
[7a0359b]265 asm volatile (
266 "wr %[v], %[zero], %%softint\n"
267 :: [v] "r" (v),
268 [zero] "i" (0)
269 );
[39494010]270}
[75e1db0]271
[1120276]272/** Write CLEAR_SOFTINT Register.
273 *
274 * Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
275 *
[abbc16e]276 * @param v New value of CLEAR_SOFTINT register.
[7a0359b]277 *
[1120276]278 */
[7a0359b]279NO_TRACE static inline void clear_softint_write(uint64_t v)
[1120276]280{
[7a0359b]281 asm volatile (
282 "wr %[v], %[zero], %%clear_softint\n"
283 :: [v] "r" (v),
284 [zero] "i" (0)
285 );
[1120276]286}
287
[f9a56c0]288/** Write SET_SOFTINT Register.
289 *
290 * Bits set in SET_SOFTINT register will be set in SOFTINT register.
291 *
292 * @param v New value of SET_SOFTINT register.
[7a0359b]293 *
[f9a56c0]294 */
[7a0359b]295NO_TRACE static inline void set_softint_write(uint64_t v)
[f9a56c0]296{
[7a0359b]297 asm volatile (
298 "wr %[v], %[zero], %%set_softint\n"
299 :: [v] "r" (v),
300 [zero] "i" (0)
301 );
[f9a56c0]302}
303
[2a99fa8]304/** Enable interrupts.
305 *
306 * Enable interrupts and return previous
307 * value of IPL.
308 *
309 * @return Old interrupt priority level.
[7a0359b]310 *
[2a99fa8]311 */
[7a0359b]312NO_TRACE static inline ipl_t interrupts_enable(void) {
[75e1db0]313 pstate_reg_t pstate;
[7a0359b]314 uint64_t value = pstate_read();
[75e1db0]315
316 pstate.value = value;
317 pstate.ie = true;
318 pstate_write(pstate.value);
319
320 return (ipl_t) value;
[2a99fa8]321}
322
323/** Disable interrupts.
324 *
325 * Disable interrupts and return previous
326 * value of IPL.
327 *
328 * @return Old interrupt priority level.
[7a0359b]329 *
[2a99fa8]330 */
[7a0359b]331NO_TRACE static inline ipl_t interrupts_disable(void) {
[75e1db0]332 pstate_reg_t pstate;
[7a0359b]333 uint64_t value = pstate_read();
[75e1db0]334
335 pstate.value = value;
336 pstate.ie = false;
337 pstate_write(pstate.value);
338
339 return (ipl_t) value;
[2a99fa8]340}
341
342/** Restore interrupt priority level.
343 *
344 * Restore IPL.
345 *
346 * @param ipl Saved interrupt priority level.
[7a0359b]347 *
[2a99fa8]348 */
[7a0359b]349NO_TRACE static inline void interrupts_restore(ipl_t ipl) {
[75e1db0]350 pstate_reg_t pstate;
351
352 pstate.value = pstate_read();
353 pstate.ie = ((pstate_reg_t) ipl).ie;
354 pstate_write(pstate.value);
[2a99fa8]355}
356
357/** Return interrupt priority level.
358 *
359 * Return IPL.
360 *
361 * @return Current interrupt priority level.
[7a0359b]362 *
[2a99fa8]363 */
[7a0359b]364NO_TRACE static inline ipl_t interrupts_read(void) {
[75e1db0]365 return (ipl_t) pstate_read();
[2a99fa8]366}
367
[bcdc185]368/** Check interrupts state.
369 *
370 * @return True if interrupts are disabled.
371 *
372 */
[7a0359b]373NO_TRACE static inline bool interrupts_disabled(void)
[bcdc185]374{
375 pstate_reg_t pstate;
[7a0359b]376
[bcdc185]377 pstate.value = pstate_read();
378 return !pstate.ie;
379}
380
[2a99fa8]381/** Return base address of current stack.
382 *
383 * Return the base address of the current stack.
384 * The stack is assumed to be STACK_SIZE bytes long.
385 * The stack must start on page boundary.
[7a0359b]386 *
[2a99fa8]387 */
[7a0359b]388NO_TRACE static inline uintptr_t get_stack_base(void)
[2a99fa8]389{
[b254b3b]390 uintptr_t unbiased_sp;
[437ee6a4]391
[7a0359b]392 asm volatile (
393 "add %%sp, %[stack_bias], %[unbiased_sp]\n"
394 : [unbiased_sp] "=r" (unbiased_sp)
395 : [stack_bias] "i" (STACK_BIAS)
396 );
[437ee6a4]397
[b254b3b]398 return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
[2a99fa8]399}
400
[2cf87e50]401/** Read Version Register.
402 *
403 * @return Value of VER register.
[7a0359b]404 *
[2cf87e50]405 */
[7a0359b]406NO_TRACE static inline uint64_t ver_read(void)
[2cf87e50]407{
[7f1c620]408 uint64_t v;
[2cf87e50]409
[7a0359b]410 asm volatile (
411 "rdpr %%ver, %[v]\n"
412 : [v] "=r" (v)
413 );
[2cf87e50]414
415 return v;
416}
417
[d78d603]418/** Read Trap Program Counter register.
[8ac5fe7]419 *
[d78d603]420 * @return Current value in TPC.
[7a0359b]421 *
[8ac5fe7]422 */
[7a0359b]423NO_TRACE static inline uint64_t tpc_read(void)
[8ac5fe7]424{
[7f1c620]425 uint64_t v;
[8ac5fe7]426
[7a0359b]427 asm volatile (
428 "rdpr %%tpc, %[v]\n"
429 : [v] "=r" (v)
430 );
[8ac5fe7]431
432 return v;
433}
434
[d78d603]435/** Read Trap Level register.
[b6fba84]436 *
[d78d603]437 * @return Current value in TL.
[7a0359b]438 *
[b6fba84]439 */
[7a0359b]440NO_TRACE static inline uint64_t tl_read(void)
[b6fba84]441{
[7f1c620]442 uint64_t v;
[b6fba84]443
[7a0359b]444 asm volatile (
445 "rdpr %%tl, %[v]\n"
446 : [v] "=r" (v)
447 );
[b6fba84]448
449 return v;
450}
451
[d78d603]452/** Read Trap Base Address register.
[7cb53f62]453 *
[d78d603]454 * @return Current value in TBA.
[7a0359b]455 *
[7cb53f62]456 */
[7a0359b]457NO_TRACE static inline uint64_t tba_read(void)
[7cb53f62]458{
[7f1c620]459 uint64_t v;
[7cb53f62]460
[7a0359b]461 asm volatile (
462 "rdpr %%tba, %[v]\n"
463 : [v] "=r" (v)
464 );
[7cb53f62]465
466 return v;
467}
[b6fba84]468
[8ac5fe7]469/** Write Trap Base Address register.
470 *
[abbc16e]471 * @param v New value of TBA.
[7a0359b]472 *
[8ac5fe7]473 */
[7a0359b]474NO_TRACE static inline void tba_write(uint64_t v)
[8ac5fe7]475{
[7a0359b]476 asm volatile (
477 "wrpr %[v], %[zero], %%tba\n"
478 :: [v] "r" (v),
479 [zero] "i" (0)
480 );
[8ac5fe7]481}
482
[7f1c620]483/** Load uint64_t from alternate space.
[b00fdde]484 *
485 * @param asi ASI determining the alternate space.
[7a0359b]486 * @param va Virtual address within the ASI.
487 *
488 * @return Value read from the virtual address in
489 * the specified address space.
[b00fdde]490 *
491 */
[7a0359b]492NO_TRACE static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
[b00fdde]493{
[7f1c620]494 uint64_t v;
[b00fdde]495
[7a0359b]496 asm volatile (
497 "ldxa [%[va]] %[asi], %[v]\n"
498 : [v] "=r" (v)
499 : [va] "r" (va),
500 [asi] "i" ((unsigned int) asi)
501 );
[b00fdde]502
503 return v;
504}
505
[7f1c620]506/** Store uint64_t to alternate space.
[b00fdde]507 *
508 * @param asi ASI determining the alternate space.
[7a0359b]509 * @param va Virtual address within the ASI.
510 * @param v Value to be written.
511 *
[b00fdde]512 */
[7a0359b]513NO_TRACE static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
[b00fdde]514{
[7a0359b]515 asm volatile (
516 "stxa %[v], [%[va]] %[asi]\n"
517 :: [v] "r" (v),
518 [va] "r" (va),
519 [asi] "i" ((unsigned int) asi)
520 : "memory"
521 );
[b00fdde]522}
523
[0fa6044]524/** Flush all valid register windows to memory. */
[7a0359b]525NO_TRACE static inline void flushw(void)
[0fa6044]526{
[e7b7be3f]527 asm volatile ("flushw\n");
[0fa6044]528}
529
[fd85ae5]530/** Switch to nucleus by setting TL to 1. */
[7a0359b]531NO_TRACE static inline void nucleus_enter(void)
[fd85ae5]532{
[e7b7be3f]533 asm volatile ("wrpr %g0, 1, %tl\n");
[fd85ae5]534}
535
536/** Switch from nucleus by setting TL to 0. */
[7a0359b]537NO_TRACE static inline void nucleus_leave(void)
[fd85ae5]538{
[e7b7be3f]539 asm volatile ("wrpr %g0, %g0, %tl\n");
[fd85ae5]540}
541
[82474ef]542extern void cpu_halt(void) __attribute__((noreturn));
[e11ae91]543extern void cpu_sleep(void);
[9a5b556]544extern void asm_delay_loop(const uint32_t usec);
[e11ae91]545
[2ee907e]546extern uint64_t read_from_ag_g6(void);
[e11ae91]547extern uint64_t read_from_ag_g7(void);
548extern void write_to_ag_g6(uint64_t val);
549extern void write_to_ag_g7(uint64_t val);
550extern void write_to_ig_g6(uint64_t val);
[2a99fa8]551
[cfa70add]552extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg);
[ed166f7]553
[2a99fa8]554#endif
[b45c443]555
[0ffa3ef5]556/** @}
[b45c443]557 */
Note: See TracBrowser for help on using the repository browser.