• 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 #define APP_ID_IDENTITY          0x05
76 #define APP_ID_GSC_FACEAUTH      0x06
77 
78 /* Fake apps used only for testing */
79 #define APP_ID_AVB_TEST          0x11
80 #define APP_ID_TRANSPORT_TEST    0x12
81 #define APP_ID_FACEAUTH_TEST     0x13
82 #define APP_ID_TEST              0x7f
83 
84 /* OR this with the APP_ID to request no-protobuf messages */
85 #define APP_ID_NO_PROTO_FLAG     0x80
86 
87 /* No-protobuf app, experimental for now */
88 #define APP_ID_WEAVER2           (APP_ID_WEAVER | APP_ID_NO_PROTO_FLAG)
89 
90 /****************************************************************************/
91 /* Other command fields */
92 
93 /*
94  * The Command encoding is:
95  *
96  *   Bits 31-24   Control flags (reserved)
97  *   Bits 23-16   Application ID (bit 23 indicates C protocol, not protobuf)
98  *   Bits 15-0    Parameters (application-specific)
99  */
100 
101 /* Control flag bits */
102 #define CMD_IS_READ       0x80000000    /* 1=Read, 0=Write */
103 /* All other control flags bits are reserved */
104 
105 /* Extracting fields from a command */
106 #define GET_APP_ID(cmd)     (((cmd) & 0x00ff0000) >> 16)
107 #define GET_APP_PARAM(cmd)  ((cmd) & 0x0000ffff)
108 
109 /* Specifying command fields */
110 #define CMD_ID(id)       (((id) & 0x000000ff) << 16)
111 #define CMD_PARAM(p)     ((p) & 0x0000ffff)
112 #define CMD_SET_PARAM(cmd, p) cmd = ((cmd & 0xffff0000) | (p & 0x0000ffff))
113 
114 /****************************************************************************/
115 /* Data transfer */
116 
117 /*
118  * Functions of this type are invoked when the Master wants to read bytes from
119  * an application. The app should parse the Command, copy up to max_tx_size
120  * bytes into the tx_buffer provided, and return the number of bytes to send
121  * back to the Master.
122  *
123  * This is called in interrupt context, so act quickly.
124  *
125  * The last arg is for internal use. Just ignore it.
126  */
127 typedef uint32_t (read_from_app_fn_t)(uint32_t command,
128                                       uint8_t *tx_buffer,
129                                       uint32_t max_tx_bytes,
130                                       __private priv);
131 
132 /*
133  * Functions of this type are invoked when the Master has sent bytes to the
134  * application. The app should parse the Command and copy or process the
135  * expected number of bytes in the rx_buffer that the master has sent, up to
136  * rx_num_bytes.
137  *
138  * NOTE: Due to a quirk of the Citadel hardware, up to four extra bytes from
139  * the *next* transaction may be at the end of the rx_buffer. The application
140  * should only poke at the bytes it expects to see and ignore any extras.
141  *
142  * This is called in interrupt context, so act quickly.
143  *
144  * The last arg is for internal use. Just ignore it.
145  */
146 typedef void (write_to_app_fn_t)(uint32_t command,
147                                  const uint8_t *rx_buffer,
148                                  uint32_t num_rx_bytes,
149                                  __private priv);
150 
151 /*
152  * For apps that run asynchronously with little oversight, occasional
153  * Read/Write operations may be all that's necessary. An app that intercepts
154  * button presses, an accelerometer, or a fingerprint scanner can simply be
155  * told to start or stop and will send interrupts to the Master when its
156  * attention is required.
157  *
158  * Applications are free to define their own protcols and APIs using only the
159  * functions and constants above (and at least one app does just that).
160  *
161  * An app that wishes to handle its messaging using only the components
162  * described to this point would use the following macro to declare itself.
163  */
164 
165 /**
166  * This registers an application that communicates using the Datagram API,
167  * which deals only with the raw byte streams between Master (AP) and Slave
168  * (application).
169  *
170  * The name and version values may be exported to the Master by Nugget OS, so
171  * the Master can query what applications are available without blindly trying
172  * them all to see what works.
173  *
174  * @param  Id        The Application ID, defined above
175  * @param  Name      A human-readable string identifying the application
176  * @param  Version   An app-specific uint32_t number, for compability purposes
177  * @param  From_fn   A pointer to the app's read_from_app_fn_t handler
178  * @param  To_fn     A pointer to the app's write_to_app_fn_t handler
179  * @param  Data      App's private data
180  */
181 #define DECLARE_APPLICATION_DATAGRAM(Id, Name, Version, From_fn, To_fn, Data) \
182   const struct app_info __keep CONCAT2(app_, Id)                        \
183     __attribute__((section(".rodata.app_info")))                        \
184     = { .api = { .id = Id,                                              \
185                  .from_fn = From_fn, .to_fn = To_fn,                    \
186                  .data = Data},                                         \
187         .version = Version, .name = Name }
188 
189 /****************************************************************************/
190 /* Transport API */
191 /*
192  * Rather than handle unidirectonal datagrams themselves, many applications
193  * want to implement a request/response behavior, where the Master tells the
194  * app to do something and waits for it to finish and return the result.
195  *
196  * Seen from the AP's side, the application would be invoked using a blocking
197  * function something like this:
198  *
199  *   uint32_t call_application(uint8_t app_id, uint16_t app_param,
200  *                             const uint8_t *args, uint16_t arg_len,
201  *                             uint8_t *reply, uint16_t *reply_len);
202  *
203  * The request or response may be larger than one bus transaction, and the AP
204  * may poll until the app finishes or wait for an interrupt before retrieving
205  * the reply (there's no difference from app's point of view).
206  *
207  * With this API, the application is initially idle. Nugget OS will marshall
208  * all the input from the Master before waking the application. The Application
209  * then performs the requested operation and transititions to a "done" state.
210  * The Master will retrieve the application status and any reply data from
211  * Nugget OS, after which the application is ready to handle the next command.
212  */
213 
214 #define TRANSPORT_V0    0x0000
215 #define TRANSPORT_V1    0x0001
216 
217 /* Command information for the transport protocol. */
218 struct transport_command_info {
219   /* v1 fields */
220   uint16_t length;           /* length of this message */
221   uint16_t version;          /* max version used by master */
222   uint16_t crc;              /* CRC of some command fields */
223   uint16_t reply_len_hint;   /* max that the master will read */
224 } __packed;
225 
226 #define COMMAND_INFO_MIN_LENGTH 8
227 #define COMMAND_INFO_MAX_LENGTH 32
228 /* If more data needs to be sent, chain a new struct to the end of this one. It
229  * will require its own CRC for data integrity and something to signify the
230  * presence of the extra data. */
231 
232 struct transport_status {
233   /* v0 fields */
234   uint32_t status;         /* status of the app */
235   uint16_t reply_len;      /* length of available response data */
236   /* v1 fields */
237   uint16_t length;         /* length of this message */
238   uint16_t version;        /* max version used by slave */
239   uint16_t flags;          /* space for more protocol state flags */
240   uint16_t crc;            /* CRC of this status with crc set to 0 */
241   uint16_t reply_crc;      /* CRC of the reply data */
242 } __packed;
243 
244 /* Valid range of lengths for the status message */
245 #define STATUS_MIN_LENGTH 0x10
246 #define STATUS_MAX_LENGTH (sizeof(struct transport_status)) /* 0x10 */
247 
248 /* Flags used in the status message */
249 #define STATUS_FLAG_WORKING 0x0001 /* added in v1 */
250 
251 /* Pre-calculated CRCs for different status responses set in the interrupt
252  * context where the CRC would otherwise not be calculated. */
253 #define STATUS_CRC_FOR_IDLE              0x54c1
254 #define STATUS_CRC_FOR_WORKING           0x2101
255 #define STATUS_CRC_FOR_ERROR_TOO_MUCH    0x97c0
256 
257 /*
258  * Applications that wish to use this transport API will need to declare a
259  * private struct app_transport which Nugget OS can use to maintain the state:
260  */
261 struct app_transport {
262   void (*done_fn)(struct app_transport *);    /* optional cleanup function */
263   /* Note: Any done_fn() is called in interrupt context. Be quick. */
264   uint8_t *const request;                     /* input data buffer */
265   uint8_t *const response;                    /* output data buffer */
266   const uint16_t max_request_len;             /* input data buffer size */
267   const uint16_t max_response_len;            /* output data buffer size */
268   /* The following are used for the incoming command. */
269   uint32_t command;                           /* from master */
270   union {
271     struct transport_command_info info;
272     uint8_t data[COMMAND_INFO_MAX_LENGTH];    /* space for future growth */
273   } command_info;                             /* extra info about the command */
274   uint16_t request_len;                       /* command data buffer size */
275   uint16_t response_idx;                      /* current index into response */
276   struct transport_status status[2];          /* current transport_status */
277   volatile uint8_t status_idx;                /* index of active status */
278 };
279 
280 /*
281  * Note that request and response buffers are transferred as byte streams.
282  * However, if they will eventually represent structs, the usual ABI alignment
283  * requirements will be required. Until we've declared all applications structs
284  * in a union, we will need to align the buffers manually. Use this to declare
285  * the uint8_t buffers until then:
286  */
287 #define __TRANSPORT_ALIGNED__ __attribute__((aligned(8)))
288 
289 /*
290  * The application will need to provide a write_to_app_fn_t function that will
291  * be invoked when a new request is ready to be processed. All command and data
292  * parameters will already be present in the app's struct app_transport, so it
293  * just needs to awaken the application task to do the work.
294  *
295  * When awakened, the application task must check that there were no errors in
296  * the transmission of the request by calling this function. If it returns
297  * true, the task should go back to sleep until the next request arrives.
298  */
299 int request_is_invalid(struct app_transport *s);
300 /*
301  * When processing is finished, the app should call the app_reply() function to
302  * return its status code and specify the length of any data it has placed into
303  * the response buffer, and then it can go back to sleep until its next
304  * invocation. CAUTION: The Master polls for app completion independently, so
305  * it may immediately begin retrieving the results as soon as this function
306  * is called *without* waiting for the Nugget OS app to go to sleep.
307  */
308 void app_reply(struct app_transport *st, uint32_t status, uint16_t reply_len);
309 
310 /* Application status codes are uint32_t, but an enum is easier to read. */
311 enum app_status {
312   /* A few values are common to all applications */
313   APP_SUCCESS = 0,
314   APP_ERROR_BOGUS_ARGS, /* caller being stupid */
315   APP_ERROR_INTERNAL,   /* application being stupid */
316   APP_ERROR_TOO_MUCH,   /* caller sent too much data */
317   APP_ERROR_IO,         /* problem sending or receiving data */
318   APP_ERROR_RPC,        /* problem during RPC communication */
319   APP_ERROR_CHECKSUM,   /* checksum failed, only used within protocol */
320   APP_ERROR_BUSY,       /* the app is already working on a commnad */
321   APP_ERROR_TIMEOUT,    /* the app took too long to respond */
322   APP_ERROR_NOT_READY,  /* some required condition is not satisfied */
323   /* more? */
324 
325   /*
326    * Applications can define their own app-specific error codes.  For example,
327    * app_foobar.h can do:
328    *
329    *	#define APP_ERROR_FOOBAR_BAZ (APP_SPECIFIC_ERROR + 0)
330    *
331    * Do not use (APP_SPECIFIC_ERROR + N) directly in your code, because the
332    * error definition, firmware which generates it, and host code which
333    * interprets it are all in different repos.  You'll never be able to keep
334    * the constants straight without using a #define or enum in your app's
335    * header file that everyone can share.
336    */
337   APP_SPECIFIC_ERROR = 0x20, /* "should be enough for anybody" */
338 
339   /* For debugging, returning a line number might be helpful */
340   APP_LINE_NUMBER_BASE = 0x70000000,
341 #define APP_ERROR_LINENO (APP_LINE_NUMBER_BASE + __LINE__)
342 
343   /* Bit 31 is reserved for internal use */
344   MAX_APP_STATUS = 0x7fffffff,
345 };
346 
347 /**
348  * This registers an application that communicates using the Transport API.
349  *
350  * The name and version values may be exported to the Master by Nugget OS, so
351  * the Master can query what applications are available without blindly trying
352  * them all to see what works.
353  *
354  * @param  Id        The Application ID, defined above
355  * @param  Name      A human-readable string identifying the application
356  * @param  Version   An app-specific uint32_t number, for compability purposes
357  * @param  State     A pointer to the app's struct app_transport
358  * @param  To_fn     A pointer to the app's write_to_app_fn_t handler
359  */
360 #define DECLARE_APPLICATION_TRANSPORT(Id, Name, Version, State, To_fn)  \
361     const struct app_info __keep CONCAT2(app_, Id)                      \
362       __attribute__((section(".rodata.app_info")))                      \
363       = { .api = { .id = Id,                                            \
364              .from_fn = transaction_api_from_fn,                        \
365              .to_fn = transaction_api_to_fn,                            \
366              .data = &(const struct datagram_api)                       \
367              { .id = Id, .to_fn = To_fn,                                \
368                .data = State } },                                       \
369           .version = Version, .name = Name }
370 
371 /****************************************************************************/
372 /* Pay no attention to that man behind the curtain */
373 
374 /* We'll allow 31 bits of application status. We need one bit for transport. */
375 #define APP_STATUS_IDLE     0x00000000    /* waiting for instructions */
376 #define APP_STATUS_DONE     0x80000000    /* finished, reply is ready */
377 #define APP_STATUS_CODE(res) ((res) & 0x7fffffff) /* actual status */
378 
379 /* Datagram API needs this info */
380 struct datagram_api {
381   uint8_t id;
382   read_from_app_fn_t * const from_fn;
383   write_to_app_fn_t * const to_fn;
384   const void * const data;
385 };
386 
387 /* Here's the struct that keeps track of registered applications */
388 struct app_info {
389   struct datagram_api api;
390   uint32_t version;
391   const char * const name;
392 };
393 
394 /* These handle the Transport API */
395 extern read_from_app_fn_t transaction_api_from_fn;
396 extern write_to_app_fn_t transaction_api_to_fn;
397 
398 /* Command flags used internally by Transport API messages */
399 #define CMD_TRANSPORT       0x40000000    /* 1=Transport API message */
400 /* When CMD_TRANSPORT is set, the following bits have meaning */
401 #define CMD_IS_DATA         0x20000000    /* 1=data msg 0=status msg */
402 #define CMD_MORE_TO_COME    0x10000000    /* 1=continued 0=new */
403 
404 #ifdef __cplusplus
405 }
406 #endif
407 
408 #endif  /* __CROS_EC_INCLUDE_APPLICATION_H */
409