lib: Factor-out SBI legacy extension
authorAnup Patel <anup.patel@wdc.com>
Fri, 17 Jan 2020 12:39:49 +0000 (18:09 +0530)
committerAnup Patel <anup@brainfault.org>
Wed, 22 Jan 2020 06:43:40 +0000 (12:13 +0530)
This patch factor-out SBI legacy extension into its own source
for better modularity of SBI implementation.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
include/sbi/sbi_ecall.h
lib/sbi/objects.mk
lib/sbi/sbi_ecall.c
lib/sbi/sbi_ecall_legacy.c [new file with mode: 0644]

index e9a9ef6..a7360b3 100644 (file)
@@ -29,6 +29,8 @@ struct sbi_ecall_extension {
                       struct sbi_trap_info *out_trap);
 };
 
+extern struct sbi_ecall_extension ecall_legacy;
+
 u16 sbi_ecall_version_major(void);
 
 u16 sbi_ecall_version_minor(void);
index b84453e..6a610b5 100644 (file)
@@ -14,6 +14,7 @@ libsbi-objs-y += riscv_locks.o
 
 libsbi-objs-y += sbi_console.o
 libsbi-objs-y += sbi_ecall.o
+libsbi-objs-y += sbi_ecall_legacy.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hfence.o
index 1c49d79..23a6c82 100644 (file)
@@ -7,20 +7,16 @@
  *   Anup Patel <anup.patel@wdc.com>
  */
 
-#include <sbi/sbi_console.h>
 #include <sbi/sbi_ecall.h>
 #include <sbi/sbi_ecall_interface.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_ipi.h>
 #include <sbi/sbi_platform.h>
-#include <sbi/sbi_system.h>
 #include <sbi/sbi_timer.h>
 #include <sbi/sbi_tlb.h>
 #include <sbi/sbi_trap.h>
-#include <sbi/sbi_unpriv.h>
 #include <sbi/sbi_hart.h>
 #include <sbi/sbi_version.h>
-#include <sbi/riscv_asm.h>
 
 #define SBI_ECALL_VERSION_MAJOR 0
 #define SBI_ECALL_VERSION_MINOR 2
@@ -36,22 +32,6 @@ u16 sbi_ecall_version_minor(void)
        return SBI_ECALL_VERSION_MINOR;
 }
 
-static int sbi_load_hart_mask_unpriv(struct sbi_scratch *scratch, ulong *pmask,
-                                    ulong *hmask, struct sbi_trap_info *uptrap)
-{
-       ulong mask = 0;
-
-       if (pmask) {
-               mask = sbi_load_ulong(pmask, scratch, uptrap);
-               if (uptrap->cause)
-                       return SBI_ETRAP;
-       } else {
-               mask = sbi_hart_available_mask();
-       }
-       *hmask = mask;
-       return 0;
-}
-
 static int sbi_ecall_base_probe(struct sbi_scratch *scratch,
                                unsigned long extid,
                                unsigned long *out_val)
@@ -245,87 +225,6 @@ static struct sbi_ecall_extension ecall_rfence = {
        .handle = sbi_ecall_rfence_handler,
 };
 
-static int sbi_ecall_0_1_handler(struct sbi_scratch *scratch,
-                                unsigned long extid, unsigned long funcid,
-                                unsigned long *args, unsigned long *out_val,
-                                struct sbi_trap_info *out_trap)
-{
-       int ret = 0;
-       struct sbi_tlb_info tlb_info;
-       u32 source_hart = sbi_current_hartid();
-       ulong hmask = 0;
-
-       switch (extid) {
-       case SBI_EXT_0_1_SET_TIMER:
-#if __riscv_xlen == 32
-               sbi_timer_event_start(scratch,
-                                     (((u64)args[1] << 32) | (u64)args[0]));
-#else
-               sbi_timer_event_start(scratch, (u64)args[0]);
-#endif
-               break;
-       case SBI_EXT_0_1_CONSOLE_PUTCHAR:
-               sbi_putc(args[0]);
-               break;
-       case SBI_EXT_0_1_CONSOLE_GETCHAR:
-               ret = sbi_getc();
-               break;
-       case SBI_EXT_0_1_CLEAR_IPI:
-               sbi_ipi_clear_smode(scratch);
-               break;
-       case SBI_EXT_0_1_SEND_IPI:
-               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
-                                               &hmask, out_trap);
-               if (ret != SBI_ETRAP)
-                       ret = sbi_ipi_send_smode(scratch, hmask, 0);
-               break;
-       case SBI_EXT_0_1_REMOTE_FENCE_I:
-               tlb_info.start  = 0;
-               tlb_info.size  = 0;
-               tlb_info.type  = SBI_ITLB_FLUSH;
-               tlb_info.shart_mask = 1UL << source_hart;
-               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
-                                               &hmask, out_trap);
-               if (ret != SBI_ETRAP)
-                       ret = sbi_tlb_request(scratch, hmask, 0, &tlb_info);
-               break;
-       case SBI_EXT_0_1_REMOTE_SFENCE_VMA:
-               tlb_info.start = (unsigned long)args[1];
-               tlb_info.size  = (unsigned long)args[2];
-               tlb_info.type  = SBI_TLB_FLUSH_VMA;
-               tlb_info.shart_mask = 1UL << source_hart;
-               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
-                                               &hmask, out_trap);
-               if (ret != SBI_ETRAP)
-                       ret = sbi_tlb_request(scratch, hmask, 0, &tlb_info);
-               break;
-       case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID:
-               tlb_info.start = (unsigned long)args[1];
-               tlb_info.size  = (unsigned long)args[2];
-               tlb_info.asid  = (unsigned long)args[3];
-               tlb_info.type  = SBI_TLB_FLUSH_VMA_ASID;
-               tlb_info.shart_mask = 1UL << source_hart;
-               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
-                                               &hmask, out_trap);
-               if (ret != SBI_ETRAP)
-                       ret = sbi_tlb_request(scratch, hmask, 0, &tlb_info);
-               break;
-       case SBI_EXT_0_1_SHUTDOWN:
-               sbi_system_shutdown(scratch, 0);
-               break;
-       default:
-               ret = SBI_ENOTSUPP;
-       };
-
-       return ret;
-}
-
-static struct sbi_ecall_extension ecall_0_1 = {
-       .extid_start = SBI_EXT_0_1_SET_TIMER,
-       .extid_end = SBI_EXT_0_1_SHUTDOWN,
-       .handle = sbi_ecall_0_1_handler,
-};
-
 static int sbi_ecall_vendor_probe(struct sbi_scratch *scratch,
                                  unsigned long extid,
                                  unsigned long *out_val)
@@ -468,7 +367,7 @@ int sbi_ecall_init(void)
        ret = sbi_ecall_register_extension(&ecall_base);
        if (ret)
                return ret;
-       ret = sbi_ecall_register_extension(&ecall_0_1);
+       ret = sbi_ecall_register_extension(&ecall_legacy);
        if (ret)
                return ret;
        ret = sbi_ecall_register_extension(&ecall_vendor);
diff --git a/lib/sbi/sbi_ecall_legacy.c b/lib/sbi/sbi_ecall_legacy.c
new file mode 100644 (file)
index 0000000..1150d7a
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ *   Anup Patel <anup.patel@wdc.com>
+ *   Atish Patra <atish.patra@wdc.com>
+ */
+
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_ecall.h>
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_ipi.h>
+#include <sbi/sbi_system.h>
+#include <sbi/sbi_timer.h>
+#include <sbi/sbi_tlb.h>
+#include <sbi/sbi_trap.h>
+#include <sbi/sbi_unpriv.h>
+#include <sbi/sbi_hart.h>
+
+static int sbi_load_hart_mask_unpriv(struct sbi_scratch *scratch,
+                                    ulong *pmask, ulong *hmask,
+                                    struct sbi_trap_info *uptrap)
+{
+       ulong mask = 0;
+
+       if (pmask) {
+               mask = sbi_load_ulong(pmask, scratch, uptrap);
+               if (uptrap->cause)
+                       return SBI_ETRAP;
+       } else {
+               mask = sbi_hart_available_mask();
+       }
+       *hmask = mask;
+       return 0;
+}
+
+static int sbi_ecall_legacy_handler(struct sbi_scratch *scratch,
+                                   unsigned long extid, unsigned long funcid,
+                                   unsigned long *args, unsigned long *out_val,
+                                   struct sbi_trap_info *out_trap)
+{
+       int ret = 0;
+       struct sbi_tlb_info tlb_info;
+       u32 source_hart = sbi_current_hartid();
+       ulong hmask = 0;
+
+       switch (extid) {
+       case SBI_EXT_0_1_SET_TIMER:
+#if __riscv_xlen == 32
+               sbi_timer_event_start(scratch,
+                                     (((u64)args[1] << 32) | (u64)args[0]));
+#else
+               sbi_timer_event_start(scratch, (u64)args[0]);
+#endif
+               break;
+       case SBI_EXT_0_1_CONSOLE_PUTCHAR:
+               sbi_putc(args[0]);
+               break;
+       case SBI_EXT_0_1_CONSOLE_GETCHAR:
+               ret = sbi_getc();
+               break;
+       case SBI_EXT_0_1_CLEAR_IPI:
+               sbi_ipi_clear_smode(scratch);
+               break;
+       case SBI_EXT_0_1_SEND_IPI:
+               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
+                                               &hmask, out_trap);
+               if (ret != SBI_ETRAP)
+                       ret = sbi_ipi_send_smode(scratch, hmask, 0);
+               break;
+       case SBI_EXT_0_1_REMOTE_FENCE_I:
+               tlb_info.start  = 0;
+               tlb_info.size  = 0;
+               tlb_info.type  = SBI_ITLB_FLUSH;
+               tlb_info.shart_mask = 1UL << source_hart;
+               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
+                                               &hmask, out_trap);
+               if (ret != SBI_ETRAP)
+                       ret = sbi_tlb_request(scratch, hmask, 0, &tlb_info);
+               break;
+       case SBI_EXT_0_1_REMOTE_SFENCE_VMA:
+               tlb_info.start = (unsigned long)args[1];
+               tlb_info.size  = (unsigned long)args[2];
+               tlb_info.type  = SBI_TLB_FLUSH_VMA;
+               tlb_info.shart_mask = 1UL << source_hart;
+               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
+                                               &hmask, out_trap);
+               if (ret != SBI_ETRAP)
+                       ret = sbi_tlb_request(scratch, hmask, 0, &tlb_info);
+               break;
+       case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID:
+               tlb_info.start = (unsigned long)args[1];
+               tlb_info.size  = (unsigned long)args[2];
+               tlb_info.asid  = (unsigned long)args[3];
+               tlb_info.type  = SBI_TLB_FLUSH_VMA_ASID;
+               tlb_info.shart_mask = 1UL << source_hart;
+               ret = sbi_load_hart_mask_unpriv(scratch, (ulong *)args[0],
+                                               &hmask, out_trap);
+               if (ret != SBI_ETRAP)
+                       ret = sbi_tlb_request(scratch, hmask, 0, &tlb_info);
+               break;
+       case SBI_EXT_0_1_SHUTDOWN:
+               sbi_system_shutdown(scratch, 0);
+               break;
+       default:
+               ret = SBI_ENOTSUPP;
+       };
+
+       return ret;
+}
+
+struct sbi_ecall_extension ecall_legacy = {
+       .extid_start = SBI_EXT_0_1_SET_TIMER,
+       .extid_end = SBI_EXT_0_1_SHUTDOWN,
+       .handle = sbi_ecall_legacy_handler,
+};