* [PATCH v2 0/6] Assorted improvements
@ 2023-12-12 9:59 Anup Patel
2023-12-12 9:59 ` [PATCH v2 1/6] lib: sbi_tlb: Reduce size of struct sbi_tlb_info Anup Patel
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-12 9:59 UTC (permalink / raw)
To: opensbi
This series does various assorted improvements. The patch1 and patch2
improve heap usage by reducing size of struct sbi_tlb_info. The patch3
is fixes PLIC driver for use on platforms with Smepmp. The patch4 and
patch5 improve ecall handlers.
These patches can also be found the misc_imp_v2 branch at
https://github.com/avpatel/opensbi.git
Changes since v1:
- Addressed Samuel's comment on PATCH1
- Added new PATCH6 which enforces that previous booting stage does
not enter OpenSBI with mseccfg.MML == 1 on platforms with Smepmp
Anup Patel (6):
lib: sbi_tlb: Reduce size of struct sbi_tlb_info
platform: generic: Fine tune fw_platform_calculate_heap_size()
lib: utils/irqchip: Add shared MMIO region for PLIC in root domain
lib: sbi: Allow ecall handlers to directly update register state
lib: sbi: Remove the SBI_ETRAP error code
lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1
include/sbi/sbi_ecall.h | 12 ++-
include/sbi/sbi_error.h | 5 +-
include/sbi/sbi_platform.h | 19 ++---
include/sbi/sbi_tlb.h | 29 +++----
include/sbi_utils/irqchip/plic.h | 1 +
lib/sbi/sbi_ecall.c | 13 +---
lib/sbi/sbi_ecall_base.c | 27 ++++---
lib/sbi/sbi_ecall_cppc.c | 13 ++--
lib/sbi/sbi_ecall_dbcn.c | 9 +--
lib/sbi/sbi_ecall_hsm.c | 7 +-
lib/sbi/sbi_ecall_ipi.c | 5 +-
lib/sbi/sbi_ecall_legacy.c | 59 ++++++++------
lib/sbi/sbi_ecall_pmu.c | 17 ++--
lib/sbi/sbi_ecall_rfence.c | 21 +++--
lib/sbi/sbi_ecall_srst.c | 5 +-
lib/sbi/sbi_ecall_susp.c | 7 +-
lib/sbi/sbi_ecall_time.c | 5 +-
lib/sbi/sbi_ecall_vendor.c | 8 +-
lib/sbi/sbi_hart.c | 10 +++
lib/sbi/sbi_tlb.c | 81 ++++++++++++--------
lib/utils/fdt/fdt_helper.c | 1 +
lib/utils/irqchip/plic.c | 6 +-
platform/fpga/ariane/platform.c | 3 +
platform/fpga/openpiton/platform.c | 3 +
platform/generic/andes/andes_sbi.c | 7 +-
platform/generic/include/andes/andes_sbi.h | 6 +-
platform/generic/include/platform_override.h | 6 +-
platform/generic/platform.c | 11 ++-
platform/kendryte/k210/platform.c | 1 +
platform/kendryte/k210/platform.h | 1 +
platform/nuclei/ux600/platform.c | 3 +
platform/template/platform.c | 3 +
32 files changed, 224 insertions(+), 180 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/6] lib: sbi_tlb: Reduce size of struct sbi_tlb_info
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
@ 2023-12-12 9:59 ` Anup Patel
2023-12-12 9:59 ` [PATCH v2 2/6] platform: generic: Fine tune fw_platform_calculate_heap_size() Anup Patel
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-12 9:59 UTC (permalink / raw)
To: opensbi
Let us reduce the size of struct sbi_tlb_info by doing the
following:
1) Change the data type of asid and vmid fields to uint16_t
2) Replace local_fn() function pointer with an enum
Based on the above, the size of struct sbi_tlb_info is reduced
by 16 bytes on RV64 and 4 bytes on RV32.
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
include/sbi/sbi_tlb.h | 29 ++++++++------
lib/sbi/sbi_ecall_legacy.c | 8 ++--
lib/sbi/sbi_ecall_rfence.c | 16 ++++----
lib/sbi/sbi_tlb.c | 81 ++++++++++++++++++++++++--------------
4 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/include/sbi/sbi_tlb.h b/include/sbi/sbi_tlb.h
index 55dcab0..2c50fe8 100644
--- a/include/sbi/sbi_tlb.h
+++ b/include/sbi/sbi_tlb.h
@@ -22,30 +22,33 @@
struct sbi_scratch;
+enum sbi_tlb_type {
+ SBI_TLB_FENCE_I = 0,
+ SBI_TLB_SFENCE_VMA,
+ SBI_TLB_SFENCE_VMA_ASID,
+ SBI_TLB_HFENCE_GVMA_VMID,
+ SBI_TLB_HFENCE_GVMA,
+ SBI_TLB_HFENCE_VVMA_ASID,
+ SBI_TLB_HFENCE_VVMA,
+ SBI_TLB_TYPE_MAX,
+};
+
struct sbi_tlb_info {
unsigned long start;
unsigned long size;
- unsigned long asid;
- unsigned long vmid;
- void (*local_fn)(struct sbi_tlb_info *tinfo);
+ uint16_t asid;
+ uint16_t vmid;
+ enum sbi_tlb_type type;
struct sbi_hartmask smask;
};
-void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo);
-void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo);
-void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo);
-void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo);
-void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo);
-void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo);
-void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo);
-
-#define SBI_TLB_INFO_INIT(__p, __start, __size, __asid, __vmid, __lfn, __src) \
+#define SBI_TLB_INFO_INIT(__p, __start, __size, __asid, __vmid, __type, __src) \
do { \
(__p)->start = (__start); \
(__p)->size = (__size); \
(__p)->asid = (__asid); \
(__p)->vmid = (__vmid); \
- (__p)->local_fn = (__lfn); \
+ (__p)->type = (__type); \
SBI_HARTMASK_INIT_EXCEPT(&(__p)->smask, (__src)); \
} while (0)
diff --git a/lib/sbi/sbi_ecall_legacy.c b/lib/sbi/sbi_ecall_legacy.c
index 99e862e..556f629 100644
--- a/lib/sbi/sbi_ecall_legacy.c
+++ b/lib/sbi/sbi_ecall_legacy.c
@@ -80,8 +80,7 @@ static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
&hmask, out_trap);
if (ret != SBI_ETRAP) {
SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
- sbi_tlb_local_fence_i,
- source_hart);
+ SBI_TLB_FENCE_I, source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
}
break;
@@ -90,8 +89,7 @@ static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
&hmask, out_trap);
if (ret != SBI_ETRAP) {
SBI_TLB_INFO_INIT(&tlb_info, regs->a1, regs->a2, 0, 0,
- sbi_tlb_local_sfence_vma,
- source_hart);
+ SBI_TLB_SFENCE_VMA, source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
}
break;
@@ -101,7 +99,7 @@ static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
if (ret != SBI_ETRAP) {
SBI_TLB_INFO_INIT(&tlb_info, regs->a1,
regs->a2, regs->a3, 0,
- sbi_tlb_local_sfence_vma_asid,
+ SBI_TLB_SFENCE_VMA_ASID,
source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
}
diff --git a/lib/sbi/sbi_ecall_rfence.c b/lib/sbi/sbi_ecall_rfence.c
index 22c6652..4b74d41 100644
--- a/lib/sbi/sbi_ecall_rfence.c
+++ b/lib/sbi/sbi_ecall_rfence.c
@@ -33,43 +33,41 @@ static int sbi_ecall_rfence_handler(unsigned long extid, unsigned long funcid,
switch (funcid) {
case SBI_EXT_RFENCE_REMOTE_FENCE_I:
SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
- sbi_tlb_local_fence_i, source_hart);
+ SBI_TLB_FENCE_I, source_hart);
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
break;
case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA:
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, 0,
- sbi_tlb_local_hfence_gvma, source_hart);
+ SBI_TLB_HFENCE_GVMA, source_hart);
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
break;
case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID:
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, regs->a4,
- sbi_tlb_local_hfence_gvma_vmid,
- source_hart);
+ SBI_TLB_HFENCE_GVMA_VMID, source_hart);
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
break;
case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA:
vmid = (csr_read(CSR_HGATP) & HGATP_VMID_MASK);
vmid = vmid >> HGATP_VMID_SHIFT;
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, vmid,
- sbi_tlb_local_hfence_vvma, source_hart);
+ SBI_TLB_HFENCE_VVMA, source_hart);
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
break;
case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID:
vmid = (csr_read(CSR_HGATP) & HGATP_VMID_MASK);
vmid = vmid >> HGATP_VMID_SHIFT;
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, regs->a4,
- vmid, sbi_tlb_local_hfence_vvma_asid,
- source_hart);
+ vmid, SBI_TLB_HFENCE_VVMA_ASID, source_hart);
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
break;
case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA:
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, 0,
- sbi_tlb_local_sfence_vma, source_hart);
+ SBI_TLB_SFENCE_VMA, source_hart);
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
break;
case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID:
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, regs->a4, 0,
- sbi_tlb_local_sfence_vma_asid, source_hart);
+ SBI_TLB_SFENCE_VMA_ASID, source_hart);
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
break;
default:
diff --git a/lib/sbi/sbi_tlb.c b/lib/sbi/sbi_tlb.c
index d3ed56d..cca319f 100644
--- a/lib/sbi/sbi_tlb.c
+++ b/lib/sbi/sbi_tlb.c
@@ -34,7 +34,7 @@ static void tlb_flush_all(void)
__asm__ __volatile("sfence.vma");
}
-void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo)
+static void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -59,7 +59,7 @@ done:
csr_write(CSR_HGATP, hgatp);
}
-void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)
+static void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -77,7 +77,7 @@ void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)
}
}
-void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
+static void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -98,7 +98,7 @@ void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
}
}
-void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo)
+static void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -124,7 +124,7 @@ done:
csr_write(CSR_HGATP, hgatp);
}
-void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
+static void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -143,7 +143,7 @@ void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
}
}
-void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
+static void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -169,32 +169,43 @@ void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
}
}
-void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo)
+static void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo)
{
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_FENCE_I_RECVD);
__asm__ __volatile("fence.i");
}
-static void tlb_pmu_incr_fw_ctr(struct sbi_tlb_info *data)
+static void tlb_entry_local_process(struct sbi_tlb_info *data)
{
if (unlikely(!data))
return;
- if (data->local_fn == sbi_tlb_local_fence_i)
- sbi_pmu_ctr_incr_fw(SBI_PMU_FW_FENCE_I_SENT);
- else if (data->local_fn == sbi_tlb_local_sfence_vma)
- sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_SENT);
- else if (data->local_fn == sbi_tlb_local_sfence_vma_asid)
- sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_ASID_SENT);
- else if (data->local_fn == sbi_tlb_local_hfence_gvma)
- sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_GVMA_SENT);
- else if (data->local_fn == sbi_tlb_local_hfence_gvma_vmid)
- sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_GVMA_VMID_SENT);
- else if (data->local_fn == sbi_tlb_local_hfence_vvma)
- sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_VVMA_SENT);
- else if (data->local_fn == sbi_tlb_local_hfence_vvma_asid)
- sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_VVMA_ASID_SENT);
+ switch (data->type) {
+ case SBI_TLB_FENCE_I:
+ sbi_tlb_local_fence_i(data);
+ break;
+ case SBI_TLB_SFENCE_VMA:
+ sbi_tlb_local_sfence_vma(data);
+ break;
+ case SBI_TLB_SFENCE_VMA_ASID:
+ sbi_tlb_local_sfence_vma_asid(data);
+ break;
+ case SBI_TLB_HFENCE_GVMA_VMID:
+ sbi_tlb_local_hfence_gvma_vmid(data);
+ break;
+ case SBI_TLB_HFENCE_GVMA:
+ sbi_tlb_local_hfence_gvma(data);
+ break;
+ case SBI_TLB_HFENCE_VVMA_ASID:
+ sbi_tlb_local_hfence_vvma_asid(data);
+ break;
+ case SBI_TLB_HFENCE_VVMA:
+ sbi_tlb_local_hfence_vvma(data);
+ break;
+ default:
+ break;
+ };
}
static void tlb_entry_process(struct sbi_tlb_info *tinfo)
@@ -203,7 +214,7 @@ static void tlb_entry_process(struct sbi_tlb_info *tinfo)
struct sbi_scratch *rscratch = NULL;
atomic_t *rtlb_sync = NULL;
- tinfo->local_fn(tinfo);
+ tlb_entry_local_process(tinfo);
sbi_hartmask_for_each_hartindex(rindex, &tinfo->smask) {
rscratch = sbi_hartindex_to_scratch(rindex);
@@ -305,12 +316,12 @@ static int tlb_update_cb(void *in, void *data)
curr = (struct sbi_tlb_info *)data;
next = (struct sbi_tlb_info *)in;
- if (next->local_fn == sbi_tlb_local_sfence_vma_asid &&
- curr->local_fn == sbi_tlb_local_sfence_vma_asid) {
+ if (next->type == SBI_TLB_SFENCE_VMA_ASID &&
+ curr->type == SBI_TLB_SFENCE_VMA_ASID) {
if (next->asid == curr->asid)
ret = tlb_range_check(curr, next);
- } else if (next->local_fn == sbi_tlb_local_sfence_vma &&
- curr->local_fn == sbi_tlb_local_sfence_vma) {
+ } else if (next->type == SBI_TLB_SFENCE_VMA &&
+ curr->type == SBI_TLB_SFENCE_VMA) {
ret = tlb_range_check(curr, next);
}
@@ -332,7 +343,7 @@ static int tlb_update(struct sbi_scratch *scratch,
* then just do a local flush and return;
*/
if (sbi_hartindex_to_hartid(remote_hartindex) == curr_hartid) {
- tinfo->local_fn(tinfo);
+ tlb_entry_local_process(tinfo);
return SBI_IPI_UPDATE_BREAK;
}
@@ -370,9 +381,19 @@ static struct sbi_ipi_event_ops tlb_ops = {
static u32 tlb_event = SBI_IPI_EVENT_MAX;
+static const u32 tlb_type_to_pmu_fw_event[SBI_TLB_TYPE_MAX] = {
+ [SBI_TLB_FENCE_I] = SBI_PMU_FW_FENCE_I_SENT,
+ [SBI_TLB_SFENCE_VMA] = SBI_PMU_FW_SFENCE_VMA_SENT,
+ [SBI_TLB_SFENCE_VMA_ASID] = SBI_PMU_FW_SFENCE_VMA_ASID_SENT,
+ [SBI_TLB_HFENCE_GVMA_VMID] = SBI_PMU_FW_HFENCE_GVMA_VMID_SENT,
+ [SBI_TLB_HFENCE_GVMA] = SBI_PMU_FW_HFENCE_GVMA_SENT,
+ [SBI_TLB_HFENCE_VVMA_ASID] = SBI_PMU_FW_HFENCE_VVMA_ASID_SENT,
+ [SBI_TLB_HFENCE_VVMA] = SBI_PMU_FW_HFENCE_VVMA_SENT,
+};
+
int sbi_tlb_request(ulong hmask, ulong hbase, struct sbi_tlb_info *tinfo)
{
- if (!tinfo->local_fn)
+ if (tinfo->type < 0 || tinfo->type >= SBI_TLB_TYPE_MAX)
return SBI_EINVAL;
/*
@@ -385,7 +406,7 @@ int sbi_tlb_request(ulong hmask, ulong hbase, struct sbi_tlb_info *tinfo)
tinfo->size = SBI_TLB_FLUSH_ALL;
}
- tlb_pmu_incr_fw_ctr(tinfo);
+ sbi_pmu_ctr_incr_fw(tlb_type_to_pmu_fw_event[tinfo->type]);
return sbi_ipi_send_many(hmask, hbase, tlb_event, tinfo);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/6] platform: generic: Fine tune fw_platform_calculate_heap_size()
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
2023-12-12 9:59 ` [PATCH v2 1/6] lib: sbi_tlb: Reduce size of struct sbi_tlb_info Anup Patel
@ 2023-12-12 9:59 ` Anup Patel
2023-12-12 9:59 ` [PATCH v2 3/6] lib: utils/irqchip: Add shared MMIO region for PLIC in root domain Anup Patel
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-12 9:59 UTC (permalink / raw)
To: opensbi
Let's use SBI_TLB_INFO_SIZE instead of hard-coded 0x40 in
fw_platform_calculate_heap_size() to fine tune the heap size
required for per-hart TLB fifos.
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
platform/generic/platform.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index 08ae92a..8507227 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -16,6 +16,7 @@
#include <sbi/sbi_platform.h>
#include <sbi/sbi_string.h>
#include <sbi/sbi_system.h>
+#include <sbi/sbi_tlb.h>
#include <sbi_utils/fdt/fdt_domain.h>
#include <sbi_utils/fdt/fdt_fixup.h>
#include <sbi_utils/fdt/fdt_helper.h>
@@ -63,7 +64,7 @@ static u32 fw_platform_calculate_heap_size(u32 hart_count)
heap_size = SBI_PLATFORM_DEFAULT_HEAP_SIZE(hart_count);
/* For TLB fifo */
- heap_size += 0x40 * (hart_count) * (hart_count);
+ heap_size += SBI_TLB_INFO_SIZE * (hart_count) * (hart_count);
return BIT_ALIGN(heap_size, HEAP_BASE_ALIGN);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/6] lib: utils/irqchip: Add shared MMIO region for PLIC in root domain
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
2023-12-12 9:59 ` [PATCH v2 1/6] lib: sbi_tlb: Reduce size of struct sbi_tlb_info Anup Patel
2023-12-12 9:59 ` [PATCH v2 2/6] platform: generic: Fine tune fw_platform_calculate_heap_size() Anup Patel
@ 2023-12-12 9:59 ` Anup Patel
2023-12-12 9:59 ` [PATCH v2 4/6] lib: sbi: Allow ecall handlers to directly update register state Anup Patel
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-12 9:59 UTC (permalink / raw)
To: opensbi
On platforms with Smepmp, the MMIO regions accessed by M-mode need
to be explicitly marked with M-mode only read/write or shared (both
(M-mode and S-mode) read/write permission.
If the above is not done then runtime PLIC access from M-mode on
platforms with Smepmp will result in access fault when further
results in CPU hotplug not working.
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
include/sbi_utils/irqchip/plic.h | 1 +
lib/utils/fdt/fdt_helper.c | 1 +
lib/utils/irqchip/plic.c | 6 +++++-
platform/fpga/ariane/platform.c | 3 +++
platform/fpga/openpiton/platform.c | 3 +++
platform/kendryte/k210/platform.c | 1 +
platform/kendryte/k210/platform.h | 1 +
platform/nuclei/ux600/platform.c | 3 +++
platform/template/platform.c | 3 +++
9 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/include/sbi_utils/irqchip/plic.h b/include/sbi_utils/irqchip/plic.h
index 112a714..2eda631 100644
--- a/include/sbi_utils/irqchip/plic.h
+++ b/include/sbi_utils/irqchip/plic.h
@@ -14,6 +14,7 @@
struct plic_data {
unsigned long addr;
+ unsigned long size;
unsigned long num_src;
};
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index 78c1f38..df74adb 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -878,6 +878,7 @@ int fdt_parse_plic_node(void *fdt, int nodeoffset, struct plic_data *plic)
if (rc < 0 || !reg_addr || !reg_size)
return SBI_ENODEV;
plic->addr = reg_addr;
+ plic->size = reg_size;
val = fdt_getprop(fdt, nodeoffset, "riscv,ndev", &len);
if (len > 0)
diff --git a/lib/utils/irqchip/plic.c b/lib/utils/irqchip/plic.c
index d633514..193e320 100644
--- a/lib/utils/irqchip/plic.c
+++ b/lib/utils/irqchip/plic.c
@@ -10,7 +10,9 @@
#include <sbi/riscv_io.h>
#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_bitops.h>
#include <sbi/sbi_console.h>
+#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_string.h>
#include <sbi_utils/irqchip/plic.h>
@@ -171,5 +173,7 @@ int plic_cold_irqchip_init(const struct plic_data *plic)
for (i = 1; i <= plic->num_src; i++)
plic_set_priority(plic, i, 0);
- return 0;
+ return sbi_domain_root_add_memrange(plic->addr, plic->size, BIT(20),
+ (SBI_DOMAIN_MEMREGION_MMIO |
+ SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW));
}
diff --git a/platform/fpga/ariane/platform.c b/platform/fpga/ariane/platform.c
index 975528f..8be5e6c 100644
--- a/platform/fpga/ariane/platform.c
+++ b/platform/fpga/ariane/platform.c
@@ -25,6 +25,8 @@
#define ARIANE_UART_REG_WIDTH 4
#define ARIANE_UART_REG_OFFSET 0
#define ARIANE_PLIC_ADDR 0xc000000
+#define ARIANE_PLIC_SIZE (0x200000 + \
+ (ARIANE_HART_COUNT * 0x1000))
#define ARIANE_PLIC_NUM_SOURCES 3
#define ARIANE_HART_COUNT 1
#define ARIANE_CLINT_ADDR 0x2000000
@@ -36,6 +38,7 @@
static struct plic_data plic = {
.addr = ARIANE_PLIC_ADDR,
+ .size = ARIANE_PLIC_SIZE,
.num_src = ARIANE_PLIC_NUM_SOURCES,
};
diff --git a/platform/fpga/openpiton/platform.c b/platform/fpga/openpiton/platform.c
index e59dc99..2317a89 100644
--- a/platform/fpga/openpiton/platform.c
+++ b/platform/fpga/openpiton/platform.c
@@ -24,6 +24,8 @@
#define OPENPITON_DEFAULT_UART_REG_WIDTH 1
#define OPENPITON_DEFAULT_UART_REG_OFFSET 0
#define OPENPITON_DEFAULT_PLIC_ADDR 0xfff1100000
+#define OPENPITON_DEFAULT_PLIC_SIZE (0x200000 + \
+ (OPENPITON_DEFAULT_HART_COUNT * 0x1000))
#define OPENPITON_DEFAULT_PLIC_NUM_SOURCES 2
#define OPENPITON_DEFAULT_HART_COUNT 3
#define OPENPITON_DEFAULT_CLINT_ADDR 0xfff1020000
@@ -40,6 +42,7 @@ static struct platform_uart_data uart = {
};
static struct plic_data plic = {
.addr = OPENPITON_DEFAULT_PLIC_ADDR,
+ .size = OPENPITON_DEFAULT_PLIC_SIZE,
.num_src = OPENPITON_DEFAULT_PLIC_NUM_SOURCES,
};
diff --git a/platform/kendryte/k210/platform.c b/platform/kendryte/k210/platform.c
index 637a217..27b23f7 100644
--- a/platform/kendryte/k210/platform.c
+++ b/platform/kendryte/k210/platform.c
@@ -32,6 +32,7 @@ unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
static struct plic_data plic = {
.addr = K210_PLIC_BASE_ADDR,
+ .size = K210_PLIC_BASE_SIZE,
.num_src = K210_PLIC_NUM_SOURCES,
};
diff --git a/platform/kendryte/k210/platform.h b/platform/kendryte/k210/platform.h
index be52aa3..9417403 100644
--- a/platform/kendryte/k210/platform.h
+++ b/platform/kendryte/k210/platform.h
@@ -27,6 +27,7 @@
#define K210_ACLINT_MTIMER_ADDR \
(K210_CLINT_BASE_ADDR + CLINT_MTIMER_OFFSET)
#define K210_PLIC_BASE_ADDR 0x0C000000ULL
+#define K210_PLIC_BASE_SIZE (0x200000ULL + (K210_HART_COUNT * 0x1000))
/* Registers */
#define K210_PLL0 0x08
diff --git a/platform/nuclei/ux600/platform.c b/platform/nuclei/ux600/platform.c
index 6fd6cd7..f688b50 100644
--- a/platform/nuclei/ux600/platform.c
+++ b/platform/nuclei/ux600/platform.c
@@ -39,6 +39,8 @@
CLINT_MTIMER_OFFSET)
#define UX600_PLIC_ADDR 0x8000000
+#define UX600_PLIC_SIZE (0x200000 + \
+ (UX600_HART_COUNT * 0x1000))
#define UX600_PLIC_NUM_SOURCES 0x35
#define UX600_PLIC_NUM_PRIORITIES 7
@@ -63,6 +65,7 @@ static u32 ux600_clk_freq = 8000000;
static struct plic_data plic = {
.addr = UX600_PLIC_ADDR,
+ .size = UX600_PLIC_SIZE,
.num_src = UX600_PLIC_NUM_SOURCES,
};
diff --git a/platform/template/platform.c b/platform/template/platform.c
index 86381ca..4b3f2ac 100644
--- a/platform/template/platform.c
+++ b/platform/template/platform.c
@@ -19,6 +19,8 @@
#include <sbi_utils/timer/aclint_mtimer.h>
#define PLATFORM_PLIC_ADDR 0xc000000
+#define PLATFORM_PLIC_SIZE (0x200000 + \
+ (PLATFORM_HART_COUNT * 0x1000))
#define PLATFORM_PLIC_NUM_SOURCES 128
#define PLATFORM_HART_COUNT 4
#define PLATFORM_CLINT_ADDR 0x2000000
@@ -33,6 +35,7 @@
static struct plic_data plic = {
.addr = PLATFORM_PLIC_ADDR,
+ .size = PLATFORM_PLIC_SIZE,
.num_src = PLATFORM_PLIC_NUM_SOURCES,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 4/6] lib: sbi: Allow ecall handlers to directly update register state
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
` (2 preceding siblings ...)
2023-12-12 9:59 ` [PATCH v2 3/6] lib: utils/irqchip: Add shared MMIO region for PLIC in root domain Anup Patel
@ 2023-12-12 9:59 ` Anup Patel
2023-12-12 9:59 ` [PATCH v2 5/6] lib: sbi: Remove the SBI_ETRAP error code Anup Patel
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-12 9:59 UTC (permalink / raw)
To: opensbi
Some of the upcoming SBI extensions (such as SSE) will directly
update register state so improve the prototype of ecall handler
to accommodate this. Further, this flexibility allows us to
push the trap redirection from sbi_ecall_handler() to the
sbi_ecall_legacy_handler().
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
include/sbi/sbi_ecall.h | 12 +++++--
include/sbi/sbi_platform.h | 19 ++++------
lib/sbi/sbi_ecall.c | 13 +++----
lib/sbi/sbi_ecall_base.c | 27 +++++++-------
lib/sbi/sbi_ecall_cppc.c | 13 ++++---
lib/sbi/sbi_ecall_dbcn.c | 9 +++--
lib/sbi/sbi_ecall_hsm.c | 7 ++--
lib/sbi/sbi_ecall_ipi.c | 5 ++-
lib/sbi/sbi_ecall_legacy.c | 37 +++++++++++++++-----
lib/sbi/sbi_ecall_pmu.c | 17 +++++----
lib/sbi/sbi_ecall_rfence.c | 5 ++-
lib/sbi/sbi_ecall_srst.c | 5 ++-
lib/sbi/sbi_ecall_susp.c | 7 ++--
lib/sbi/sbi_ecall_time.c | 5 ++-
lib/sbi/sbi_ecall_vendor.c | 8 ++---
platform/generic/andes/andes_sbi.c | 7 ++--
platform/generic/include/andes/andes_sbi.h | 6 ++--
platform/generic/include/platform_override.h | 6 ++--
platform/generic/platform.c | 8 ++---
19 files changed, 109 insertions(+), 107 deletions(-)
diff --git a/include/sbi/sbi_ecall.h b/include/sbi/sbi_ecall.h
index 027213c..0bf42d1 100644
--- a/include/sbi/sbi_ecall.h
+++ b/include/sbi/sbi_ecall.h
@@ -20,6 +20,13 @@
struct sbi_trap_regs;
struct sbi_trap_info;
+struct sbi_ecall_return {
+ /* Return flag to skip register update */
+ bool skip_regs_update;
+ /* Return value */
+ unsigned long value;
+};
+
struct sbi_ecall_extension {
/* head is used by the extension list */
struct sbi_dlist head;
@@ -62,9 +69,8 @@ struct sbi_ecall_extension {
* never invoked with an invalid or unavailable extension ID.
*/
int (* handle)(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap);
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out);
};
u16 sbi_ecall_version_major(void);
diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h
index 58b9069..2fb33e1 100644
--- a/include/sbi/sbi_platform.h
+++ b/include/sbi/sbi_platform.h
@@ -50,7 +50,7 @@
#include <sbi/sbi_version.h>
struct sbi_domain_memregion;
-struct sbi_trap_info;
+struct sbi_ecall_return;
struct sbi_trap_regs;
struct sbi_hart_features;
@@ -137,9 +137,8 @@ struct sbi_platform_operations {
bool (*vendor_ext_check)(void);
/** platform specific SBI extension implementation provider */
int (*vendor_ext_provider)(long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_value,
- struct sbi_trap_info *out_trap);
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out);
};
/** Platform default per-HART stack size for exception/interrupt handling */
@@ -666,16 +665,12 @@ static inline bool sbi_platform_vendor_ext_check(
static inline int sbi_platform_vendor_ext_provider(
const struct sbi_platform *plat,
long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_value,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
- if (plat && sbi_platform_ops(plat)->vendor_ext_provider) {
+ if (plat && sbi_platform_ops(plat)->vendor_ext_provider)
return sbi_platform_ops(plat)->vendor_ext_provider(funcid,
- regs,
- out_value,
- out_trap);
- }
+ regs, out);
return SBI_ENOTSUPP;
}
diff --git a/lib/sbi/sbi_ecall.c b/lib/sbi/sbi_ecall.c
index 3eb4f0a..631c5dd 100644
--- a/lib/sbi/sbi_ecall.c
+++ b/lib/sbi/sbi_ecall.c
@@ -101,14 +101,12 @@ int sbi_ecall_handler(struct sbi_trap_regs *regs)
struct sbi_ecall_extension *ext;
unsigned long extension_id = regs->a7;
unsigned long func_id = regs->a6;
- struct sbi_trap_info trap = {0};
- unsigned long out_val = 0;
+ struct sbi_ecall_return out = {0};
bool is_0_1_spec = 0;
ext = sbi_ecall_find_extension(extension_id);
if (ext && ext->handle) {
- ret = ext->handle(extension_id, func_id,
- regs, &out_val, &trap);
+ ret = ext->handle(extension_id, func_id, regs, &out);
if (extension_id >= SBI_EXT_0_1_SET_TIMER &&
extension_id <= SBI_EXT_0_1_SHUTDOWN)
is_0_1_spec = 1;
@@ -116,10 +114,7 @@ int sbi_ecall_handler(struct sbi_trap_regs *regs)
ret = SBI_ENOTSUPP;
}
- if (ret == SBI_ETRAP) {
- trap.epc = regs->mepc;
- sbi_trap_redirect(regs, &trap);
- } else {
+ if (!out.skip_regs_update) {
if (ret < SBI_LAST_ERR ||
(extension_id != SBI_EXT_0_1_CONSOLE_GETCHAR &&
SBI_SUCCESS < ret)) {
@@ -140,7 +135,7 @@ int sbi_ecall_handler(struct sbi_trap_regs *regs)
regs->mepc += 4;
regs->a0 = ret;
if (!is_0_1_spec)
- regs->a1 = out_val;
+ regs->a1 = out.value;
}
return 0;
diff --git a/lib/sbi/sbi_ecall_base.c b/lib/sbi/sbi_ecall_base.c
index 74f05eb..b7178ea 100644
--- a/lib/sbi/sbi_ecall_base.c
+++ b/lib/sbi/sbi_ecall_base.c
@@ -33,37 +33,36 @@ static int sbi_ecall_base_probe(unsigned long extid, unsigned long *out_val)
}
static int sbi_ecall_base_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
switch (funcid) {
case SBI_EXT_BASE_GET_SPEC_VERSION:
- *out_val = (SBI_ECALL_VERSION_MAJOR <<
- SBI_SPEC_VERSION_MAJOR_OFFSET) &
- (SBI_SPEC_VERSION_MAJOR_MASK <<
- SBI_SPEC_VERSION_MAJOR_OFFSET);
- *out_val = *out_val | SBI_ECALL_VERSION_MINOR;
+ out->value = (SBI_ECALL_VERSION_MAJOR <<
+ SBI_SPEC_VERSION_MAJOR_OFFSET) &
+ (SBI_SPEC_VERSION_MAJOR_MASK <<
+ SBI_SPEC_VERSION_MAJOR_OFFSET);
+ out->value = out->value | SBI_ECALL_VERSION_MINOR;
break;
case SBI_EXT_BASE_GET_IMP_ID:
- *out_val = sbi_ecall_get_impid();
+ out->value = sbi_ecall_get_impid();
break;
case SBI_EXT_BASE_GET_IMP_VERSION:
- *out_val = OPENSBI_VERSION;
+ out->value = OPENSBI_VERSION;
break;
case SBI_EXT_BASE_GET_MVENDORID:
- *out_val = csr_read(CSR_MVENDORID);
+ out->value = csr_read(CSR_MVENDORID);
break;
case SBI_EXT_BASE_GET_MARCHID:
- *out_val = csr_read(CSR_MARCHID);
+ out->value = csr_read(CSR_MARCHID);
break;
case SBI_EXT_BASE_GET_MIMPID:
- *out_val = csr_read(CSR_MIMPID);
+ out->value = csr_read(CSR_MIMPID);
break;
case SBI_EXT_BASE_PROBE_EXT:
- ret = sbi_ecall_base_probe(regs->a0, out_val);
+ ret = sbi_ecall_base_probe(regs->a0, &out->value);
break;
default:
ret = SBI_ENOTSUPP;
diff --git a/lib/sbi/sbi_ecall_cppc.c b/lib/sbi/sbi_ecall_cppc.c
index b54d54e..c26bb40 100644
--- a/lib/sbi/sbi_ecall_cppc.c
+++ b/lib/sbi/sbi_ecall_cppc.c
@@ -12,9 +12,8 @@
#include <sbi/sbi_cppc.h>
static int sbi_ecall_cppc_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
uint64_t temp;
@@ -22,14 +21,14 @@ static int sbi_ecall_cppc_handler(unsigned long extid, unsigned long funcid,
switch (funcid) {
case SBI_EXT_CPPC_READ:
ret = sbi_cppc_read(regs->a0, &temp);
- *out_val = temp;
+ out->value = temp;
break;
case SBI_EXT_CPPC_READ_HI:
#if __riscv_xlen == 32
ret = sbi_cppc_read(regs->a0, &temp);
- *out_val = temp >> 32;
+ out->value = temp >> 32;
#else
- *out_val = 0;
+ out->value = 0;
#endif
break;
case SBI_EXT_CPPC_WRITE:
@@ -38,7 +37,7 @@ static int sbi_ecall_cppc_handler(unsigned long extid, unsigned long funcid,
case SBI_EXT_CPPC_PROBE:
ret = sbi_cppc_probe(regs->a0);
if (ret >= 0) {
- *out_val = ret;
+ out->value = ret;
ret = 0;
}
break;
diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
index 18cd6c8..49a7713 100644
--- a/lib/sbi/sbi_ecall_dbcn.c
+++ b/lib/sbi/sbi_ecall_dbcn.c
@@ -17,9 +17,8 @@
#include <sbi/sbi_hart.h>
static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
ulong smode = (csr_read(CSR_MSTATUS) & MSTATUS_MPP) >>
MSTATUS_MPP_SHIFT;
@@ -49,9 +48,9 @@ static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
return SBI_ERR_INVALID_PARAM;
sbi_hart_map_saddr(regs->a1, regs->a0);
if (funcid == SBI_EXT_DBCN_CONSOLE_WRITE)
- *out_val = sbi_nputs((const char *)regs->a1, regs->a0);
+ out->value = sbi_nputs((const char *)regs->a1, regs->a0);
else
- *out_val = sbi_ngets((char *)regs->a1, regs->a0);
+ out->value = sbi_ngets((char *)regs->a1, regs->a0);
sbi_hart_unmap_saddr();
return 0;
case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
diff --git a/lib/sbi/sbi_ecall_hsm.c b/lib/sbi/sbi_ecall_hsm.c
index 20705c3..93170b0 100644
--- a/lib/sbi/sbi_ecall_hsm.c
+++ b/lib/sbi/sbi_ecall_hsm.c
@@ -17,9 +17,8 @@
#include <sbi/riscv_asm.h>
static int sbi_ecall_hsm_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
@@ -47,7 +46,7 @@ static int sbi_ecall_hsm_handler(unsigned long extid, unsigned long funcid,
}
if (ret >= 0) {
- *out_val = ret;
+ out->value = ret;
ret = 0;
}
diff --git a/lib/sbi/sbi_ecall_ipi.c b/lib/sbi/sbi_ecall_ipi.c
index a40d6b8..50ef41d 100644
--- a/lib/sbi/sbi_ecall_ipi.c
+++ b/lib/sbi/sbi_ecall_ipi.c
@@ -15,9 +15,8 @@
#include <sbi/sbi_ipi.h>
static int sbi_ecall_ipi_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
diff --git a/lib/sbi/sbi_ecall_legacy.c b/lib/sbi/sbi_ecall_legacy.c
index 556f629..48bd227 100644
--- a/lib/sbi/sbi_ecall_legacy.c
+++ b/lib/sbi/sbi_ecall_legacy.c
@@ -43,13 +43,13 @@ static int sbi_load_hart_mask_unpriv(ulong *pmask, ulong *hmask,
}
static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
struct sbi_tlb_info tlb_info;
u32 source_hart = current_hartid();
+ struct sbi_trap_info trap = {0};
ulong hmask = 0;
switch (extid) {
@@ -71,37 +71,58 @@ static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
break;
case SBI_EXT_0_1_SEND_IPI:
ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, out_trap);
- if (ret != SBI_ETRAP)
+ &hmask, &trap);
+ if (ret != SBI_ETRAP) {
ret = sbi_ipi_send_smode(hmask, 0);
+ } else {
+ ret = 0;
+ trap.epc = regs->mepc;
+ sbi_trap_redirect(regs, &trap);
+ out->skip_regs_update = true;
+ }
break;
case SBI_EXT_0_1_REMOTE_FENCE_I:
ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, out_trap);
+ &hmask, &trap);
if (ret != SBI_ETRAP) {
SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
SBI_TLB_FENCE_I, source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
+ } else {
+ ret = 0;
+ trap.epc = regs->mepc;
+ sbi_trap_redirect(regs, &trap);
+ out->skip_regs_update = true;
}
break;
case SBI_EXT_0_1_REMOTE_SFENCE_VMA:
ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, out_trap);
+ &hmask, &trap);
if (ret != SBI_ETRAP) {
SBI_TLB_INFO_INIT(&tlb_info, regs->a1, regs->a2, 0, 0,
SBI_TLB_SFENCE_VMA, source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
+ } else {
+ ret = 0;
+ trap.epc = regs->mepc;
+ sbi_trap_redirect(regs, &trap);
+ out->skip_regs_update = true;
}
break;
case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID:
ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, out_trap);
+ &hmask, &trap);
if (ret != SBI_ETRAP) {
SBI_TLB_INFO_INIT(&tlb_info, regs->a1,
regs->a2, regs->a3, 0,
SBI_TLB_SFENCE_VMA_ASID,
source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
+ } else {
+ ret = 0;
+ trap.epc = regs->mepc;
+ sbi_trap_redirect(regs, &trap);
+ out->skip_regs_update = true;
}
break;
case SBI_EXT_0_1_SHUTDOWN:
diff --git a/lib/sbi/sbi_ecall_pmu.c b/lib/sbi/sbi_ecall_pmu.c
index c585911..40a63a6 100644
--- a/lib/sbi/sbi_ecall_pmu.c
+++ b/lib/sbi/sbi_ecall_pmu.c
@@ -18,9 +18,8 @@
#include <sbi/riscv_asm.h>
static int sbi_ecall_pmu_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
uint64_t temp;
@@ -29,12 +28,12 @@ static int sbi_ecall_pmu_handler(unsigned long extid, unsigned long funcid,
case SBI_EXT_PMU_NUM_COUNTERS:
ret = sbi_pmu_num_ctr();
if (ret >= 0) {
- *out_val = ret;
+ out->value = ret;
ret = 0;
}
break;
case SBI_EXT_PMU_COUNTER_GET_INFO:
- ret = sbi_pmu_ctr_get_info(regs->a0, out_val);
+ ret = sbi_pmu_ctr_get_info(regs->a0, &out->value);
break;
case SBI_EXT_PMU_COUNTER_CFG_MATCH:
#if __riscv_xlen == 32
@@ -45,21 +44,21 @@ static int sbi_ecall_pmu_handler(unsigned long extid, unsigned long funcid,
ret = sbi_pmu_ctr_cfg_match(regs->a0, regs->a1, regs->a2,
regs->a3, temp);
if (ret >= 0) {
- *out_val = ret;
+ out->value = ret;
ret = 0;
}
break;
case SBI_EXT_PMU_COUNTER_FW_READ:
ret = sbi_pmu_ctr_fw_read(regs->a0, &temp);
- *out_val = temp;
+ out->value = temp;
break;
case SBI_EXT_PMU_COUNTER_FW_READ_HI:
#if __riscv_xlen == 32
ret = sbi_pmu_ctr_fw_read(regs->a0, &temp);
- *out_val = temp >> 32;
+ out->value = temp >> 32;
#else
- *out_val = 0;
+ out->value = 0;
#endif
break;
case SBI_EXT_PMU_COUNTER_START:
diff --git a/lib/sbi/sbi_ecall_rfence.c b/lib/sbi/sbi_ecall_rfence.c
index 4b74d41..ded16c2 100644
--- a/lib/sbi/sbi_ecall_rfence.c
+++ b/lib/sbi/sbi_ecall_rfence.c
@@ -16,9 +16,8 @@
#include <sbi/sbi_tlb.h>
static int sbi_ecall_rfence_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
unsigned long vmid;
diff --git a/lib/sbi/sbi_ecall_srst.c b/lib/sbi/sbi_ecall_srst.c
index dcd560d..46cfaca 100644
--- a/lib/sbi/sbi_ecall_srst.c
+++ b/lib/sbi/sbi_ecall_srst.c
@@ -15,9 +15,8 @@
#include <sbi/sbi_system.h>
static int sbi_ecall_srst_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
if (funcid == SBI_EXT_SRST_RESET) {
if ((((u32)-1U) <= ((u64)regs->a0)) ||
diff --git a/lib/sbi/sbi_ecall_susp.c b/lib/sbi/sbi_ecall_susp.c
index 2bfd99a..7b66bfc 100644
--- a/lib/sbi/sbi_ecall_susp.c
+++ b/lib/sbi/sbi_ecall_susp.c
@@ -6,9 +6,8 @@
#include <sbi/sbi_system.h>
static int sbi_ecall_susp_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = SBI_ENOTSUPP;
@@ -16,7 +15,7 @@ static int sbi_ecall_susp_handler(unsigned long extid, unsigned long funcid,
ret = sbi_system_suspend(regs->a0, regs->a1, regs->a2);
if (ret >= 0) {
- *out_val = ret;
+ out->value = ret;
ret = 0;
}
diff --git a/lib/sbi/sbi_ecall_time.c b/lib/sbi/sbi_ecall_time.c
index e79196f..5a2316e 100644
--- a/lib/sbi/sbi_ecall_time.c
+++ b/lib/sbi/sbi_ecall_time.c
@@ -15,9 +15,8 @@
#include <sbi/sbi_timer.h>
static int sbi_ecall_time_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
int ret = 0;
diff --git a/lib/sbi/sbi_ecall_vendor.c b/lib/sbi/sbi_ecall_vendor.c
index 700f475..ebebc58 100644
--- a/lib/sbi/sbi_ecall_vendor.c
+++ b/lib/sbi/sbi_ecall_vendor.c
@@ -23,13 +23,11 @@ static inline unsigned long sbi_ecall_vendor_id(void)
}
static int sbi_ecall_vendor_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
return sbi_platform_vendor_ext_provider(sbi_platform_thishart_ptr(),
- funcid, regs,
- out_val, out_trap);
+ funcid, regs, out);
}
struct sbi_ecall_extension ecall_vendor;
diff --git a/platform/generic/andes/andes_sbi.c b/platform/generic/andes/andes_sbi.c
index 3e89fb9..267c663 100644
--- a/platform/generic/andes/andes_sbi.c
+++ b/platform/generic/andes/andes_sbi.c
@@ -33,14 +33,13 @@ static bool andes45_apply_iocp_sw_workaround(void)
}
int andes_sbi_vendor_ext_provider(long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_value,
- struct sbi_trap_info *out_trap,
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out,
const struct fdt_match *match)
{
switch (funcid) {
case SBI_EXT_ANDES_IOCP_SW_WORKAROUND:
- *out_value = andes45_apply_iocp_sw_workaround();
+ out->value = andes45_apply_iocp_sw_workaround();
break;
default:
diff --git a/platform/generic/include/andes/andes_sbi.h b/platform/generic/include/andes/andes_sbi.h
index e5dc250..1288af8 100644
--- a/platform/generic/include/andes/andes_sbi.h
+++ b/platform/generic/include/andes/andes_sbi.h
@@ -3,13 +3,13 @@
#ifndef _RISCV_ANDES_SBI_H
#define _RISCV_ANDES_SBI_H
+#include <sbi/sbi_ecall.h>
#include <sbi/sbi_trap.h>
#include <sbi_utils/fdt/fdt_helper.h>
int andes_sbi_vendor_ext_provider(long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_value,
- struct sbi_trap_info *out_trap,
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out,
const struct fdt_match *match);
#endif /* _RISCV_ANDES_SBI_H */
diff --git a/platform/generic/include/platform_override.h b/platform/generic/include/platform_override.h
index f2a4327..b0585c2 100644
--- a/platform/generic/include/platform_override.h
+++ b/platform/generic/include/platform_override.h
@@ -10,6 +10,7 @@
#ifndef __PLATFORM_OVERRIDE_H__
#define __PLATFORM_OVERRIDE_H__
+#include <sbi/sbi_ecall.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_types.h>
#include <sbi/sbi_trap.h>
@@ -30,9 +31,8 @@ struct platform_override {
int (*pmu_init)(const struct fdt_match *match);
void (*fw_init)(void *fdt, const struct fdt_match *match);
int (*vendor_ext_provider)(long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_value,
- struct sbi_trap_info *out_trap,
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out,
const struct fdt_match *match);
};
diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index 8507227..bfd7d31 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -203,12 +203,10 @@ static bool generic_vendor_ext_check(void)
}
static int generic_vendor_ext_provider(long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_value,
- struct sbi_trap_info *out_trap)
+ struct sbi_trap_regs *regs,
+ struct sbi_ecall_return *out)
{
- return generic_plat->vendor_ext_provider(funcid, regs,
- out_value, out_trap,
+ return generic_plat->vendor_ext_provider(funcid, regs, out,
generic_plat_match);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 5/6] lib: sbi: Remove the SBI_ETRAP error code
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
` (3 preceding siblings ...)
2023-12-12 9:59 ` [PATCH v2 4/6] lib: sbi: Allow ecall handlers to directly update register state Anup Patel
@ 2023-12-12 9:59 ` Anup Patel
2023-12-12 9:59 ` [PATCH v2 6/6] lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1 Anup Patel
2023-12-19 13:54 ` [PATCH v2 0/6] Assorted improvements Anup Patel
6 siblings, 0 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-12 9:59 UTC (permalink / raw)
To: opensbi
The SBI_ETRAP error code was introduced only for doing trap
redirection in generic sbi_ecall_handler(). Now the trap
redirection is moved into sbi_ecall_legacy.c and SBI_ETRAP
error code is only used in this source file so let us remove
it.
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
include/sbi/sbi_error.h | 5 ++---
lib/sbi/sbi_ecall_legacy.c | 32 ++++++++++++--------------------
2 files changed, 14 insertions(+), 23 deletions(-)
diff --git a/include/sbi/sbi_error.h b/include/sbi/sbi_error.h
index 7f97506..a77e3f8 100644
--- a/include/sbi/sbi_error.h
+++ b/include/sbi/sbi_error.h
@@ -32,9 +32,8 @@
#define SBI_EILL -1004
#define SBI_ENOSPC -1005
#define SBI_ENOMEM -1006
-#define SBI_ETRAP -1007
-#define SBI_EUNKNOWN -1008
-#define SBI_ENOENT -1009
+#define SBI_EUNKNOWN -1007
+#define SBI_ENOENT -1008
/* clang-format on */
diff --git a/lib/sbi/sbi_ecall_legacy.c b/lib/sbi/sbi_ecall_legacy.c
index 48bd227..14913c9 100644
--- a/lib/sbi/sbi_ecall_legacy.c
+++ b/lib/sbi/sbi_ecall_legacy.c
@@ -24,22 +24,22 @@
#include <sbi/sbi_unpriv.h>
#include <sbi/sbi_hart.h>
-static int sbi_load_hart_mask_unpriv(ulong *pmask, ulong *hmask,
- struct sbi_trap_info *uptrap)
+static bool sbi_load_hart_mask_unpriv(ulong *pmask, ulong *hmask,
+ struct sbi_trap_info *uptrap)
{
ulong mask = 0;
if (pmask) {
mask = sbi_load_ulong(pmask, uptrap);
if (uptrap->cause)
- return SBI_ETRAP;
+ return false;
} else {
sbi_hsm_hart_interruptible_mask(sbi_domain_thishart_ptr(),
0, &mask);
}
*hmask = mask;
- return 0;
+ return true;
}
static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
@@ -70,56 +70,48 @@ static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
sbi_ipi_clear_smode();
break;
case SBI_EXT_0_1_SEND_IPI:
- ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, &trap);
- if (ret != SBI_ETRAP) {
+ if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
+ &hmask, &trap)) {
ret = sbi_ipi_send_smode(hmask, 0);
} else {
- ret = 0;
trap.epc = regs->mepc;
sbi_trap_redirect(regs, &trap);
out->skip_regs_update = true;
}
break;
case SBI_EXT_0_1_REMOTE_FENCE_I:
- ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, &trap);
- if (ret != SBI_ETRAP) {
+ if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
+ &hmask, &trap)) {
SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
SBI_TLB_FENCE_I, source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
} else {
- ret = 0;
trap.epc = regs->mepc;
sbi_trap_redirect(regs, &trap);
out->skip_regs_update = true;
}
break;
case SBI_EXT_0_1_REMOTE_SFENCE_VMA:
- ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, &trap);
- if (ret != SBI_ETRAP) {
+ if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
+ &hmask, &trap)) {
SBI_TLB_INFO_INIT(&tlb_info, regs->a1, regs->a2, 0, 0,
SBI_TLB_SFENCE_VMA, source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
} else {
- ret = 0;
trap.epc = regs->mepc;
sbi_trap_redirect(regs, &trap);
out->skip_regs_update = true;
}
break;
case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID:
- ret = sbi_load_hart_mask_unpriv((ulong *)regs->a0,
- &hmask, &trap);
- if (ret != SBI_ETRAP) {
+ if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
+ &hmask, &trap)) {
SBI_TLB_INFO_INIT(&tlb_info, regs->a1,
regs->a2, regs->a3, 0,
SBI_TLB_SFENCE_VMA_ASID,
source_hart);
ret = sbi_tlb_request(hmask, 0, &tlb_info);
} else {
- ret = 0;
trap.epc = regs->mepc;
sbi_trap_redirect(regs, &trap);
out->skip_regs_update = true;
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 6/6] lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
` (4 preceding siblings ...)
2023-12-12 9:59 ` [PATCH v2 5/6] lib: sbi: Remove the SBI_ETRAP error code Anup Patel
@ 2023-12-12 9:59 ` Anup Patel
2023-12-19 13:54 ` [PATCH v2 0/6] Assorted improvements Anup Patel
6 siblings, 0 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-12 9:59 UTC (permalink / raw)
To: opensbi
On platforms with Smepmp, the previous booting stage must enter
OpenSBI with mseccfg.MML == 0. This allows OpenSBI to configure
it's own M-mode only regions without depending on the previous
booting stage.
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
lib/sbi/sbi_hart.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 6acff37..16da38d 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -975,6 +975,16 @@ __pmp_skip:
/* Mark hart feature detection done */
hfeatures->detected = true;
+ /*
+ * On platforms with Smepmp, the previous booting stage must
+ * enter OpenSBI with mseccfg.MML == 0. This allows OpenSBI
+ * to configure it's own M-mode only regions without depending
+ * on the previous booting stage.
+ */
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMEPMP) &&
+ (csr_read(CSR_MSECCFG) & MSECCFG_MML))
+ return SBI_EILL;
+
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 0/6] Assorted improvements
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
` (5 preceding siblings ...)
2023-12-12 9:59 ` [PATCH v2 6/6] lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1 Anup Patel
@ 2023-12-19 13:54 ` Anup Patel
6 siblings, 0 replies; 8+ messages in thread
From: Anup Patel @ 2023-12-19 13:54 UTC (permalink / raw)
To: opensbi
On Tue, Dec 12, 2023 at 3:29?PM Anup Patel <apatel@ventanamicro.com> wrote:
>
> This series does various assorted improvements. The patch1 and patch2
> improve heap usage by reducing size of struct sbi_tlb_info. The patch3
> is fixes PLIC driver for use on platforms with Smepmp. The patch4 and
> patch5 improve ecall handlers.
>
> These patches can also be found the misc_imp_v2 branch at
> https://github.com/avpatel/opensbi.git
>
> Changes since v1:
> - Addressed Samuel's comment on PATCH1
> - Added new PATCH6 which enforces that previous booting stage does
> not enter OpenSBI with mseccfg.MML == 1 on platforms with Smepmp
>
> Anup Patel (6):
> lib: sbi_tlb: Reduce size of struct sbi_tlb_info
> platform: generic: Fine tune fw_platform_calculate_heap_size()
> lib: utils/irqchip: Add shared MMIO region for PLIC in root domain
> lib: sbi: Allow ecall handlers to directly update register state
> lib: sbi: Remove the SBI_ETRAP error code
> lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1
Applied this series to the riscv/opensbi repo.
Regards,
Anup
>
> include/sbi/sbi_ecall.h | 12 ++-
> include/sbi/sbi_error.h | 5 +-
> include/sbi/sbi_platform.h | 19 ++---
> include/sbi/sbi_tlb.h | 29 +++----
> include/sbi_utils/irqchip/plic.h | 1 +
> lib/sbi/sbi_ecall.c | 13 +---
> lib/sbi/sbi_ecall_base.c | 27 ++++---
> lib/sbi/sbi_ecall_cppc.c | 13 ++--
> lib/sbi/sbi_ecall_dbcn.c | 9 +--
> lib/sbi/sbi_ecall_hsm.c | 7 +-
> lib/sbi/sbi_ecall_ipi.c | 5 +-
> lib/sbi/sbi_ecall_legacy.c | 59 ++++++++------
> lib/sbi/sbi_ecall_pmu.c | 17 ++--
> lib/sbi/sbi_ecall_rfence.c | 21 +++--
> lib/sbi/sbi_ecall_srst.c | 5 +-
> lib/sbi/sbi_ecall_susp.c | 7 +-
> lib/sbi/sbi_ecall_time.c | 5 +-
> lib/sbi/sbi_ecall_vendor.c | 8 +-
> lib/sbi/sbi_hart.c | 10 +++
> lib/sbi/sbi_tlb.c | 81 ++++++++++++--------
> lib/utils/fdt/fdt_helper.c | 1 +
> lib/utils/irqchip/plic.c | 6 +-
> platform/fpga/ariane/platform.c | 3 +
> platform/fpga/openpiton/platform.c | 3 +
> platform/generic/andes/andes_sbi.c | 7 +-
> platform/generic/include/andes/andes_sbi.h | 6 +-
> platform/generic/include/platform_override.h | 6 +-
> platform/generic/platform.c | 11 ++-
> platform/kendryte/k210/platform.c | 1 +
> platform/kendryte/k210/platform.h | 1 +
> platform/nuclei/ux600/platform.c | 3 +
> platform/template/platform.c | 3 +
> 32 files changed, 224 insertions(+), 180 deletions(-)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-12-19 13:54 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-12 9:59 [PATCH v2 0/6] Assorted improvements Anup Patel
2023-12-12 9:59 ` [PATCH v2 1/6] lib: sbi_tlb: Reduce size of struct sbi_tlb_info Anup Patel
2023-12-12 9:59 ` [PATCH v2 2/6] platform: generic: Fine tune fw_platform_calculate_heap_size() Anup Patel
2023-12-12 9:59 ` [PATCH v2 3/6] lib: utils/irqchip: Add shared MMIO region for PLIC in root domain Anup Patel
2023-12-12 9:59 ` [PATCH v2 4/6] lib: sbi: Allow ecall handlers to directly update register state Anup Patel
2023-12-12 9:59 ` [PATCH v2 5/6] lib: sbi: Remove the SBI_ETRAP error code Anup Patel
2023-12-12 9:59 ` [PATCH v2 6/6] lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1 Anup Patel
2023-12-19 13:54 ` [PATCH v2 0/6] Assorted improvements Anup Patel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox