summaryrefslogtreecommitdiffstats
path: root/meta/recipes-bsp/opensbi/files/0002-lib-Create-a-sbi_ipi_data-structure.patch
blob: 3c846bde629d28aa6abf693a1f0be139a517fba4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From 508a27204cbbca0a9430236e56681e5e0d343fb9 Mon Sep 17 00:00:00 2001
From: Alistair Francis <alistair.francis@wdc.com>
Date: Fri, 8 Mar 2019 11:22:22 -0800
Subject: [PATCH] lib: Create a sbi_ipi_data structure

Create a sbi_ipi_data structure that holds unpacked IPI information. At
the same time remove ipi_type from the sbi_scratch struct and use a
fixed offset to access it.

This structure fits in behind the sbi_scratch structure.

This fixes https://github.com/riscv/opensbi/issues/81

Upstream-Status: Backport [https://github.com/riscv/opensbi/commit/508a27204cbbca0a9430236e56681e5e0d343fb9]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 firmware/fw_base.S        |  1 -
 include/sbi/sbi_scratch.h | 23 ++++++++++++++++-------
 lib/sbi_ipi.c             |  8 +++++---
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index cf2c6a0..69cfc90 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -183,7 +183,6 @@ _start_warm:
 	REG_S	a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
 	la	a4, _hartid_to_scratch
 	REG_S	a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
-	REG_S	zero, SBI_SCRATCH_IPI_TYPE_OFFSET(tp)
 	REG_S	zero, SBI_SCRATCH_TMP0_OFFSET(tp)
 
 	/* Setup stack */
diff --git a/include/sbi/sbi_scratch.h b/include/sbi/sbi_scratch.h
index 8389ef3..70ab384 100644
--- a/include/sbi/sbi_scratch.h
+++ b/include/sbi/sbi_scratch.h
@@ -28,17 +28,24 @@
 #define SBI_SCRATCH_PLATFORM_ADDR_OFFSET	(6 * __SIZEOF_POINTER__)
 /** Offset of hartid_to_scratch member in sbi_scratch */
 #define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET	(7 * __SIZEOF_POINTER__)
-/** Offset of ipi_type member in sbi_scratch */
-#define SBI_SCRATCH_IPI_TYPE_OFFSET		(8 * __SIZEOF_POINTER__)
 /** Offset of tmp0 member in sbi_scratch */
-#define SBI_SCRATCH_TMP0_OFFSET			(9 * __SIZEOF_POINTER__)
-/** Maximum size of sbi_scratch */
-#define SBI_SCRATCH_SIZE			256
+#define SBI_SCRATCH_TMP0_OFFSET			(8 * __SIZEOF_POINTER__)
+
+/** sbi_ipi_data is located behind sbi_scratch. This struct is not packed. */
+/** Offset of ipi_type in sbi_ipi_data */
+#define SBI_IPI_DATA_IPI_TYPE_OFFSET		(15 * __SIZEOF_POINTER__)
+
+/** Maximum size of sbi_scratch and sbi_ipi_data */
+#define SBI_SCRATCH_SIZE			(32 * __SIZEOF_POINTER__)
 
 #ifndef __ASSEMBLY__
 
 #include <sbi/sbi_types.h>
 
+struct sbi_ipi_data {
+	unsigned long ipi_type;
+};
+
 /** Representation of per-HART scratch space */
 struct sbi_scratch {
 	/** Start (or base) address of firmware linked to OpenSBI library */
@@ -57,8 +64,6 @@ struct sbi_scratch {
 	unsigned long platform_addr;
 	/** Address of HART ID to sbi_scratch conversion function */
 	unsigned long hartid_to_scratch;
-	/** IPI type (or flags) */
-	unsigned long ipi_type;
 	/** Temporary storage */
 	unsigned long tmp0;
 } __packed;
@@ -71,6 +76,10 @@ struct sbi_scratch {
 #define sbi_scratch_thishart_arg1_ptr()	\
 ((void *)(sbi_scratch_thishart_ptr()->next_arg1))
 
+/** Get pointer to sbi_ipi_data from sbi_scratch */
+#define sbi_ipi_data_ptr(scratch)      \
+((struct sbi_ipi_data *)(void*)scratch + SBI_IPI_DATA_IPI_TYPE_OFFSET)
+
 #endif
 
 #endif
diff --git a/lib/sbi_ipi.c b/lib/sbi_ipi.c
index 0e371d7..e0f2a19 100644
--- a/lib/sbi_ipi.c
+++ b/lib/sbi_ipi.c
@@ -31,7 +31,7 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid, u32 event)
 	 * trigger the interrupt
 	 */
 	remote_scratch = sbi_hart_id_to_scratch(scratch, hartid);
-	atomic_raw_set_bit(event, &remote_scratch->ipi_type);
+	atomic_raw_set_bit(event, &sbi_ipi_data_ptr(remote_scratch)->ipi_type);
 	mb();
 	sbi_platform_ipi_send(plat, hartid);
 	if (event != SBI_IPI_EVENT_SOFT)
@@ -80,7 +80,7 @@ void sbi_ipi_process(struct sbi_scratch *scratch)
 	sbi_platform_ipi_clear(plat, hartid);
 
 	do {
-		ipi_type = scratch->ipi_type;
+		ipi_type = sbi_ipi_data_ptr(scratch)->ipi_type;
 		rmb();
 		ipi_event = __ffs(ipi_type);
 		switch (ipi_event) {
@@ -97,12 +97,14 @@ void sbi_ipi_process(struct sbi_scratch *scratch)
 			sbi_hart_hang();
 			break;
 		};
-		ipi_type = atomic_raw_clear_bit(ipi_event, &scratch->ipi_type);
+		ipi_type = atomic_raw_clear_bit(ipi_event, &sbi_ipi_data_ptr(scratch)->ipi_type);
 	} while(ipi_type > 0);
 }
 
 int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot)
 {
+	sbi_ipi_data_ptr(scratch)->ipi_type = 0x00;
+
 	/* Enable software interrupts */
 	csr_set(CSR_MIE, MIP_MSIP);
 
-- 
2.22.0