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