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_version.h>
15 #include <sbi/riscv_asm.h>
16 
sbi_ecall_base_probe(unsigned long extid,unsigned long * out_val)17 static int sbi_ecall_base_probe(unsigned long extid, unsigned long *out_val)
18 {
19 	struct sbi_ecall_extension *ext;
20 
21 	ext = sbi_ecall_find_extension(extid);
22 	if (!ext) {
23 		*out_val = 0;
24 		return 0;
25 	}
26 
27 	if (ext->probe)
28 		return ext->probe(extid, out_val);
29 
30 	*out_val = 1;
31 	return 0;
32 }
33 
sbi_ecall_base_handler(unsigned long extid,unsigned long funcid,unsigned long * args,unsigned long * out_val,struct sbi_trap_info * out_trap)34 static int sbi_ecall_base_handler(unsigned long extid, unsigned long funcid,
35 				  unsigned long *args, unsigned long *out_val,
36 				  struct sbi_trap_info *out_trap)
37 {
38 	int ret = 0;
39 
40 	switch (funcid) {
41 	case SBI_EXT_BASE_GET_SPEC_VERSION:
42 		*out_val = (SBI_ECALL_VERSION_MAJOR <<
43 			   SBI_SPEC_VERSION_MAJOR_OFFSET) &
44 			   (SBI_SPEC_VERSION_MAJOR_MASK <<
45 			    SBI_SPEC_VERSION_MAJOR_OFFSET);
46 		*out_val = *out_val | SBI_ECALL_VERSION_MINOR;
47 		break;
48 	case SBI_EXT_BASE_GET_IMP_ID:
49 		*out_val = sbi_ecall_get_impid();
50 		break;
51 	case SBI_EXT_BASE_GET_IMP_VERSION:
52 		*out_val = OPENSBI_VERSION;
53 		break;
54 	case SBI_EXT_BASE_GET_MVENDORID:
55 		*out_val = csr_read(CSR_MVENDORID);
56 		break;
57 	case SBI_EXT_BASE_GET_MARCHID:
58 		*out_val = csr_read(CSR_MARCHID);
59 		break;
60 	case SBI_EXT_BASE_GET_MIMPID:
61 		*out_val = csr_read(CSR_MIMPID);
62 		break;
63 	case SBI_EXT_BASE_PROBE_EXT:
64 		ret = sbi_ecall_base_probe(args[0], out_val);
65 		break;
66 	default:
67 		ret = SBI_ENOTSUPP;
68 	}
69 
70 	return ret;
71 }
72 
73 struct sbi_ecall_extension ecall_base = {
74 	.extid_start = SBI_EXT_BASE,
75 	.extid_end = SBI_EXT_BASE,
76 	.handle = sbi_ecall_base_handler,
77 };
78