xref: /aosp_15_r20/external/coreboot/src/arch/riscv/include/mcall.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef _MCALL_H
4 #define _MCALL_H
5 
6 // NOTE: this is the size of struct hls below. A static_assert would be
7 // nice to have.
8 #if __riscv_xlen == 64
9 #define HLS_SIZE 88
10 #endif
11 
12 #if __riscv_xlen == 32
13 #define HLS_SIZE 52
14 #endif
15 
16 /* We save 37 registers, currently. */
17 #define MENTRY_FRAME_SIZE (HLS_SIZE + 37 * __SIZEOF_POINTER__)
18 
19 #ifndef __ASSEMBLER__
20 
21 #include <arch/encoding.h>
22 #include <arch/smp/atomic.h>
23 #include <stdint.h>
24 
25 struct sbi_device_message {
26 	unsigned long dev;
27 	unsigned long cmd;
28 	unsigned long data;
29 	unsigned long sbi_private_data;
30 };
31 
32 struct blocker {
33 	void *arg;
34 	void (*fn)(void *arg);
35 	atomic_t sync_a;
36 	atomic_t sync_b;
37 };
38 
39 struct hls {
40 	struct sbi_device_message *device_request_queue_head;
41 	unsigned long device_request_queue_size;
42 	struct sbi_device_message *device_response_queue_head;
43 	struct sbi_device_message *device_response_queue_tail;
44 
45 	int hart_id;
46 	int ipi_pending;
47 	uint64_t *timecmp;
48 	uint64_t *time;
49 	void *fdt;
50 	struct blocker entry;
51 };
52 
53 _Static_assert(
54 	sizeof(struct hls) == HLS_SIZE,
55 	"HLS_SIZE must equal to sizeof(struct hls)");
56 
57 register uintptr_t current_stack_pointer asm("sp");
58 
59 #define MACHINE_STACK_TOP() ({ \
60 	(void *)((current_stack_pointer + RISCV_PGSIZE) & -RISCV_PGSIZE); })
61 
62 // hart-local storage, at top of stack
63 #define HLS() ((struct hls *)(MACHINE_STACK_TOP() - HLS_SIZE))
64 #define OTHER_HLS(id) ((struct hls *)((void *)HLS() + RISCV_PGSIZE * ((id) - HLS()->hart_id)))
65 
66 #define MACHINE_STACK_SIZE RISCV_PGSIZE
67 
68 // need to call this before launching linux
69 void hls_init(uint32_t hart_id, void *fdt);
70 
71 /* This function is used to initialize HLS()->time/HLS()->timecmp  */
72 void mtime_init(void);
73 
74 /*
75  * This function needs be implement by SoC code.
76  * Although the privileged instruction set defines that MSIP will be
77  * memory-mapped, but does not define how to map. SoC can be implemented as
78  * a bit, a byte, a word, and so on.
79  * So we can't provide code that is related to implementation.
80  */
81 void set_msip(int hartid, int val);
82 
83 #endif // __ASSEMBLER__
84 
85 #endif
86