1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2020 Western Digital Corporation or its affiliates.
5  *
6  * Authors:
7  *   Anup Patel <anup.patel@wdc.com>
8  *   Atish Patra <atish.patra@wdc.com>
9  */
10 
11 #include <sbi/sbi_ecall.h>
12 #include <sbi/sbi_ecall_interface.h>
13 #include <sbi/sbi_error.h>
14 #include <sbi/sbi_trap.h>
15 #include <sbi/sbi_version.h>
16 #include <sbi/riscv_asm.h>
17 
sbi_ecall_base_probe(unsigned long extid,unsigned long * out_val)18 static int sbi_ecall_base_probe(unsigned long extid, unsigned long *out_val)
19 {
20 	struct sbi_ecall_extension *ext;
21 
22 	ext = sbi_ecall_find_extension(extid);
23 	if (!ext) {
24 		*out_val = 0;
25 		return 0;
26 	}
27 
28 	if (ext->probe)
29 		return ext->probe(extid, out_val);
30 
31 	*out_val = 1;
32 	return 0;
33 }
34 
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)35 static int sbi_ecall_base_handler(unsigned long extid, unsigned long funcid,
36 				  const struct sbi_trap_regs *regs,
37 				  unsigned long *out_val,
38 				  struct sbi_trap_info *out_trap)
39 {
40 	int ret = 0;
41 
42 	switch (funcid) {
43 	case SBI_EXT_BASE_GET_SPEC_VERSION:
44 		*out_val = (SBI_ECALL_VERSION_MAJOR <<
45 			   SBI_SPEC_VERSION_MAJOR_OFFSET) &
46 			   (SBI_SPEC_VERSION_MAJOR_MASK <<
47 			    SBI_SPEC_VERSION_MAJOR_OFFSET);
48 		*out_val = *out_val | SBI_ECALL_VERSION_MINOR;
49 		break;
50 	case SBI_EXT_BASE_GET_IMP_ID:
51 		*out_val = sbi_ecall_get_impid();
52 		break;
53 	case SBI_EXT_BASE_GET_IMP_VERSION:
54 		*out_val = OPENSBI_VERSION;
55 		break;
56 	case SBI_EXT_BASE_GET_MVENDORID:
57 		*out_val = csr_read(CSR_MVENDORID);
58 		break;
59 	case SBI_EXT_BASE_GET_MARCHID:
60 		*out_val = csr_read(CSR_MARCHID);
61 		break;
62 	case SBI_EXT_BASE_GET_MIMPID:
63 		*out_val = csr_read(CSR_MIMPID);
64 		break;
65 	case SBI_EXT_BASE_PROBE_EXT:
66 		ret = sbi_ecall_base_probe(regs->a0, out_val);
67 		break;
68 	default:
69 		ret = SBI_ENOTSUPP;
70 	}
71 
72 	return ret;
73 }
74 
75 struct sbi_ecall_extension ecall_base = {
76 	.extid_start = SBI_EXT_BASE,
77 	.extid_end = SBI_EXT_BASE,
78 	.handle = sbi_ecall_base_handler,
79 };
80