2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2019 Western Digital Corporation or its affiliates.
7 * Anup Patel <anup.patel@wdc.com>
10 #ifndef __SBI_SCRATCH_H__
11 #define __SBI_SCRATCH_H__
13 #include <sbi/riscv_asm.h>
15 /* clang-format off */
17 /** Offset of fw_start member in sbi_scratch */
18 #define SBI_SCRATCH_FW_START_OFFSET (0 * __SIZEOF_POINTER__)
19 /** Offset of fw_size member in sbi_scratch */
20 #define SBI_SCRATCH_FW_SIZE_OFFSET (1 * __SIZEOF_POINTER__)
21 /** Offset (in sbi_scratch) of the R/W Offset */
22 #define SBI_SCRATCH_FW_RW_OFFSET (2 * __SIZEOF_POINTER__)
23 /** Offset of fw_heap_offset member in sbi_scratch */
24 #define SBI_SCRATCH_FW_HEAP_OFFSET (3 * __SIZEOF_POINTER__)
25 /** Offset of fw_heap_size_offset member in sbi_scratch */
26 #define SBI_SCRATCH_FW_HEAP_SIZE_OFFSET (4 * __SIZEOF_POINTER__)
27 /** Offset of next_arg1 member in sbi_scratch */
28 #define SBI_SCRATCH_NEXT_ARG1_OFFSET (5 * __SIZEOF_POINTER__)
29 /** Offset of next_addr member in sbi_scratch */
30 #define SBI_SCRATCH_NEXT_ADDR_OFFSET (6 * __SIZEOF_POINTER__)
31 /** Offset of next_mode member in sbi_scratch */
32 #define SBI_SCRATCH_NEXT_MODE_OFFSET (7 * __SIZEOF_POINTER__)
33 /** Offset of warmboot_addr member in sbi_scratch */
34 #define SBI_SCRATCH_WARMBOOT_ADDR_OFFSET (8 * __SIZEOF_POINTER__)
35 /** Offset of platform_addr member in sbi_scratch */
36 #define SBI_SCRATCH_PLATFORM_ADDR_OFFSET (9 * __SIZEOF_POINTER__)
37 /** Offset of hartid_to_scratch member in sbi_scratch */
38 #define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET (10 * __SIZEOF_POINTER__)
39 /** Offset of trap_exit member in sbi_scratch */
40 #define SBI_SCRATCH_TRAP_EXIT_OFFSET (11 * __SIZEOF_POINTER__)
41 /** Offset of tmp0 member in sbi_scratch */
42 #define SBI_SCRATCH_TMP0_OFFSET (12 * __SIZEOF_POINTER__)
43 /** Offset of options member in sbi_scratch */
44 #define SBI_SCRATCH_OPTIONS_OFFSET (13 * __SIZEOF_POINTER__)
45 /** Offset of extra space in sbi_scratch */
46 #define SBI_SCRATCH_EXTRA_SPACE_OFFSET (14 * __SIZEOF_POINTER__)
47 /** Maximum size of sbi_scratch (4KB) */
48 #define SBI_SCRATCH_SIZE (0x1000)
54 #include <sbi/sbi_types.h>
56 /** Representation of per-HART scratch space */
58 /** Start (or base) address of firmware linked to OpenSBI library */
59 unsigned long fw_start;
60 /** Size (in bytes) of firmware linked to OpenSBI library */
61 unsigned long fw_size;
62 /** Offset (in bytes) of the R/W section */
63 unsigned long fw_rw_offset;
64 /** Offset (in bytes) of the heap area */
65 unsigned long fw_heap_offset;
66 /** Size (in bytes) of the heap area */
67 unsigned long fw_heap_size;
68 /** Arg1 (or 'a1' register) of next booting stage for this HART */
69 unsigned long next_arg1;
70 /** Address of next booting stage for this HART */
71 unsigned long next_addr;
72 /** Privilege mode of next booting stage for this HART */
73 unsigned long next_mode;
74 /** Warm boot entry point address for this HART */
75 unsigned long warmboot_addr;
76 /** Address of sbi_platform */
77 unsigned long platform_addr;
78 /** Address of HART ID to sbi_scratch conversion function */
79 unsigned long hartid_to_scratch;
80 /** Address of trap exit function */
81 unsigned long trap_exit;
82 /** Temporary storage */
84 /** Options for OpenSBI library */
85 unsigned long options;
89 * Prevent modification of struct sbi_scratch from affecting
90 * SBI_SCRATCH_xxx_OFFSET
93 offsetof(struct sbi_scratch, fw_start)
94 == SBI_SCRATCH_FW_START_OFFSET,
95 "struct sbi_scratch definition has changed, please redefine "
96 "SBI_SCRATCH_FW_START_OFFSET");
98 offsetof(struct sbi_scratch, fw_size)
99 == SBI_SCRATCH_FW_SIZE_OFFSET,
100 "struct sbi_scratch definition has changed, please redefine "
101 "SBI_SCRATCH_FW_SIZE_OFFSET");
103 offsetof(struct sbi_scratch, next_arg1)
104 == SBI_SCRATCH_NEXT_ARG1_OFFSET,
105 "struct sbi_scratch definition has changed, please redefine "
106 "SBI_SCRATCH_NEXT_ARG1_OFFSET");
108 offsetof(struct sbi_scratch, next_addr)
109 == SBI_SCRATCH_NEXT_ADDR_OFFSET,
110 "struct sbi_scratch definition has changed, please redefine "
111 "SBI_SCRATCH_NEXT_ADDR_OFFSET");
113 offsetof(struct sbi_scratch, next_mode)
114 == SBI_SCRATCH_NEXT_MODE_OFFSET,
115 "struct sbi_scratch definition has changed, please redefine "
116 "SBI_SCRATCH_NEXT_MODE_OFFSET");
118 offsetof(struct sbi_scratch, warmboot_addr)
119 == SBI_SCRATCH_WARMBOOT_ADDR_OFFSET,
120 "struct sbi_scratch definition has changed, please redefine "
121 "SBI_SCRATCH_WARMBOOT_ADDR_OFFSET");
123 offsetof(struct sbi_scratch, platform_addr)
124 == SBI_SCRATCH_PLATFORM_ADDR_OFFSET,
125 "struct sbi_scratch definition has changed, please redefine "
126 "SBI_SCRATCH_PLATFORM_ADDR_OFFSET");
128 offsetof(struct sbi_scratch, hartid_to_scratch)
129 == SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET,
130 "struct sbi_scratch definition has changed, please redefine "
131 "SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET");
133 offsetof(struct sbi_scratch, trap_exit)
134 == SBI_SCRATCH_TRAP_EXIT_OFFSET,
135 "struct sbi_scratch definition has changed, please redefine "
136 "SBI_SCRATCH_TRAP_EXIT_OFFSET");
138 offsetof(struct sbi_scratch, tmp0)
139 == SBI_SCRATCH_TMP0_OFFSET,
140 "struct sbi_scratch definition has changed, please redefine "
141 "SBI_SCRATCH_TMP0_OFFSET");
143 offsetof(struct sbi_scratch, options)
144 == SBI_SCRATCH_OPTIONS_OFFSET,
145 "struct sbi_scratch definition has changed, please redefine "
146 "SBI_SCRATCH_OPTIONS_OFFSET");
148 /** Possible options for OpenSBI library */
149 enum sbi_scratch_options {
150 /** Disable prints during boot */
151 SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0),
152 /** Enable runtime debug prints */
153 SBI_SCRATCH_DEBUG_PRINTS = (1 << 1),
156 /** Get pointer to sbi_scratch for current HART */
157 #define sbi_scratch_thishart_ptr() \
158 ((struct sbi_scratch *)csr_read(CSR_MSCRATCH))
160 /** Get Arg1 of next booting stage for current HART */
161 #define sbi_scratch_thishart_arg1_ptr() \
162 ((void *)(sbi_scratch_thishart_ptr()->next_arg1))
164 /** Initialize scratch table and allocator */
165 int sbi_scratch_init(struct sbi_scratch *scratch);
168 * Allocate from extra space in sbi_scratch
170 * @return zero on failure and non-zero (>= SBI_SCRATCH_EXTRA_SPACE_OFFSET)
173 unsigned long sbi_scratch_alloc_offset(unsigned long size);
175 /** Free-up extra space in sbi_scratch */
176 void sbi_scratch_free_offset(unsigned long offset);
178 /** Amount (in bytes) of used space in in sbi_scratch */
179 unsigned long sbi_scratch_used_space(void);
181 /** Get pointer from offset in sbi_scratch */
182 #define sbi_scratch_offset_ptr(scratch, offset) (void *)((char *)(scratch) + (offset))
184 /** Get pointer from offset in sbi_scratch for current HART */
185 #define sbi_scratch_thishart_offset_ptr(offset) \
186 (void *)((char *)sbi_scratch_thishart_ptr() + (offset))
188 /** Allocate offset for a data type in sbi_scratch */
189 #define sbi_scratch_alloc_type_offset(__type) \
190 sbi_scratch_alloc_offset(sizeof(__type))
192 /** Read a data type from sbi_scratch at given offset */
193 #define sbi_scratch_read_type(__scratch, __type, __offset) \
195 *((__type *)sbi_scratch_offset_ptr((__scratch), (__offset))); \
198 /** Write a data type to sbi_scratch at given offset */
199 #define sbi_scratch_write_type(__scratch, __type, __offset, __ptr) \
201 *((__type *)sbi_scratch_offset_ptr((__scratch), (__offset))) \
205 /** HART id to scratch table */
206 extern struct sbi_scratch *hartid_to_scratch_table[];
208 /** Get sbi_scratch from HART id */
209 #define sbi_hartid_to_scratch(__hartid) \
210 hartid_to_scratch_table[__hartid]
212 /** Last HART id having a sbi_scratch pointer */
213 extern u32 last_hartid_having_scratch;
215 /** Get last HART id having a sbi_scratch pointer */
216 #define sbi_scratch_last_hartid() last_hartid_having_scratch