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