1/* $NetBSD: profile.h,v 1.1.60.1 2026/04/02 15:59:59 martin Exp $ */
2
3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef _RISCV_PROFILE_H_
33#define _RISCV_PROFILE_H_
34
35#include <machine/sysreg.h>
36
37#define _MCOUNT_DECL void mcount
38
39#define MCOUNT_ASM_NAME "_mcount"
40#define PLTSYM
41
42#ifdef _LP64
43#define MCOUNT MCOUNT_ARCH("8", "sd", "ld")
44#else
45#define MCOUNT MCOUNT_ARCH("4", "sw", "lw")
46#endif
47
48#ifdef __PIC__
49#define _PLT "@plt"
50#else
51#define _PLT /* nothing */
52#endif
53
54
55#define MCOUNT_ARCH(_SZREG, _REG_S, _REG_L) __asm( \
56" .text\n" \
57" .align 2\n" \
58" .type " MCOUNT_ASM_NAME ",@function\n" \
59" .global " MCOUNT_ASM_NAME "\n" \
60MCOUNT_ASM_NAME ":\n" \
61 /* \
62 * Preserve registers that could be trashed during mcount, i.e. \
63 * caller saved registers. \
64 */ \
65" addi sp, sp, -(16 * " _SZREG ")\n" \
66" " _REG_S " ra, ( 0 * " _SZREG ")(sp)\n" \
67" " _REG_S " t0, ( 1 * " _SZREG ")(sp)\n" \
68" " _REG_S " t1, ( 2 * " _SZREG ")(sp)\n" \
69" " _REG_S " t2, ( 3 * " _SZREG ")(sp)\n" \
70" " _REG_S " a0, ( 4 * " _SZREG ")(sp)\n" \
71" " _REG_S " a1, ( 5 * " _SZREG ")(sp)\n" \
72" " _REG_S " a2, ( 6 * " _SZREG ")(sp)\n" \
73" " _REG_S " a3, ( 7 * " _SZREG ")(sp)\n" \
74" " _REG_S " a4, ( 8 * " _SZREG ")(sp)\n" \
75" " _REG_S " a5, ( 9 * " _SZREG ")(sp)\n" \
76" " _REG_S " a6, (10 * " _SZREG ")(sp)\n" \
77" " _REG_S " a7, (11 * " _SZREG ")(sp)\n" \
78" " _REG_S " t3, (12 * " _SZREG ")(sp)\n" \
79" " _REG_S " t4, (13 * " _SZREG ")(sp)\n" \
80" " _REG_S " t5, (14 * " _SZREG ")(sp)\n" \
81" " _REG_S " t6, (15 * " _SZREG ")(sp)\n" \
82" mv a1, ra\n" \
83" call mcount " _PLT "\n" \
84 /* restore caller saved registers */ \
85" " _REG_L " ra, ( 0 * " _SZREG ")(sp)\n" \
86" " _REG_L " t0, ( 1 * " _SZREG ")(sp)\n" \
87" " _REG_L " t1, ( 2 * " _SZREG ")(sp)\n" \
88" " _REG_L " t2, ( 3 * " _SZREG ")(sp)\n" \
89" " _REG_L " a0, ( 4 * " _SZREG ")(sp)\n" \
90" " _REG_L " a1, ( 5 * " _SZREG ")(sp)\n" \
91" " _REG_L " a2, ( 6 * " _SZREG ")(sp)\n" \
92" " _REG_L " a3, ( 7 * " _SZREG ")(sp)\n" \
93" " _REG_L " a4, ( 8 * " _SZREG ")(sp)\n" \
94" " _REG_L " a5, ( 9 * " _SZREG ")(sp)\n" \
95" " _REG_L " a6, (10 * " _SZREG ")(sp)\n" \
96" " _REG_L " a7, (11 * " _SZREG ")(sp)\n" \
97" " _REG_L " t3, (12 * " _SZREG ")(sp)\n" \
98" " _REG_L " t4, (13 * " _SZREG ")(sp)\n" \
99" " _REG_L " t5, (14 * " _SZREG ")(sp)\n" \
100" " _REG_L " t6, (15 * " _SZREG ")(sp)\n" \
101" addi sp, sp, (16 * " _SZREG ")\n" \
102" jr ra\n");
103
104
105#ifdef _KERNEL
106
107#define MCOUNT_ENTER \
108 s = (csr_sstatus_read() & SR_SIE) != 0; \
109 csr_sstatus_clear(SR_SIE); // DISABLE_INTERRUPTS
110
111#define MCOUNT_EXIT \
112 if (s) \
113 csr_sstatus_set(SR_SIE); // ENABLE_INTERRUPTS
114
115#endif
116
117#endif /* _RISCV_PROFILE_H_ */