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