Brad Bishop | f3fd288 | 2019-06-21 08:06:37 -0400 | [diff] [blame^] | 1 | From 508a27204cbbca0a9430236e56681e5e0d343fb9 Mon Sep 17 00:00:00 2001 |
| 2 | From: Alistair Francis <alistair.francis@wdc.com> |
| 3 | Date: Fri, 8 Mar 2019 11:22:22 -0800 |
| 4 | Subject: [PATCH] lib: Create a sbi_ipi_data structure |
| 5 | |
| 6 | Create a sbi_ipi_data structure that holds unpacked IPI information. At |
| 7 | the same time remove ipi_type from the sbi_scratch struct and use a |
| 8 | fixed offset to access it. |
| 9 | |
| 10 | This structure fits in behind the sbi_scratch structure. |
| 11 | |
| 12 | This fixes https://github.com/riscv/opensbi/issues/81 |
| 13 | |
| 14 | Upstream-Status: Backport [https://github.com/riscv/opensbi/commit/508a27204cbbca0a9430236e56681e5e0d343fb9] |
| 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
| 16 | --- |
| 17 | firmware/fw_base.S | 1 - |
| 18 | include/sbi/sbi_scratch.h | 23 ++++++++++++++++------- |
| 19 | lib/sbi_ipi.c | 8 +++++--- |
| 20 | 3 files changed, 21 insertions(+), 11 deletions(-) |
| 21 | |
| 22 | diff --git a/firmware/fw_base.S b/firmware/fw_base.S |
| 23 | index cf2c6a0..69cfc90 100644 |
| 24 | --- a/firmware/fw_base.S |
| 25 | +++ b/firmware/fw_base.S |
| 26 | @@ -183,7 +183,6 @@ _start_warm: |
| 27 | REG_S a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp) |
| 28 | la a4, _hartid_to_scratch |
| 29 | REG_S a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp) |
| 30 | - REG_S zero, SBI_SCRATCH_IPI_TYPE_OFFSET(tp) |
| 31 | REG_S zero, SBI_SCRATCH_TMP0_OFFSET(tp) |
| 32 | |
| 33 | /* Setup stack */ |
| 34 | diff --git a/include/sbi/sbi_scratch.h b/include/sbi/sbi_scratch.h |
| 35 | index 8389ef3..70ab384 100644 |
| 36 | --- a/include/sbi/sbi_scratch.h |
| 37 | +++ b/include/sbi/sbi_scratch.h |
| 38 | @@ -28,17 +28,24 @@ |
| 39 | #define SBI_SCRATCH_PLATFORM_ADDR_OFFSET (6 * __SIZEOF_POINTER__) |
| 40 | /** Offset of hartid_to_scratch member in sbi_scratch */ |
| 41 | #define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET (7 * __SIZEOF_POINTER__) |
| 42 | -/** Offset of ipi_type member in sbi_scratch */ |
| 43 | -#define SBI_SCRATCH_IPI_TYPE_OFFSET (8 * __SIZEOF_POINTER__) |
| 44 | /** Offset of tmp0 member in sbi_scratch */ |
| 45 | -#define SBI_SCRATCH_TMP0_OFFSET (9 * __SIZEOF_POINTER__) |
| 46 | -/** Maximum size of sbi_scratch */ |
| 47 | -#define SBI_SCRATCH_SIZE 256 |
| 48 | +#define SBI_SCRATCH_TMP0_OFFSET (8 * __SIZEOF_POINTER__) |
| 49 | + |
| 50 | +/** sbi_ipi_data is located behind sbi_scratch. This struct is not packed. */ |
| 51 | +/** Offset of ipi_type in sbi_ipi_data */ |
| 52 | +#define SBI_IPI_DATA_IPI_TYPE_OFFSET (15 * __SIZEOF_POINTER__) |
| 53 | + |
| 54 | +/** Maximum size of sbi_scratch and sbi_ipi_data */ |
| 55 | +#define SBI_SCRATCH_SIZE (32 * __SIZEOF_POINTER__) |
| 56 | |
| 57 | #ifndef __ASSEMBLY__ |
| 58 | |
| 59 | #include <sbi/sbi_types.h> |
| 60 | |
| 61 | +struct sbi_ipi_data { |
| 62 | + unsigned long ipi_type; |
| 63 | +}; |
| 64 | + |
| 65 | /** Representation of per-HART scratch space */ |
| 66 | struct sbi_scratch { |
| 67 | /** Start (or base) address of firmware linked to OpenSBI library */ |
| 68 | @@ -57,8 +64,6 @@ struct sbi_scratch { |
| 69 | unsigned long platform_addr; |
| 70 | /** Address of HART ID to sbi_scratch conversion function */ |
| 71 | unsigned long hartid_to_scratch; |
| 72 | - /** IPI type (or flags) */ |
| 73 | - unsigned long ipi_type; |
| 74 | /** Temporary storage */ |
| 75 | unsigned long tmp0; |
| 76 | } __packed; |
| 77 | @@ -71,6 +76,10 @@ struct sbi_scratch { |
| 78 | #define sbi_scratch_thishart_arg1_ptr() \ |
| 79 | ((void *)(sbi_scratch_thishart_ptr()->next_arg1)) |
| 80 | |
| 81 | +/** Get pointer to sbi_ipi_data from sbi_scratch */ |
| 82 | +#define sbi_ipi_data_ptr(scratch) \ |
| 83 | +((struct sbi_ipi_data *)(void*)scratch + SBI_IPI_DATA_IPI_TYPE_OFFSET) |
| 84 | + |
| 85 | #endif |
| 86 | |
| 87 | #endif |
| 88 | diff --git a/lib/sbi_ipi.c b/lib/sbi_ipi.c |
| 89 | index 0e371d7..e0f2a19 100644 |
| 90 | --- a/lib/sbi_ipi.c |
| 91 | +++ b/lib/sbi_ipi.c |
| 92 | @@ -31,7 +31,7 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid, u32 event) |
| 93 | * trigger the interrupt |
| 94 | */ |
| 95 | remote_scratch = sbi_hart_id_to_scratch(scratch, hartid); |
| 96 | - atomic_raw_set_bit(event, &remote_scratch->ipi_type); |
| 97 | + atomic_raw_set_bit(event, &sbi_ipi_data_ptr(remote_scratch)->ipi_type); |
| 98 | mb(); |
| 99 | sbi_platform_ipi_send(plat, hartid); |
| 100 | if (event != SBI_IPI_EVENT_SOFT) |
| 101 | @@ -80,7 +80,7 @@ void sbi_ipi_process(struct sbi_scratch *scratch) |
| 102 | sbi_platform_ipi_clear(plat, hartid); |
| 103 | |
| 104 | do { |
| 105 | - ipi_type = scratch->ipi_type; |
| 106 | + ipi_type = sbi_ipi_data_ptr(scratch)->ipi_type; |
| 107 | rmb(); |
| 108 | ipi_event = __ffs(ipi_type); |
| 109 | switch (ipi_event) { |
| 110 | @@ -97,12 +97,14 @@ void sbi_ipi_process(struct sbi_scratch *scratch) |
| 111 | sbi_hart_hang(); |
| 112 | break; |
| 113 | }; |
| 114 | - ipi_type = atomic_raw_clear_bit(ipi_event, &scratch->ipi_type); |
| 115 | + ipi_type = atomic_raw_clear_bit(ipi_event, &sbi_ipi_data_ptr(scratch)->ipi_type); |
| 116 | } while(ipi_type > 0); |
| 117 | } |
| 118 | |
| 119 | int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot) |
| 120 | { |
| 121 | + sbi_ipi_data_ptr(scratch)->ipi_type = 0x00; |
| 122 | + |
| 123 | /* Enable software interrupts */ |
| 124 | csr_set(CSR_MIE, MIP_MSIP); |
| 125 | |
| 126 | -- |
| 127 | 2.22.0 |
| 128 | |