blob: 51b48f1b8e85e5e1b655718fe6410f0f331f2260 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
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 <stdbool.h>
10
11/*
12 * Status codes which can be returned from RMM commands.
13 *
14 * For each code, the meaning of return_code_t::index is stated.
15 */
16typedef enum {
17 /*
18 * Command completed successfully.
19 *
20 * index is zero.
21 */
22 RMI_SUCCESS = 0,
23
24 /*
25 * The value of a command input value caused the command to fail.
26 *
27 * index is zero.
28 */
29 RMI_ERROR_INPUT = 1,
30
31 /*
32 * An attribute of a Realm does not match the expected value.
33 *
34 * index varies between usages.
35 */
36 RMI_ERROR_REALM = 2,
37
38 /*
39 * An attribute of a REC does not match the expected value.
40 *
41 * index is zero.
42 */
43 RMI_ERROR_REC = 3,
44
45 /*
46 * An RTT walk terminated before reaching the target RTT level,
47 * or reached an RTTE with an unexpected value.
48 *
49 * index: RTT level at which the walk terminated
50 */
51 RMI_ERROR_RTT = 4,
52
53 /*
54 * An operation cannot be completed because a resource is in use.
55 *
56 * index is zero.
57 */
58 RMI_ERROR_IN_USE = 5,
59
60 RMI_ERROR_COUNT
61} status_t;
62
63/*
64 * Logical representation of return code returned by RMM commands.
65 * Each failure mode of a given command should return a unique return code, so
66 * that the caller can use it to unambiguously identify the failure mode. To
67 * avoid having a very large list of enumerated values, the return code is
68 * composed of a status which identifies the category of the error (for example,
69 * an address was misaligned), and an index which disambiguates between multiple
70 * similar failure modes (for example, a command may take multiple addresses as
71 * its input; the index identifies _which_ of them was misaligned.)
72 */
73typedef struct {
74 status_t status;
75 unsigned int index;
76} return_code_t;
77
78/*
79 * Convenience function for creating a return_code_t.
80 */
81static inline return_code_t make_return_code(unsigned int status,
82 unsigned int index)
83{
84 return (return_code_t) {status, index};
85}
86
87/*
88 * Pack a return_code_t into a binary format, suitable for storing in a
89 * register before exit from the RMM.
90 */
91static inline unsigned long pack_struct_return_code(return_code_t return_code)
92{
93 return (unsigned long)(return_code.status | (return_code.index << 8));
94}
95
96/*
97 * Pack a return code into a binary format, suitable for storing in a register
98 * on exit from the RMM.
99 */
100static inline unsigned long pack_return_code(unsigned int status, unsigned int index)
101{
102 /* The width of @status and @index is 8 bits */
103 assert((status <= 0xffU) && (index <= 0xffU));
104 return pack_struct_return_code(make_return_code(status, index));
105}
106
107/*
108 * Unpacks a return code.
109 */
110static inline return_code_t unpack_return_code(unsigned long error_code)
111{
112 return make_return_code(error_code & 0xffU, error_code >> 8);
113}
114
115#define MAX_ERR 4095
116
117/*
118 * Cast a status value to a pointer.
119 */
120static inline void *status_ptr(status_t status)
121{
122 return (void *)(-1 * (unsigned long)status);
123}
124
125/*
126 * Check whether a pointer value represents an error.
127 */
128static inline bool ptr_is_err(const void *ptr)
129{
130 return (unsigned long)ptr >= (unsigned long)(-MAX_ERR);
131}
132
133/*
134 * Cast a pointer to a status value.
135 */
136static inline status_t ptr_status(const void *ptr)
137{
138 return (status_t)(-1 * (unsigned long)ptr);
139}
140
141#endif /* STATUS_H */