• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef __CROS_EC_INCLUDE_APPLICATION_H
17 #define __CROS_EC_INCLUDE_APPLICATION_H
18 #include <stdint.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #ifndef __packed
25 #define __packed __attribute__((packed))
26 #endif
27 
28 typedef const void * const __private;
29 
30 /*
31  * Typical applications are independent tasks which are directed (or at least
32  * influenced) by some off-chip program. Communications with the applications
33  * are initiated by that off-chip Master and are routed to the application
34  * using a variety of methods.
35  */
36 
37 /****************************************************************************/
38 /*
39  * Datagram API:
40  *
41  * Nugget OS abstracts the bus protocol (SPI, USB, whatever) into two
42  * unidirectional "datagram" transactions:
43  *
44  * - Read (the master wants data from the application)
45  * - Write (the master sends data to the application)
46  *
47  * Each transaction consists of a four-byte Command from the Master, plus zero
48  * or more data bytes either to (Read) or from (Write) the Master.
49  *
50  * The Command indicates the direction of data transfer, the application it
51  * addresses, and various other parameters. The application is responsible for
52  * providing (Read) or accepting (Write) the data bytes.
53  *
54  * Note: This interface was first used on the SPI bus, which allows for
55  * simultaneous bidirectional data transfer. We limit this interface to
56  * unidirectional transfers, because none of the other buses support that
57  * feature.
58  */
59 
60 /****************************************************************************/
61 /* Application IDs */
62 
63 /* These two App IDs shouldn't be changed or used for other purposes */
64 #define APP_ID_NUGGET            0x00    /* because we're selfish */
65 #define APP_ID_TPM_REGISTER_API  0xD4    /* mandated by the TCG */
66 /*
67  * Other App IDs are defined here. It will help avoid confusion if you use only
68  * the values from here and don't change them once they're set. But it's up to
69  * you. I'm a comment, not a cop.
70  */
71 #define APP_ID_AVB               0x01
72 #define APP_ID_KEYMASTER         0x02
73 #define APP_ID_WEAVER            0x03
74 #define APP_ID_PROTOBUF          0x04
75 
76 /* Fake apps used only for testing */
77 #define APP_ID_AVB_TEST          0x11
78 
79 /* This app ID should only be used by tests. */
80 #define APP_ID_TEST              0xff
81 
82 /****************************************************************************/
83 /* Other command fields */
84 
85 /*
86  * The Command encoding is:
87  *
88  *   Bits 31-24   Control flags (reserved)
89  *   Bits 23-16   Application ID
90  *   Bits 15-0    Parameters (application-specific)
91  */
92 
93 /* Control flag bits */
94 #define CMD_IS_READ       0x80000000    /* 1=Read, 0=Write */
95 /* All other control flags bits are reserved */
96 
97 /* Extracting fields from a command */
98 #define GET_APP_ID(cmd)     (((cmd) & 0x00ff0000) >> 16)
99 #define GET_APP_PARAM(cmd)  ((cmd) & 0x0000ffff)
100 
101 /* Specifying command fields */
102 #define CMD_ID(id)       (((id) & 0x000000ff) << 16)
103 #define CMD_PARAM(p)     ((p) & 0x0000ffff)
104 #define CMD_SET_PARAM(cmd, p) cmd = ((cmd & 0xffff0000) | (p & 0x0000ffff))
105 
106 /****************************************************************************/
107 /* Data transfer */
108 
109 /*
110  * Functions of this type are invoked when the Master wants to read bytes from
111  * an application. The app should parse the Command, copy up to max_tx_size
112  * bytes into the tx_buffer provided, and return the number of bytes to send
113  * back to the Master.
114  *
115  * This is called in interrupt context, so act quickly.
116  *
117  * The last arg is for internal use. Just ignore it.
118  */
119 typedef uint32_t (read_from_app_fn_t)(uint32_t command,
120                                       uint8_t *tx_buffer,
121                                       uint32_t max_tx_bytes,
122                                       __private priv);
123 
124 /*
125  * Functions of this type are invoked when the Master has sent bytes to the
126  * application. The app should parse the Command and copy or process the
127  * expected number of bytes in the rx_buffer that the master has sent, up to
128  * rx_num_bytes.
129  *
130  * NOTE: Due to a quirk of the Citadel hardware, up to four extra bytes from
131  * the *next* transaction may be at the end of the rx_buffer. The application
132  * should only poke at the bytes it expects to see and ignore any extras.
133  *
134  * This is called in interrupt context, so act quickly.
135  *
136  * The last arg is for internal use. Just ignore it.
137  */
138 typedef void (write_to_app_fn_t)(uint32_t command,
139                                  const uint8_t *rx_buffer,
140                                  uint32_t num_rx_bytes,
141                                  __private priv);
142 
143 /*
144  * For apps that run asynchronously with little oversight, occasional
145  * Read/Write operations may be all that's necessary. An app that intercepts
146  * button presses, an accelerometer, or a fingerprint scanner can simply be
147  * told to start or stop and will send interrupts to the Master when its
148  * attention is required.
149  *
150  * Applications are free to define their own protcols and APIs using only the
151  * functions and constants above (and at least one app does just that).
152  *
153  * An app that wishes to handle its messaging using only the components
154  * described to this point would use the following macro to declare itself.
155  */
156 
157 /**
158  * This registers an application that communicates using the Datagram API,
159  * which deals only with the raw byte streams between Master (AP) and Slave
160  * (application).
161  *
162  * The name and version values may be exported to the Master by Nugget OS, so
163  * the Master can query what applications are available without blindly trying
164  * them all to see what works.
165  *
166  * @param  Id        The Application ID, defined above
167  * @param  Name      A human-readable string identifying the application
168  * @param  Version   An app-specific uint32_t number, for compability purposes
169  * @param  From_fn   A pointer to the app's read_from_app_fnt_t handler
170  * @param  To_fn     A pointer to the app's write_to_app_fn_t handler
171  */
172 #define DECLARE_APPLICATION_DATAGRAM(Id, Name, Version, From_fn, To_fn) \
173     const struct app_info __keep CONCAT2(app_, Id)                      \
174       __attribute__((section(".rodata.app_info")))                      \
175       = { .api = { .id = Id,                                            \
176              .from_fn = From_fn, .to_fn = To_fn},                       \
177           .version = Version, .name = Name }
178 
179 /****************************************************************************/
180 /* Transport API */
181 /*
182  * Rather than handle unidirectonal datagrams themselves, many applications
183  * want to implement a request/response behavior, where the Master tells the
184  * app to do something and waits for it to finish and return the result.
185  *
186  * Seen from the AP's side, the application would be invoked using a blocking
187  * function something like this:
188  *
189  *   uint32_t call_application(uint8_t app_id, uint16_t app_param,
190  *                             const uint8_t *args, uint16_t arg_len,
191  *                             uint8_t *reply, uint16_t *reply_len);
192  *
193  * The request or response may be larger than one bus transaction, and the AP
194  * may poll until the app finishes or wait for an interrupt before retrieving
195  * the reply (there's no difference from app's point of view).
196  *
197  * With this API, the application is initially idle. Nugget OS will marshall
198  * all the input from the Master before waking the application. The Application
199  * then performs the requested operation and transititions to a "done" state.
200  * The Master will retrieve the application status and any reply data from
201  * Nugget OS, after which the application is ready to handle the next command.
202  *
203  * Applications that wish to use this transport API will need to declare a
204  * private struct app_transport which Nugget OS can use to maintain the state:
205  */
206 
207 struct app_transport {
208   uint32_t command;                           /* from master */
209   volatile uint32_t status;                   /* current application status */
210   uint8_t *request, *response;                /* input/output data buffer */
211   uint16_t max_request_len, max_response_len; /* data buffer sizes */
212   uint16_t request_len, response_len;         /* current buffer count */
213   uint16_t request_idx, response_idx;         /* used internally */
214   void (*done_fn)(struct app_transport *);    /* optional cleanup function */
215   /* Note: Any done_fn() is called in interrupt context. Be quick. */
216 };
217 
218 /*
219  * TODO(b/66104849): Note that request and response buffers are transferred as
220  * byte streams. However, if they will eventually represent structs, the usual
221  * ABI alignment requirements will be required. Until we've declared all
222  * applications structs in a union, we will need to align the buffers manually.
223  * Use this to declare the uint8_t buffers until then:
224  */
225 #define __TRANSPORT_ALIGNED__ __attribute__((aligned(8)))
226 
227 /* For debugging if needed */
228 extern void dump_transport_state(const struct app_transport *s);
229 
230 /*
231  * The application will need to provide a write_to_app_fn_t function that will
232  * be invoked when a new request is ready to be processed. All command and data
233  * parameters will already be present in the app's struct app_transport, so it
234  * just needs to awaken the application task to do the work.
235  *
236  * When processing is finished, the app should call the app_reply() function to
237  * return its status code and specify length of any data it has placed into the
238  * response buffer, and then it can go back to sleep until its next invocation.
239  */
240 void app_reply(struct app_transport *st, uint32_t status, uint16_t reply_len);
241 
242 /* Application status codes are uint32_t, but an enum is easier to read. */
243 enum app_status {
244   /* A few values are common to all applications */
245   APP_SUCCESS = 0,
246   APP_ERROR_BOGUS_ARGS,      /* caller being stupid */
247   APP_ERROR_INTERNAL,        /* application being stupid */
248   APP_ERROR_TOO_MUCH,        /* caller sent too much data */
249   APP_ERROR_IO,              /* problem sending or receiving data */
250   APP_ERROR_RPC,             /* problem during RPC communication */
251   /* more? */
252 
253   APP_SPECIFIC_ERROR = 0x20, /* "should be enough for anybody" */
254   /* App-specific error codes can use APP_SPECIFIC_ERROR+0, +1, +2, ... */
255 
256   /* For debugging, returning a line number might be helpful */
257   APP_LINE_NUMBER_BASE = 0x70000000,
258 #define APP_ERROR_LINENO (APP_LINE_NUMBER_BASE + __LINE__)
259 
260   /* Bit 31 is reserved for internal use */
261   MAX_APP_STATUS = 0x7fffffff,
262 };
263 
264 /**
265  * This registers an application that communicates using the Transport API.
266  *
267  * The name and version values may be exported to the Master by Nugget OS, so
268  * the Master can query what applications are available without blindly trying
269  * them all to see what works.
270  *
271  * @param  Id        The Application ID, defined above
272  * @param  Name      A human-readable string identifying the application
273  * @param  Version   An app-specific uint32_t number, for compability purposes
274  * @param  State     A pointer to the app's struct app_transport
275  * @param  To_fn     A pointer to the app's write_to_app_fn_t handler
276  */
277 #define DECLARE_APPLICATION_TRANSPORT(Id, Name, Version, State, To_fn)  \
278     const struct app_info __keep CONCAT2(app_, Id)                      \
279       __attribute__((section(".rodata.app_info")))                      \
280       = { .api = { .id = Id,                                            \
281              .from_fn = transaction_api_from_fn,                        \
282              .to_fn = transaction_api_to_fn,                            \
283              .data = &(const struct datagram_api)                       \
284              { .id = Id, .to_fn = To_fn,                                \
285                .data = State } },                                       \
286           .version = Version, .name = Name }
287 
288 /****************************************************************************/
289 /* Pay no attention to that man behind the curtain */
290 
291 /* We'll allow 31 bits of application status. We need one bit for transport. */
292 #define APP_STATUS_IDLE     0x00000000    /* waiting for instructions */
293 #define APP_STATUS_DONE     0x80000000    /* finished, reply is ready */
294 #define APP_STATUS_CODE(res) ((res) & 0x7fffffff) /* actual status */
295 
296 /* Datagram API needs this info */
297 struct datagram_api {
298   uint8_t id;
299   read_from_app_fn_t * const from_fn;
300   write_to_app_fn_t * const to_fn;
301   const void * const data;
302 };
303 
304 /* Here's the struct that keeps track of registered applications */
305 struct app_info {
306   struct datagram_api api;
307   uint32_t version;
308   const char * const name;
309 };
310 
311 /* These handle the Transport API */
312 extern read_from_app_fn_t transaction_api_from_fn;
313 extern write_to_app_fn_t transaction_api_to_fn;
314 
315 /* Command flags used internally by Transport API messages */
316 #define CMD_TRANSPORT       0x40000000    /* 1=Transport API message */
317 #define CMD_IS_DATA         0x20000000    /* 1=data msg 0=status msg */
318 #define CMD_MORE_TO_COME    0x10000000    /* 1=continued 0=new */
319 
320 #ifdef __cplusplus
321 }
322 #endif
323 
324 #endif  /* __CROS_EC_INCLUDE_APPLICATION_H */
325