1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #ifndef STATUS_H
7 #define STATUS_H
8 
9 #include <assert.h>
10 #include <smc-rmi.h>
11 
12 /*
13  * Logical representation of return code returned by RMM commands.
14  * Each failure mode of a given command should return a unique return code, so
15  * that the caller can use it to unambiguously identify the failure mode.  To
16  * avoid having a very large list of enumerated values, the return code is
17  * composed of a status which identifies the category of the error (for example,
18  * an address was misaligned), and an index which disambiguates between multiple
19  * similar failure modes (for example, a command may take multiple addresses as
20  * its input; the index identifies _which_ of them was misaligned).
21  *
22  * Refer to smc-rmi.h for status error codes and their meanings.
23  */
24 typedef struct {
25 	unsigned int status;
26 	unsigned int index;
27 } return_code_t;
28 
29 /*
30  * Convenience function for creating a return_code_t.
31  */
make_return_code(unsigned int status,unsigned int index)32 static inline return_code_t make_return_code(unsigned int status,
33 					     unsigned int index)
34 {
35 	return (return_code_t){status, index};
36 }
37 
38 /*
39  * Pack a return_code_t into a binary format, suitable for storing in a
40  * register before exit from the RMM.
41  */
pack_struct_return_code(return_code_t return_code)42 static inline unsigned long pack_struct_return_code(return_code_t return_code)
43 {
44 	return ((unsigned long)(return_code.index) << 8) | return_code.status;
45 }
46 
47 /*
48  * Pack a return code into a binary format, suitable for storing in a register
49  * on exit from the RMM.
50  */
pack_return_code(unsigned int status,unsigned char index)51 static inline unsigned long pack_return_code(unsigned int status,
52 					     unsigned char index)
53 {
54 	assert(status < RMI_ERROR_COUNT_MAX);
55 
56 	/* The width of @status and @index is 8 bits */
57 	return pack_struct_return_code(make_return_code(status, index));
58 }
59 
60 /*
61  * Unpacks a return code.
62  */
unpack_return_code(unsigned long error_code)63 static inline return_code_t unpack_return_code(unsigned long error_code)
64 {
65 	return make_return_code((unsigned int)error_code & 0xffU,
66 				(unsigned int)error_code >> 8);
67 }
68 
69 #define MAX_ERR 4095
70 
71 #endif /* STATUS_H */
72